Version 1.2.0-dev.1.0

svn merge -r 31316:31907 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@31918 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/dart.gyp b/dart.gyp
index b87b568..914b088 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -184,5 +184,13 @@
         'pkg/pkg.gyp:pkg_packages',
       ],
     },
+    {
+      'target_name': 'try',
+      'type': 'none',
+      'dependencies': [
+        'create_sdk',
+        'site/try/build_try.gyp:try_site',
+      ],
+    },
   ],
 }
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index b5d0f47..d10095c 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -5,7 +5,7 @@
 \usepackage{hyperref}
 \newcommand{\code}[1]{{\sf #1}}
 \title{Dart Programming Language  Specification \\
-{\large Version 1.0}}
+{\large Version 1.11}}
 \author{The Dart Team}
 \begin{document}
 \maketitle
@@ -1563,7 +1563,7 @@
   \item  If possible the interface gets a member named $m$ that has the minimum number of required parameters among all the members in the superinterfaces, the maximal number of    positionals, and the superset of named parameters.  The types of these are all \DYNAMIC{}. If this is impossible then no member $m$ appears in the interface.
   \end{itemize}  (\ref{interfaceInheritanceAndOverriding})
 \item  Rule \ref{typeSigAssignable} applies to interfaces as well as classes  (\ref{interfaceInheritanceAndOverriding}).
-\item  It is a static warning if a concrete class does not have an implementation for a  method in any of its superinterfaces  unless it declares  its own \cd{noSuchMethod} method (\ref{superinterfaces}) or is annotated with \cd{@proxy}.
+\item  It is a static warning if a concrete class does not have an implementation for a  method in any of its superinterfaces  unless it declares  its own \cd{noSuchMethod} method (\ref{superinterfaces}). 
 \item The identifier of a named constructor cannot be the same as the name of a member declared (as opposed to inherited) in the same class (\ref{constructors}).
 \end{enumerate}
 }
@@ -1593,7 +1593,7 @@
 
 It is a compile-time error if the interface of a class $C$ is a superinterface of itself.
 
-Let $C$ be a concrete class that does not declare its own \code{noSuchMethod()} method and is not annotated with a metadata declaration of the form \cd{@proxy}, where \cd{proxy} is declared in \cd{dart:core}.
+Let $C$ be a concrete class that does not declare its own \code{noSuchMethod()} method.
 It is a static warning if the implicit interface of  $C$ includes an instance member $m$ of type $F$ and $C$ does not declare or inherit a corresponding instance member $m$ of type $F'$ such that $F' <: F$. 
 
 \commentary{A class does not inherit members from its superinterfaces. However, its implicit interface does.
@@ -1604,9 +1604,13 @@
 We choose to issue these warnings only for concrete classes; an abstract class might legitimately be designed with the expectation that concrete subclasses will implement part of  the interface.
 We also disable these warnings if a \code{noSuchMethod()} declaration is present. In such cases, the supported interface is going to be implemented via \code{noSuchMethod()} and no actual declarations of the implemented interface's members are needed. This allows proxy classes for specific types to be implemented without provoking type warnings.
 
-In addition, it may be useful to suppress these warnings if \code{noSuchMethod} is inherited, However, this may suppress meaningful warnings and so we choose not to do so by default. Instead, a special annotation is defined in \cd{dart:core} for this purpose.
+In addition, it may be useful to suppress these warnings if \code{noSuchMethod} is inherited, However, this may suppress meaningful warnings and so we choose not to do so. If one does want to suppress the warnings in a subclass, one can define a simple implementation of \code{noSuchMethod} in the subclass:
 }
 
+\begin{dartCode}
+noSuchMethod(inv) =$>$ \SUPER.noSuchMethod(inv);
+\end{dartCode}
+
 It is a static warning if the implicit interface of  a class $C$ includes an instance member $m$ of type $F$ and $C$ declares or inherits a corresponding instance member $m$ of type $F'$ if  $F'$ is not a subtype of $F$. 
 
 \rationale{
@@ -1942,7 +1946,7 @@
 It is possible to associate metadata with constructs that may not be accessible via reflection, such as local variables (though it is conceivable that in the future, richer reflective libraries might provide access to these as well).  This is not as useless as it might seem. As noted above, the data can be retrieved statically if source code is available.
 }
 
-Metadata can appear before a library, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import or export directive.
+Metadata can appear before a library, part header, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import, export or part directive.
 
 The constant expression given in an annotation  is type checked and evaluated in the scope surrounding the declaration being annotated.  
 
@@ -3110,7 +3114,7 @@
 A function expression invocation $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is equivalent to $e_f.call(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$.
 
 \commentary{
-The implication of this definition, and the other definitions involving the method \code{call()}, is that user defined types can be used as function values provided they define a \code{call()} method. The method \code{call()} is special in this regard. The signature of the \code{call()} method determines the signature used when using the object via the built-in invocation syntax.
+The implication of this definition, and the other definitions involving the method \code{call()}, is that user defined types can be used as function values provided they define a \CALL{} method. The method \CALL{} is special in this regard. The signature of the \CALL{} method determines the signature used when using the object via the built-in invocation syntax.
 }
 
 It is a static warning if the static type $F$ of $e_f$ may not be assigned to a function type.  If $F$ is not a function type, the static type of $i$ is \DYNAMIC{}. Otherwise 
@@ -3174,7 +3178,7 @@
 
 \commentary{Notice that the wording carefully avoids re-evaluating the receiver $o$ and the arguments $a_i$. }
 
-Let $T$ be the  static type of $o$. It is a static type warning if $T$ does not have an accessible  (\ref{privacy}) instance member named $m$.   If $T.m$ exists, it  is a static type warning if the type $F$ of $T.m$ may not be assigned to a function type. If $T.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of  $F$.  
+Let $T$ be the  static type of $o$. It is a static type warning if $T$ does not have an accessible  (\ref{privacy}) instance member named $m$ unless $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}.   If $T.m$ exists, it  is a static type warning if the type $F$ of $T.m$ may not be assigned to a function type. If $T.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of  $F$.  
 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static warning if $F$ is not a supertype of  $(T_1, \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \to \bot$.
 %\end{itemize}
 
@@ -3270,7 +3274,7 @@
 
 It is a compile-time error if a super method invocation occurs in a top-level function or variable initializer, in an instance variable initializer or initializer list, in class \code{Object}, in a factory constructor or in a static method or variable initializer.
 
-It is a static type warning if $S$ does not have an accessible (\ref{privacy}) instance member named $m$. If $S.m$ exists, it  is a static type warning if the type $F$ of $S.m$ may not be assigned to a function type. If $S.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of  $F$.  
+It is a static type warning if $S$ does not have an accessible (\ref{privacy}) instance member named $m$ unless $S$ or a superinterface of $S$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. If $S.m$ exists, it  is a static type warning if the type $F$ of $S.m$ may not be assigned to a function type. If $S.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of  $F$.  
 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static warning if $F$ is not a supertype of  $(T_1, \ldots, t_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \to \bot$.
 %\end{itemize}
 
@@ -3317,7 +3321,7 @@
 \end{itemize}
 Then the method \code{noSuchMethod()} is looked up in $o$ and invoked  with argument $im$, and the result of this invocation is the result of evaluating $i$.
 
-Let $T$ be the  static type of $e$. It is a static type warning if $T$ does not have a getter named $m$. The static type of $i$ is the declared return type of $T.m$, if $T.m$ exists; otherwise the static type of $i$  is  \DYNAMIC{}. 
+Let $T$ be the  static type of $e$. It is a static type warning if $T$ does not have a getter named $m$ unless $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. The static type of $i$ is the declared return type of $T.m$, if $T.m$ exists; otherwise the static type of $i$  is  \DYNAMIC{}. 
 
 Evaluation of a getter invocation $i$ of the form $C.m$ proceeds as follows:
 
@@ -3423,7 +3427,7 @@
 
 In checked mode, it is a dynamic type error if $o_2$ is not \NULL{} and the interface of the class of $o_2$ is not a subtype of the actual type of $e_1.v$.
 
-Let $T$ be the static type of $e_1$. It is a static type warning if $T$ does not have an accessible instance setter named $v=$. It is a static type warning if the static type of $e_2$ may not be assigned to $T$.   The static type of the expression $e_1v$ \code{=} $e_2$ is the static type of $e_2$.
+Let $T$ be the static type of $e_1$. It is a static type warning if $T$ does not have an accessible instance setter named $v=$ unless $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. It is a static type warning if the static type of $e_2$ may not be assigned to $T$.   The static type of the expression $e_1v$ \code{=} $e_2$ is the static type of $e_2$.
 
 Evaluation of an assignment of the form $e_1[e_2]$ \code{=} $e_3$ is equivalent to the evaluation of the expression \code{(a, i, e)\{a.[]=(i, e); \RETURN{} e; \} ($e_1, e_2, e_3$)}.  The static type of the expression $e_1[e_2]$ \code{=} $e_3$ is the static type of $e_3$.
 
@@ -3714,22 +3718,29 @@
 \begin{grammar}
 {\bf unaryExpression:}prefixOperator unaryExpression;
       postfixExpression;
-      prefixOperator \SUPER{};
+      (minusOperator $|$ tildeOperator) \SUPER{};
       incrementOperator assignableExpression
     .
  
- {\bf prefixOperator:}`-';
-      unaryOperator
+ {\bf prefixOperator:}minusOperator;
+      negationOperator;
+      tildeOperator
     .
        
-    {\bf unaryOperator:}`!' ;
-      `\~{}'
+       
+  {\bf minusOperator:}`-';  .
+
+
+    {\bf negationOperator:}`!' ;
+      .
+      
+    {\bf tildeOperator:}  `\~{}'
     .
     
     
 \end{grammar}
 
-A {\em unary expression} is either aa postfix expression  (\ref{postfixExpressions}), an invocation of a prefix operator on an expression or an invocation of a unary operator on either \SUPER{} or an expression $e$.
+A {\em unary expression} is either a postfix expression  (\ref{postfixExpressions}), an invocation of a prefix operator on an expression or an invocation of a unary operator on either \SUPER{} or an expression $e$.
 
 The expression $!e$ is equivalent to the expression $e? \FALSE{} :\TRUE{}$. 
 
@@ -4301,16 +4312,20 @@
 \subsubsection{For-in}
 \label{for-in}
 
-A for statement of the form \code{ \FOR{} ($varOrType?$ id \IN{} $e$) $s$} is equivalent to the following code: 
+A for statement of the form \code{ \FOR{} ($finalConstVarOrType?$ id \IN{} $e$) $s$} is equivalent to the following code: 
 
 \begin{dartCode}
 var n0 = $e$.iterator;
 \WHILE{} (n0.moveNext()) \{
-   $varOrType?$ id = n0.current;
+   $finalConstVarOrType?$ id = n0.current;
    $s$ 
 \}
 \end{dartCode}
 where \code{n0} is an identifier that does not occur anywhere in the program.
+
+\commentary{
+Note that in fact, using a  \CONST{} variable would give rise to a compile time error since \cd{n0.current} is not a constant expression.  
+}
  
 \subsection{While}
 \label{while}
@@ -4589,8 +4604,14 @@
 Nothing is said about how any native function calls may be represented in the trace.
  }
  
+\commentary{
+Note that we say nothing about the identity of the stack trace, or what notion of equality is defined for stack traces.
+}
  
- For each such function activation, the active stack trace includes the name of the function, the bindings of all its formal parameters, local variables and \THIS{}, and the position at which the function was executing.
+% Sadly, the info below cannot be computed efficiently. It would need to be computed at the throw point, since at latte points it might be destroyed. Native code in calling frames executes relative to the stack pointer, which therefore needs to be reset as each frame is unwound.  This means that the
+% OS kernel can dispose of this stack memory - it is not reliably preserved. And such code must execute if only to test if the exception should be caught or sent onward.
+
+% For each such function activation, the active stack trace includes the name of the function, the bindings of all its formal parameters, local variables and \THIS{}, and the position at which the function was executing.
  
  % Is this controversial? We were thinking of viewing the trace as a List<Invocation>,
  % but that won't capture the receiver or the locals. More generally, we need a standard interface that describes these traces, so one can type the stack trace variable in the catch.
@@ -5031,7 +5052,7 @@
  
  An export specifies a URI $x$ where the declaration of an exported library is to be found.  It is a compile-time error if  the specified URI does not refer to a library declaration.  
 
-We say that a name {\em is exported by a library} (or equivalently, that a library {\em exports a name}) if the name is in the library`s exported namespace. We say that a declaration {\em is exported by a library} (or equivalently, that a library {\em exports a declaration}) if the declaration is in the library`s exported namespace.
+We say that a name {\em is exported by a library} (or equivalently, that a library {\em exports a name}) if the name is in the library's exported namespace. We say that a declaration {\em is exported by a library} (or equivalently, that a library {\em exports a declaration}) if the declaration is in the library`s exported namespace.
 
 A library always exports all names and all declarations in its public namespace. In addition, a library may choose to re-export additional libraries via {\em export directives}, often referred to simply as {\em exports}.
 
@@ -5071,7 +5092,7 @@
 
 We say that $L$ {\em re-exports library } $B$, and also that $L$ {\em re-exports namespace } $NS_n$. When no confusion can arise, we may simply state that $L$ {\em re-exports }$B$, or that $L$ {\em re-exports }$NS_n$.
 
-It is a compile-time error if a name $N$ is re-exported by a library $L$ and $N$ is  introduced into the export namespace of $L$ by more than one export, unless each all exports refer to same declaration for the name $N$.  It is a static warning to export two different libraries with the same name.
+It is a compile-time error if a name $N$ is re-exported by a library $L$ and $N$ is  introduced into the export namespace of $L$ by more than one export, unless all  exports refer to same declaration for the name $N$.  It is a static warning to export two different libraries with the same name.
 
 
 
@@ -5483,7 +5504,7 @@
 
 % ensure that Object  and dynamic may be assign dot a function type
 A function is always an instance of some class that implements the class \code{Function} and implements a \CALL{} method with the same signature as the function. All function types are subtypes of \code{Function}.
-If a type $I$ includes an instance method named \CALL{}, and the type of \CALL{} is the function type $F$, then $I$ is considered to be a subtype of $F$.  It is a static warning if a concrete class implements \cd{Function} and does not have a concrete method named \CALL{}.
+If a type $I$ includes an instance method named \CALL{}, and the type of \CALL{} is the function type $F$, then $I$ is considered to be a subtype of $F$.  It is a static warning if a concrete class implements \cd{Function} and does not have a concrete method named \CALL{} unless that class declares its own implementation of \cd{noSuchMethod()}.
 
 
 
@@ -5763,7 +5784,7 @@
 \hline
 Description &  Operator & Associativity & Precedence \\ 
 \hline
-Unary postfix &  ., ?id, e++, e--, e1[e2], e1() , () & None & 15 \\
+Unary postfix &  ., e++, e--, e1[e2], e1() , () & None & 15 \\
 \hline
 Unary prefix & -e, !e, \~{}e, ++e, --e & None & 14\\
 \hline
diff --git a/pkg/analysis_server/LICENSE b/pkg/analysis_server/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/analysis_server/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/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
new file mode 100644
index 0000000..889f1f5
--- /dev/null
+++ b/pkg/analysis_server/pubspec.yaml
@@ -0,0 +1,13 @@
+name: analysis_server
+version: 0.0.1
+author: Dart Team <misc@dartlang.org>
+description: An HTTP server that performs analysis of Dart code via web sockets.
+homepage: http://www.dartlang.org
+environment:
+  sdk: ">=1.0.0 <2.0.0"
+dependencies:
+  analyzer: any
+  args: any
+  logging: any
+dev_dependencies:
+  unittest: any
diff --git a/pkg/analyzer/bin/analyzer.dart b/pkg/analyzer/bin/analyzer.dart
index 2d22e44..8648221 100644
--- a/pkg/analyzer/bin/analyzer.dart
+++ b/pkg/analyzer/bin/analyzer.dart
@@ -13,7 +13,7 @@
 
 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/src/generated/java_core.dart' show JavaSystem, instanceOfTimer;
 import 'package:analyzer/options.dart';
 
 import 'package:analyzer/src/analyzer_impl.dart';
@@ -38,6 +38,8 @@
       print("resolve:${PerformanceStatistics.resolve.result}");
       print("errors:${PerformanceStatistics.errors.result}");
       print("hints:${PerformanceStatistics.hints.result}");
+      print("angular:${PerformanceStatistics.angular.result}");
+      print("instanceof:${instanceOfTimer.elapsedMilliseconds}");
       print("total:$totalTime");
     }
 
diff --git a/pkg/analyzer/bin/formatter.dart b/pkg/analyzer/bin/formatter.dart
index b49aff3..6842aab 100755
--- a/pkg/analyzer/bin/formatter.dart
+++ b/pkg/analyzer/bin/formatter.dart
@@ -24,7 +24,9 @@
 bool machineFormat;
 bool overwriteFileContents;
 Selection selection;
-const followLinks = false;
+final List<String> paths = [];
+
+const FOLLOW_LINKS = false;
 
 
 main(args) {
@@ -39,7 +41,8 @@
   if (options.rest.isEmpty) {
     _formatStdin(kind);
   } else {
-    _formatPaths(options.rest);
+    paths.addAll(options.rest);
+    _formatPaths(paths);
   }
 }
 
@@ -96,17 +99,24 @@
   }
 }
 
-_formatDirectory(dir) => dir.listSync(followLinks: followLinks)
+_formatDirectory(dir) => dir.listSync(followLinks: FOLLOW_LINKS)
     .forEach((resource) => _formatResource(resource));
 
 _formatFile(file) {
   if (_isDartFile(file)) {
+    if (_isPatchFile(file) && !paths.contains(file.path)) {
+      _log('Skipping patch file "${file.path}"');
+      return;
+    }
     try {
       var buffer = new StringBuffer();
       var rawSource = file.readAsStringSync();
       var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT);
       if (overwriteFileContents) {
-        file.writeAsStringSync(formatted);
+        // Only touch files files whose contents will be changed
+        if (rawSource != formatted) {
+          file.writeAsStringSync(formatted);
+        }
       } else {
         print(formatted);
       }
@@ -116,6 +126,8 @@
   }
 }
 
+_isPatchFile(file) => file.path.endsWith('_patch.dart');
+
 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path));
 
 _formatStdin(kind) {
@@ -135,12 +147,12 @@
             'Do not print reformatted sources to standard output.');
   parser.addOption('kind', abbr: 'k', defaultsTo: 'cu',
       help: 'Specify source snippet kind ("stmt" or "cu")'
-            ' --- [PROVISIONAL API].');
+            ' --- [PROVISIONAL API].', hide: true);
   parser.addFlag('machine', abbr: 'm', negatable: false,
       help: 'Produce output in a format suitable for parsing.');
   parser.addOption('selection', abbr: 's',
       help: 'Specify selection information as an offset,length pair '
-            '(e.g., -s "0,4").');
+            '(e.g., -s "0,4").', hide: true);
   parser.addFlag('transform', abbr: 't', negatable: true,
       help: 'Perform code transformations.');
   parser.addFlag('help', abbr: 'h', negatable: false,
@@ -161,8 +173,8 @@
                 'default, $BINARY_NAME prints the reformatted sources to '
                 'standard output.')
         ..write('\n\n')
-        ..write('Supported flags are:')
         ..write('Usage: $BINARY_NAME [flags] [path...]\n\n')
+        ..write('Supported flags are:\n')
         ..write('${argParser.getUsage()}\n\n');
   _log(buffer.toString());
 }
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
index 64a6d01..8cb18dc 100644
--- a/pkg/analyzer/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -44,7 +44,7 @@
   visitNode(ASTNode node) {
     String text = '${node.runtimeType} : <"${node.toString()}">';
     if (node is SimpleIdentifier) {
-      Element element = (node as SimpleIdentifier).staticElement;
+      Element element = node.staticElement;
       if (element != null) {
         text += " element: ${element.runtimeType}";
         LibraryElement library = element.library;
diff --git a/pkg/analyzer/lib/options.dart b/pkg/analyzer/lib/options.dart
index 2cf2d58..bdb58f0 100644
--- a/pkg/analyzer/lib/options.dart
+++ b/pkg/analyzer/lib/options.dart
@@ -4,11 +4,9 @@
 
 library options;
 
-import 'package:args/args.dart';
-import 'package:path/path.dart';
-
 import 'dart:io';
 
+import 'package:args/args.dart';
 
 const _BINARY_NAME = 'dartanalyzer';
 
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 91adcd0..15763a7 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -64,7 +68,7 @@
     while (node != null && !isInstanceOf(node, enclosingClass)) {
       node = node.parent;
     }
-    return node as ASTNode;
+    return node;
   }
 
   /**
@@ -1036,10 +1040,13 @@
    */
   ParameterElement getPropagatedParameterElementFor(Expression expression) {
     if (_correspondingPropagatedParameters == null) {
+      // Either the AST structure has not been resolved or the invocation of which this list is a
+      // part could not be resolved.
       return null;
     }
     int index = _arguments.indexOf(expression);
     if (index < 0) {
+      // The expression isn't a child of this node.
       return null;
     }
     return _correspondingPropagatedParameters[index];
@@ -1060,10 +1067,13 @@
    */
   ParameterElement getStaticParameterElementFor(Expression expression) {
     if (_correspondingStaticParameters == null) {
+      // Either the AST structure has not been resolved or the invocation of which this list is a
+      // part could not be resolved.
       return null;
     }
     int index = _arguments.indexOf(expression);
     if (index < 0) {
+      // The expression isn't a child of this node.
       return null;
     }
     return _correspondingStaticParameters[index];
@@ -2203,6 +2213,28 @@
 
   accept(ASTVisitor visitor) => visitor.visitClassDeclaration(this);
 
+  /**
+   * Return the constructor declared in the class with the given name.
+   *
+   * @param name the name of the constructor to find, `null` for default
+   * @return the found constructor or `null` if not found
+   */
+  ConstructorDeclaration getConstructor(String name) {
+    for (ClassMember classMember in _members) {
+      if (classMember is ConstructorDeclaration) {
+        ConstructorDeclaration constructor = classMember;
+        SimpleIdentifier constructorName = constructor.name;
+        if (name == null && constructorName == null) {
+          return constructor;
+        }
+        if (constructorName != null && constructorName.name == name) {
+          return constructor;
+        }
+      }
+    }
+    return null;
+  }
+
   ClassElement get element => _name != null ? (_name.staticElement as ClassElement) : null;
 
   Token get endToken => rightBracket;
@@ -2224,7 +2256,7 @@
   VariableDeclaration getField(String name) {
     for (ClassMember classMember in _members) {
       if (classMember is FieldDeclaration) {
-        FieldDeclaration fieldDeclaration = classMember as FieldDeclaration;
+        FieldDeclaration fieldDeclaration = classMember;
         NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables;
         for (VariableDeclaration field in fields) {
           SimpleIdentifier fieldName = field.name;
@@ -2253,6 +2285,25 @@
   NodeList<ClassMember> get members => _members;
 
   /**
+   * Return the method declared in the class with the given name.
+   *
+   * @param name the name of the method to find
+   * @return the found method or `null` if not found
+   */
+  MethodDeclaration getMethod(String name) {
+    for (ClassMember classMember in _members) {
+      if (classMember is MethodDeclaration) {
+        MethodDeclaration method = classMember;
+        SimpleIdentifier methodName = method.name;
+        if (methodName != null && name == methodName.name) {
+          return method;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
    * Return the name of the class being declared.
    *
    * @return the name of the class being declared
@@ -4204,7 +4255,7 @@
   LibraryElement get uriElement {
     Element element = this.element;
     if (element is ExportElement) {
-      return (element as ExportElement).exportedLibrary;
+      return element.exportedLibrary;
     }
     return null;
   }
@@ -4299,26 +4350,26 @@
   ParameterElement get propagatedParameterElement {
     ASTNode parent = this.parent;
     if (parent is ArgumentList) {
-      return (parent as ArgumentList).getPropagatedParameterElementFor(this);
+      return parent.getPropagatedParameterElementFor(this);
     } else if (parent is IndexExpression) {
-      IndexExpression indexExpression = parent as IndexExpression;
+      IndexExpression indexExpression = parent;
       if (identical(indexExpression.index, this)) {
         return indexExpression.propagatedParameterElementForIndex;
       }
     } else if (parent is BinaryExpression) {
-      BinaryExpression binaryExpression = parent as BinaryExpression;
+      BinaryExpression binaryExpression = parent;
       if (identical(binaryExpression.rightOperand, this)) {
         return binaryExpression.propagatedParameterElementForRightOperand;
       }
     } else if (parent is AssignmentExpression) {
-      AssignmentExpression assignmentExpression = parent as AssignmentExpression;
+      AssignmentExpression assignmentExpression = parent;
       if (identical(assignmentExpression.rightHandSide, this)) {
         return assignmentExpression.propagatedParameterElementForRightHandSide;
       }
     } else if (parent is PrefixExpression) {
-      return (parent as PrefixExpression).propagatedParameterElementForOperand;
+      return parent.propagatedParameterElementForOperand;
     } else if (parent is PostfixExpression) {
-      return (parent as PostfixExpression).propagatedParameterElementForOperand;
+      return parent.propagatedParameterElementForOperand;
     }
     return null;
   }
@@ -4336,26 +4387,26 @@
   ParameterElement get staticParameterElement {
     ASTNode parent = this.parent;
     if (parent is ArgumentList) {
-      return (parent as ArgumentList).getStaticParameterElementFor(this);
+      return parent.getStaticParameterElementFor(this);
     } else if (parent is IndexExpression) {
-      IndexExpression indexExpression = parent as IndexExpression;
+      IndexExpression indexExpression = parent;
       if (identical(indexExpression.index, this)) {
         return indexExpression.staticParameterElementForIndex;
       }
     } else if (parent is BinaryExpression) {
-      BinaryExpression binaryExpression = parent as BinaryExpression;
+      BinaryExpression binaryExpression = parent;
       if (identical(binaryExpression.rightOperand, this)) {
         return binaryExpression.staticParameterElementForRightOperand;
       }
     } else if (parent is AssignmentExpression) {
-      AssignmentExpression assignmentExpression = parent as AssignmentExpression;
+      AssignmentExpression assignmentExpression = parent;
       if (identical(assignmentExpression.rightHandSide, this)) {
         return assignmentExpression.staticParameterElementForRightHandSide;
       }
     } else if (parent is PrefixExpression) {
-      return (parent as PrefixExpression).staticParameterElementForOperand;
+      return parent.staticParameterElementForOperand;
     } else if (parent is PostfixExpression) {
-      return (parent as PostfixExpression).staticParameterElementForOperand;
+      return parent.staticParameterElementForOperand;
     }
     return null;
   }
@@ -5609,6 +5660,8 @@
     } else if (_body != null) {
       return _body.beginToken;
     }
+    // This should never be reached because external functions must be named, hence either the body
+    // or the name should be non-null.
     throw new IllegalStateException("Non-external functions must have a body");
   }
 
@@ -5625,6 +5678,8 @@
     } else if (_parameters != null) {
       return _parameters.endToken;
     }
+    // This should never be reached because external functions must be named, hence either the body
+    // or the name should be non-null.
     throw new IllegalStateException("Non-external functions must have a body");
   }
 
@@ -6321,6 +6376,9 @@
  */
 class ImportDirective extends NamespaceDirective {
   static Comparator<ImportDirective> COMPARATOR = (ImportDirective import1, ImportDirective import2) {
+    //
+    // uri
+    //
     StringLiteral uri1 = import1.uri;
     StringLiteral uri2 = import2.uri;
     String uriStr1 = uri1.stringValue;
@@ -6337,6 +6395,9 @@
         }
       }
     }
+    //
+    // as
+    //
     SimpleIdentifier prefix1 = import1.prefix;
     SimpleIdentifier prefix2 = import2.prefix;
     String prefixStr1 = prefix1 != null ? prefix1.name : null;
@@ -6353,12 +6414,15 @@
         }
       }
     }
+    //
+    // hides and shows
+    //
     NodeList<Combinator> combinators1 = import1.combinators;
     List<String> allHides1 = new List<String>();
     List<String> allShows1 = new List<String>();
     for (Combinator combinator in combinators1) {
       if (combinator is HideCombinator) {
-        NodeList<SimpleIdentifier> hides = (combinator as HideCombinator).hiddenNames;
+        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
         for (SimpleIdentifier simpleIdentifier in hides) {
           allHides1.add(simpleIdentifier.name);
         }
@@ -6374,7 +6438,7 @@
     List<String> allShows2 = new List<String>();
     for (Combinator combinator in combinators2) {
       if (combinator is HideCombinator) {
-        NodeList<SimpleIdentifier> hides = (combinator as HideCombinator).hiddenNames;
+        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
         for (SimpleIdentifier simpleIdentifier in hides) {
           allHides2.add(simpleIdentifier.name);
         }
@@ -6385,12 +6449,14 @@
         }
       }
     }
+    // test lengths of combinator lists first
     if (allHides1.length != allHides2.length) {
       return allHides1.length - allHides2.length;
     }
     if (allShows1.length != allShows2.length) {
       return allShows1.length - allShows2.length;
     }
+    // next ensure that the lists are equivalent
     if (!javaCollectionContainsAll(allHides1, allHides2)) {
       return -1;
     }
@@ -6665,7 +6731,7 @@
   bool inGetterContext() {
     ASTNode parent = this.parent;
     if (parent is AssignmentExpression) {
-      AssignmentExpression assignment = parent as AssignmentExpression;
+      AssignmentExpression assignment = parent;
       if (identical(assignment.leftHandSide, this) && identical(assignment.operator.type, TokenType.EQ)) {
         return false;
       }
@@ -6686,11 +6752,11 @@
   bool inSetterContext() {
     ASTNode parent = this.parent;
     if (parent is PrefixExpression) {
-      return (parent as PrefixExpression).operator.type.isIncrementOperator;
+      return parent.operator.type.isIncrementOperator;
     } else if (parent is PostfixExpression) {
       return true;
     } else if (parent is AssignmentExpression) {
-      return identical((parent as AssignmentExpression).leftHandSide, this);
+      return identical(parent.leftHandSide, this);
     }
     return false;
   }
@@ -8197,7 +8263,7 @@
   ParameterElement get element {
     Element element = _name.label.staticElement;
     if (element is ParameterElement) {
-      return element as ParameterElement;
+      return element;
     }
     return null;
   }
@@ -8456,7 +8522,7 @@
   ParameterKind get kind {
     ASTNode parent = this.parent;
     if (parent is DefaultFormalParameter) {
-      return (parent as DefaultFormalParameter).kind;
+      return parent.kind;
     }
     return ParameterKind.REQUIRED;
   }
@@ -8487,6 +8553,10 @@
   }
 
   void visitChildren(ASTVisitor visitor) {
+    //
+    // Note that subclasses are responsible for visiting the identifier because they often need to
+    // visit other nodes before visiting the identifier.
+    //
     if (commentIsBeforeAnnotations()) {
       safelyVisitChild(_comment, visitor);
       _metadata.accept(visitor);
@@ -9795,30 +9865,30 @@
   bool inDeclarationContext() {
     ASTNode parent = this.parent;
     if (parent is CatchClause) {
-      CatchClause clause = parent as CatchClause;
+      CatchClause clause = parent;
       return identical(this, clause.exceptionParameter) || identical(this, clause.stackTraceParameter);
     } else if (parent is ClassDeclaration) {
-      return identical(this, (parent as ClassDeclaration).name);
+      return identical(this, parent.name);
     } else if (parent is ClassTypeAlias) {
-      return identical(this, (parent as ClassTypeAlias).name);
+      return identical(this, parent.name);
     } else if (parent is ConstructorDeclaration) {
-      return identical(this, (parent as ConstructorDeclaration).name);
+      return identical(this, parent.name);
     } else if (parent is DeclaredIdentifier) {
-      return identical(this, (parent as DeclaredIdentifier).identifier);
+      return identical(this, parent.identifier);
     } else if (parent is FunctionDeclaration) {
-      return identical(this, (parent as FunctionDeclaration).name);
+      return identical(this, parent.name);
     } else if (parent is FunctionTypeAlias) {
-      return identical(this, (parent as FunctionTypeAlias).name);
+      return identical(this, parent.name);
     } else if (parent is Label) {
-      return identical(this, (parent as Label).label) && (parent.parent is LabeledStatement);
+      return identical(this, parent.label) && (parent.parent is LabeledStatement);
     } else if (parent is MethodDeclaration) {
-      return identical(this, (parent as MethodDeclaration).name);
+      return identical(this, parent.name);
     } else if (parent is FunctionTypedFormalParameter || parent is SimpleFormalParameter) {
       return identical(this, (parent as NormalFormalParameter).identifier);
     } else if (parent is TypeParameter) {
-      return identical(this, (parent as TypeParameter).name);
+      return identical(this, parent.name);
     } else if (parent is VariableDeclaration) {
-      return identical(this, (parent as VariableDeclaration).name);
+      return identical(this, parent.name);
     }
     return false;
   }
@@ -9835,6 +9905,7 @@
   bool inGetterContext() {
     ASTNode parent = this.parent;
     ASTNode target = this;
+    // skip prefix
     if (parent is PrefixedIdentifier) {
       PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
       if (identical(prefixed.prefix, this)) {
@@ -9850,9 +9921,11 @@
       parent = access.parent;
       target = access;
     }
+    // skip label
     if (parent is Label) {
       return false;
     }
+    // analyze usage
     if (parent is AssignmentExpression) {
       AssignmentExpression expr = parent as AssignmentExpression;
       if (identical(expr.leftHandSide, target) && identical(expr.operator.type, TokenType.EQ)) {
@@ -9874,8 +9947,10 @@
   bool inSetterContext() {
     ASTNode parent = this.parent;
     ASTNode target = this;
+    // skip prefix
     if (parent is PrefixedIdentifier) {
       PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
+      // if this is the prefix, then return false
       if (identical(prefixed.prefix, this)) {
         return false;
       }
@@ -9889,6 +9964,7 @@
       parent = access.parent;
       target = access;
     }
+    // analyze usage
     if (parent is PrefixExpression) {
       return (parent as PrefixExpression).operator.type.isIncrementOperator;
     } else if (parent is PostfixExpression) {
@@ -9951,23 +10027,23 @@
       return null;
     }
     ASTNode parent = this.parent;
-    if (parent is ClassDeclaration && identical((parent as ClassDeclaration).name, this)) {
+    if (parent is ClassDeclaration && identical(parent.name, this)) {
       return validateElement(parent, ClassElement, element);
-    } else if (parent is ClassTypeAlias && identical((parent as ClassTypeAlias).name, this)) {
+    } else if (parent is ClassTypeAlias && identical(parent.name, this)) {
       return validateElement(parent, ClassElement, element);
-    } else if (parent is DeclaredIdentifier && identical((parent as DeclaredIdentifier).identifier, this)) {
+    } else if (parent is DeclaredIdentifier && identical(parent.identifier, this)) {
       return validateElement(parent, LocalVariableElement, element);
-    } else if (parent is FormalParameter && identical((parent as FormalParameter).identifier, this)) {
+    } else if (parent is FormalParameter && identical(parent.identifier, this)) {
       return validateElement(parent, ParameterElement, element);
-    } else if (parent is FunctionDeclaration && identical((parent as FunctionDeclaration).name, this)) {
+    } else if (parent is FunctionDeclaration && identical(parent.name, this)) {
       return validateElement(parent, ExecutableElement, element);
-    } else if (parent is FunctionTypeAlias && identical((parent as FunctionTypeAlias).name, this)) {
+    } else if (parent is FunctionTypeAlias && identical(parent.name, this)) {
       return validateElement(parent, FunctionTypeAliasElement, element);
-    } else if (parent is MethodDeclaration && identical((parent as MethodDeclaration).name, this)) {
+    } else if (parent is MethodDeclaration && identical(parent.name, this)) {
       return validateElement(parent, ExecutableElement, element);
-    } else if (parent is TypeParameter && identical((parent as TypeParameter).name, this)) {
+    } else if (parent is TypeParameter && identical(parent.name, this)) {
       return validateElement(parent, TypeParameterElement, element);
-    } else if (parent is VariableDeclaration && identical((parent as VariableDeclaration).name, this)) {
+    } else if (parent is VariableDeclaration && identical(parent.name, this)) {
       return validateElement(parent, VariableElement, element);
     }
     return element;
@@ -9984,7 +10060,7 @@
  *   | basicStringLiteral
  *
  * rawStringLiteral ::=
- *     '@' basicStringLiteral
+ *     'r' basicStringLiteral
  *
  * simpleStringLiteral ::=
  *     multiLineStringLiteral
@@ -10036,15 +10112,34 @@
   String get value => _value;
 
   /**
+   * Return the offset of the first value character.
+   *
+   * @return the offset of the first value character
+   */
+  int get valueOffset {
+    int valueOffset = 0;
+    if (isRaw) {
+      valueOffset += 1;
+    }
+    if (isMultiline) {
+      valueOffset += 3;
+    } else {
+      valueOffset += 1;
+    }
+    return offset + valueOffset;
+  }
+
+  /**
    * Return `true` if this string literal is a multi-line string.
    *
    * @return `true` if this string literal is a multi-line string
    */
   bool get isMultiline {
-    if (_value.length < 6) {
+    String lexeme = literal.lexeme;
+    if (lexeme.length < 6) {
       return false;
     }
-    return _value.endsWith("\"\"\"") || _value.endsWith("'''");
+    return lexeme.endsWith("\"\"\"") || lexeme.endsWith("'''");
   }
 
   /**
@@ -10052,7 +10147,7 @@
    *
    * @return `true` if this string literal is a raw string
    */
-  bool get isRaw => _value.codeUnitAt(0) == 0x40;
+  bool get isRaw => literal.lexeme.codeUnitAt(0) == 0x72;
 
   bool get isSynthetic => literal.isSynthetic;
 
@@ -11399,7 +11494,7 @@
       if (parent != null && parent.parent != null) {
         ASTNode node = parent.parent;
         if (node is AnnotatedNode) {
-          return (node as AnnotatedNode).documentationComment;
+          return node.documentationComment;
         }
       }
     }
@@ -11437,7 +11532,7 @@
    */
   bool get isConst {
     ASTNode parent = this.parent;
-    return parent is VariableDeclarationList && (parent as VariableDeclarationList).isConst;
+    return parent is VariableDeclarationList && parent.isConst;
   }
 
   /**
@@ -11449,7 +11544,7 @@
    */
   bool get isFinal {
     ASTNode parent = this.parent;
-    return parent is VariableDeclarationList && (parent as VariableDeclarationList).isFinal;
+    return parent is VariableDeclarationList && parent.isFinal;
   }
 
   /**
@@ -11856,14 +11951,14 @@
   }
 
   BreadthFirstVisitor() {
-    this._childVisitor = new GeneralizingASTVisitor_2(this);
+    this._childVisitor = new GeneralizingASTVisitor_BreadthFirstVisitor(this);
   }
 }
 
-class GeneralizingASTVisitor_2 extends GeneralizingASTVisitor<Object> {
+class GeneralizingASTVisitor_BreadthFirstVisitor extends GeneralizingASTVisitor<Object> {
   final BreadthFirstVisitor BreadthFirstVisitor_this;
 
-  GeneralizingASTVisitor_2(this.BreadthFirstVisitor_this) : super();
+  GeneralizingASTVisitor_BreadthFirstVisitor(this.BreadthFirstVisitor_this) : super();
 
   Object visitNode(ASTNode node) {
     BreadthFirstVisitor_this._queue.add(node);
@@ -11942,124 +12037,144 @@
     }
     while (true) {
       if (node.operator.type == TokenType.AMPERSAND) {
+        // integer or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) & (rightOperand as int);
+          return leftOperand & rightOperand;
         }
       } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+        // boolean or {@code null}
         if (leftOperand is bool && rightOperand is bool) {
-          return (leftOperand as bool) && (rightOperand as bool);
+          return leftOperand && rightOperand;
         }
       } else if (node.operator.type == TokenType.BANG_EQ) {
+        // numeric, string, boolean, or {@code null}
         if (leftOperand is bool && rightOperand is bool) {
-          return (leftOperand as bool) != (rightOperand as bool);
+          return leftOperand != rightOperand;
         } else if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) != rightOperand;
+          return leftOperand != rightOperand;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) != rightOperand;
+          return leftOperand != rightOperand;
         } else if (leftOperand is String && rightOperand is String) {
-          return (leftOperand as String) != rightOperand;
+          return leftOperand != rightOperand;
         }
       } else if (node.operator.type == TokenType.BAR) {
+        // integer or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) | (rightOperand as int);
+          return leftOperand | rightOperand;
         }
       } else if (node.operator.type == TokenType.BAR_BAR) {
+        // boolean or {@code null}
         if (leftOperand is bool && rightOperand is bool) {
-          return (leftOperand as bool) || (rightOperand as bool);
+          return leftOperand || rightOperand;
         }
       } else if (node.operator.type == TokenType.CARET) {
+        // integer or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) ^ (rightOperand as int);
+          return leftOperand ^ rightOperand;
         }
       } else if (node.operator.type == TokenType.EQ_EQ) {
+        // numeric, string, boolean, or {@code null}
         if (leftOperand is bool && rightOperand is bool) {
-          return identical(leftOperand as bool, rightOperand as bool);
+          return identical(leftOperand, rightOperand);
         } else if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) == rightOperand;
+          return leftOperand == rightOperand;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) == rightOperand;
+          return leftOperand == rightOperand;
         } else if (leftOperand is String && rightOperand is String) {
-          return (leftOperand as String) == rightOperand;
+          return leftOperand == rightOperand;
         }
       } else if (node.operator.type == TokenType.GT) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int).compareTo(rightOperand as int) > 0;
+          return leftOperand.compareTo(rightOperand) > 0;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double).compareTo(rightOperand as double) > 0;
+          return leftOperand.compareTo(rightOperand) > 0;
         }
       } else if (node.operator.type == TokenType.GT_EQ) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int).compareTo(rightOperand as int) >= 0;
+          return leftOperand.compareTo(rightOperand) >= 0;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double).compareTo(rightOperand as double) >= 0;
+          return leftOperand.compareTo(rightOperand) >= 0;
         }
       } else if (node.operator.type == TokenType.GT_GT) {
+        // integer or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) >> (rightOperand as int);
+          return leftOperand >> rightOperand;
         }
       } else if (node.operator.type == TokenType.LT) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int).compareTo(rightOperand as int) < 0;
+          return leftOperand.compareTo(rightOperand) < 0;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double).compareTo(rightOperand as double) < 0;
+          return leftOperand.compareTo(rightOperand) < 0;
         }
       } else if (node.operator.type == TokenType.LT_EQ) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int).compareTo(rightOperand as int) <= 0;
+          return leftOperand.compareTo(rightOperand) <= 0;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double).compareTo(rightOperand as double) <= 0;
+          return leftOperand.compareTo(rightOperand) <= 0;
         }
       } else if (node.operator.type == TokenType.LT_LT) {
+        // integer or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) << (rightOperand as int);
+          return leftOperand << rightOperand;
         }
       } else if (node.operator.type == TokenType.MINUS) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) - (rightOperand as int);
+          return leftOperand - rightOperand;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) - (rightOperand as double);
+          return leftOperand - rightOperand;
         }
       } else if (node.operator.type == TokenType.PERCENT) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int).remainder(rightOperand as int);
+          return leftOperand.remainder(rightOperand);
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) % (rightOperand as double);
+          return leftOperand % rightOperand;
         }
       } else if (node.operator.type == TokenType.PLUS) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) + (rightOperand as int);
+          return leftOperand + rightOperand;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) + (rightOperand as double);
+          return leftOperand + rightOperand;
         }
       } else if (node.operator.type == TokenType.STAR) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
-          return (leftOperand as int) * (rightOperand as int);
+          return leftOperand * rightOperand;
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) * (rightOperand as double);
+          return leftOperand * rightOperand;
         }
       } else if (node.operator.type == TokenType.SLASH) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
           if (rightOperand != 0) {
-            return (leftOperand as int) ~/ (rightOperand as int);
+            return leftOperand ~/ rightOperand;
           } else {
-            return (leftOperand as int).toDouble() / (rightOperand as int).toDouble();
+            return leftOperand.toDouble() / rightOperand.toDouble();
           }
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) / (rightOperand as double);
+          return leftOperand / rightOperand;
         }
       } else if (node.operator.type == TokenType.TILDE_SLASH) {
+        // numeric or {@code null}
         if (leftOperand is int && rightOperand is int) {
           if (rightOperand != 0) {
-            return (leftOperand as int) ~/ (rightOperand as int);
+            return leftOperand ~/ rightOperand;
           } else {
             return 0;
           }
         } else if (leftOperand is double && rightOperand is double) {
-          return (leftOperand as double) ~/ (rightOperand as double);
+          return leftOperand ~/ rightOperand;
         }
       }
       break;
     }
+    // TODO(brianwilkerson) This doesn't handle numeric conversions.
     return visitExpression(node);
   }
 
@@ -12128,15 +12243,15 @@
         }
       } else if (node.operator.type == TokenType.TILDE) {
         if (operand is int) {
-          return ~(operand as int);
+          return ~operand;
         }
       } else if (node.operator.type == TokenType.MINUS) {
         if (operand == null) {
           return null;
         } else if (operand is int) {
-          return -(operand as int);
+          return -operand;
         } else if (operand is double) {
-          return -(operand as double);
+          return -operand;
         }
       }
       break;
@@ -12163,6 +12278,7 @@
   }
 
   Object visitSymbolLiteral(SymbolLiteral node) {
+    // TODO(brianwilkerson) This isn't optimal because a Symbol is not a String.
     JavaStringBuilder builder = new JavaStringBuilder();
     for (Token component in node.components) {
       if (builder.length > 0) {
@@ -12180,8 +12296,9 @@
    * @return the constant value of the static constant
    */
   Object getConstantValue(Element element) {
+    // TODO(brianwilkerson) Implement this
     if (element is FieldElement) {
-      FieldElement field = element as FieldElement;
+      FieldElement field = element;
       if (field.isStatic && field.isConst) {
       }
     }
@@ -12206,6 +12323,32 @@
     ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
     return node.accept(mapper);
   }
+
+  /**
+   * Locate the [Element] associated with the given [ASTNode] and offset.
+   *
+   * @param node the node (not `null`)
+   * @param offset the offset relative to source
+   * @return the associated element, or `null` if none is found
+   */
+  static Element locate2(ASTNode node, int offset) {
+    // try to get Element from node
+    {
+      Element nodeElement = locate(node);
+      if (nodeElement != null) {
+        return nodeElement;
+      }
+    }
+    // try to get Angular specific Element
+    {
+      Element element = null;
+      if (element != null) {
+        return element;
+      }
+    }
+    // no Element
+    return null;
+  }
 }
 
 /**
@@ -12226,8 +12369,9 @@
 
   Element visitIdentifier(Identifier node) {
     ASTNode parent = node.parent;
+    // Extra work to map Constructor Declarations to their associated Constructor Elements
     if (parent is ConstructorDeclaration) {
-      ConstructorDeclaration decl = parent as ConstructorDeclaration;
+      ConstructorDeclaration decl = parent;
       Identifier returnType = decl.returnType;
       if (identical(returnType, node)) {
         SimpleIdentifier name = decl.name;
@@ -12236,16 +12380,16 @@
         }
         Element element = node.bestElement;
         if (element is ClassElement) {
-          return (element as ClassElement).unnamedConstructor;
+          return element.unnamedConstructor;
         }
       }
     }
     if (parent is LibraryIdentifier) {
-      ASTNode grandParent = (parent as LibraryIdentifier).parent;
+      ASTNode grandParent = parent.parent;
       if (grandParent is PartOfDirective) {
-        Element element = (grandParent as PartOfDirective).element;
+        Element element = grandParent.element;
         if (element is LibraryElement) {
-          return (element as LibraryElement).definingCompilationUnit;
+          return element.definingCompilationUnit;
         }
       }
     }
@@ -12277,7 +12421,7 @@
   Element visitStringLiteral(StringLiteral node) {
     ASTNode parent = node.parent;
     if (parent is UriBasedDirective) {
-      return (parent as UriBasedDirective).uriElement;
+      return parent.uriElement;
     }
     return null;
   }
@@ -12647,6 +12791,7 @@
     } on NodeLocator_NodeFoundException catch (exception) {
       throw exception;
     } on JavaException catch (exception) {
+      // Ignore the exception and proceed in order to visit the rest of the structure.
       AnalysisEngine.instance.logger.logInformation2("Exception caught while traversing an AST structure.", exception);
     }
     if (start <= _startOffset && _endOffset <= end) {
@@ -15882,6 +16027,10 @@
   SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
     Token mappedToken = map(node.token);
     if (mappedToken == null) {
+      // This only happens for SimpleIdentifiers created by the parser as part of scanning
+      // documentation comments (the tokens for those identifiers are not in the original token
+      // stream and hence do not get copied). This extra check can be removed if the scanner is
+      // changed to scan documentation comments for the parser.
       mappedToken = node.token;
     }
     SimpleIdentifier copy = new SimpleIdentifier(mappedToken);
@@ -15978,7 +16127,7 @@
       return null;
     }
     if (identical(node, _oldNode)) {
-      return _newNode as ASTNode;
+      return _newNode;
     }
     return node.accept(this) as ASTNode;
   }
@@ -16162,15 +16311,16 @@
         return;
       }
       if (stmt is VariableDeclarationStatement) {
-        addVariables((stmt as VariableDeclarationStatement).variables.variables);
+        addVariables(stmt.variables.variables);
       } else if (stmt is FunctionDeclarationStatement && !_referenceIsWithinLocalFunction) {
-        addToScope((stmt as FunctionDeclarationStatement).functionDeclaration.name);
+        addToScope(stmt.functionDeclaration.name);
       }
     }
   }
 
   bool isInRange(ASTNode node) {
     if (_position < 0) {
+      // if source position is not set then all nodes are in range
       return true;
     }
     return node.end < _position;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 8fe9e12..5b23784 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -1,15 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 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.constant;
 
 import 'java_core.dart';
+import 'java_engine.dart' show ObjectUtilities;
 import 'source.dart' show Source;
 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode;
-import 'scanner.dart' show TokenType;
+import 'scanner.dart' show Token, TokenType;
 import 'ast.dart';
 import 'element.dart';
+import 'resolver.dart' show TypeProvider;
 import 'engine.dart' show AnalysisEngine;
+import 'utilities_dart.dart' show ParameterKind;
 
 /**
  * Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
@@ -19,36 +26,42 @@
  * * A literal number.
  * * A literal boolean.
  * * A literal string where any interpolated expression is a compile-time constant that evaluates
- * to a numeric, string or boolean value or to `null`.
- * * `null`.
- * * A reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, a class or a type parameter.
+ * to a numeric, string or boolean value or to <b>null</b>.
+ * * A literal symbol.
+ * * <b>null</b>.
+ * * A qualified reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, class or type alias.
  * * A constant constructor invocation.
  * * A constant list literal.
  * * A constant map literal.
  * * A simple or qualified identifier denoting a top-level function or a static method.
- * * A parenthesized expression `(e)` where `e` is a constant expression.
- * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,
- * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
- * numeric, string or boolean value or to `null`.
- * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where
- * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
- * to `null`.
- * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,
- * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`
- * are constant expressions that evaluate to an integer value or to `null`.
- * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,
- * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,
- * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`
- * are constant expressions that evaluate to a numeric value or to `null`.
+ * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expression.
+ * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> where
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i>identical()</i> is
+ * statically bound to the predefined dart function <i>identical()</i> discussed above.
+ * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub>
+ * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
+ * that evaluate to a numeric, string or boolean value.
+ * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e<sub>2</sub></i> or
+ * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i>e2</sub></i> are
+ * constant expressions that evaluate to a boolean value.
+ * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> &amp; e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub>
+ * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where <i>e</i>,
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that evaluate to an
+ * integer value or to <b>null</b>.
+ * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
+ * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * expressions that evaluate to a numeric value or to <b>null</b>.
+ * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> where
+ * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are constant expressions, and
+ * <i>e<sub>1</sub></i> evaluates to a boolean value.
  *
- * </blockquote> The values returned by instances of this class are therefore `null` and
- * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
- * `DartObject`.
- *
- * In addition, this class defines several values that can be returned to indicate various
- * conditions encountered during evaluation. These are documented with the static field that define
- * those values.
+ * </blockquote>
  */
 class ConstantEvaluator {
   /**
@@ -57,18 +70,25 @@
   Source _source;
 
   /**
+   * The type provider used to access the known types.
+   */
+  TypeProvider _typeProvider;
+
+  /**
    * Initialize a newly created evaluator to evaluate expressions in the given source.
    *
    * @param source the source containing the expression(s) that will be evaluated
+   * @param typeProvider the type provider used to access known types
    */
-  ConstantEvaluator(Source source) {
+  ConstantEvaluator(Source source, TypeProvider typeProvider) {
     this._source = source;
+    this._typeProvider = typeProvider;
   }
 
   EvaluationResult evaluate(Expression expression) {
-    EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+    EvaluationResultImpl result = expression.accept(new ConstantVisitor(_typeProvider));
     if (result is ValidResult) {
-      return EvaluationResult.forValue((result as ValidResult).value);
+      return EvaluationResult.forValue(result.value);
     }
     List<AnalysisError> errors = new List<AnalysisError>();
     for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) {
@@ -80,6 +100,88 @@
 }
 
 /**
+ * The interface `DartObject` defines the behavior of objects that represent the state of a
+ * Dart object.
+ */
+abstract class DartObject {
+  /**
+   * Return the boolean value of this object, or `null` if either the value of this object is
+   * not known or this object is not of type 'bool'.
+   *
+   * @return the boolean value of this object
+   */
+  bool get boolValue;
+
+  /**
+   * Return the floating point value of this object, or `null` if either the value of this
+   * object is not known or this object is not of type 'double'.
+   *
+   * @return the floating point value of this object
+   */
+  double get doubleValue;
+
+  /**
+   * Return the integer value of this object, or `null` if either the value of this object is
+   * not known or this object is not of type 'int'.
+   *
+   * @return the integer value of this object
+   */
+  int get intValue;
+
+  /**
+   * Return the string value of this object, or `null` if either the value of this object is
+   * not known or this object is not of type 'String'.
+   *
+   * @return the string value of this object
+   */
+  String get stringValue;
+
+  /**
+   * Return the run-time type of this object.
+   *
+   * @return the run-time type of this object
+   */
+  InterfaceType get type;
+
+  /**
+   * Return this object's value if it can be represented exactly, or `null` if either the
+   * value cannot be represented exactly or if the value is `null`. Clients should use
+   * [hasExactValue] to distinguish between these two cases.
+   *
+   * @return this object's value
+   */
+  Object get value;
+
+  /**
+   * Return `true` if this object's value can be represented exactly.
+   *
+   * @return `true` if this object's value can be represented exactly
+   */
+  bool hasExactValue();
+
+  /**
+   * Return `true` if this object represents the value 'false'.
+   *
+   * @return `true` if this object represents the value 'false'
+   */
+  bool get isFalse;
+
+  /**
+   * Return `true` if this object represents the value 'null'.
+   *
+   * @return `true` if this object represents the value 'null'
+   */
+  bool get isNull;
+
+  /**
+   * Return `true` if this object represents the value 'true'.
+   *
+   * @return `true` if this object represents the value 'true'
+   */
+  bool get isTrue;
+}
+
+/**
  * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
  * expression.
  */
@@ -100,12 +202,12 @@
    * @param value the value of the expression
    * @return the result of evaluating an expression that is a compile-time constant
    */
-  static EvaluationResult forValue(Object value) => new EvaluationResult(value, null);
+  static EvaluationResult forValue(DartObject value) => new EvaluationResult(value, null);
 
   /**
    * The value of the expression.
    */
-  final Object value;
+  final DartObject value;
 
   /**
    * The errors that should be reported for the expression(s) that were evaluated.
@@ -168,11 +270,16 @@
  * Instances of the class `ConstantValueComputer` compute the values of constant variables in
  * one or more compilation units. The expected usage pattern is for the compilation units to be
  * added to this computer using the method [add] and then for the method
- * [computeValues] to invoked exactly once. Any use of an instance after invoking the
+ * [computeValues] to be invoked exactly once. Any use of an instance after invoking the
  * method [computeValues] will result in unpredictable behavior.
  */
 class ConstantValueComputer {
   /**
+   * The type provider used to access the known types.
+   */
+  TypeProvider _typeProvider;
+
+  /**
    * The object used to find constant variables in the compilation units that were added.
    */
   ConstantFinder _constantFinder = new ConstantFinder();
@@ -189,6 +296,15 @@
   Map<VariableElement, VariableDeclaration> _declarationMap;
 
   /**
+   * Initialize a newly created constant value computer.
+   *
+   * @param typeProvider the type provider used to access known types
+   */
+  ConstantValueComputer(TypeProvider typeProvider) {
+    this._typeProvider = typeProvider;
+  }
+
+  /**
    * Add the constant variables in the given compilation unit to the list of constant variables
    * whose value needs to be computed.
    *
@@ -218,7 +334,12 @@
       if (!_referenceGraph.isEmpty) {
         List<VariableElement> variablesInCycle = _referenceGraph.findCycle();
         if (variablesInCycle == null) {
-          AnalysisEngine.instance.logger.logError("Exiting constant value computer with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cycle");
+          //
+          // This should not happen. Either the graph should be empty, or there should be at least
+          // one sink, or there should be a cycle. If this does happen we exit to prevent an
+          // infinite loop.
+          //
+          AnalysisEngine.instance.logger.logError("Exiting constant value computer with ${_referenceGraph.nodeCount} variables that are neither sinks nor in a cycle");
           return;
         }
         for (VariableElement variable in variablesInCycle) {
@@ -237,13 +358,19 @@
   void computeValueFor(VariableElement variable) {
     VariableDeclaration declaration = _declarationMap[variable];
     if (declaration == null) {
+      //
+      // The declaration will be null when the variable was added to the graph as a result of being
+      // referenced by another variable but is not defined in the compilation units that were added
+      // to this computer. In such cases, the variable should already have a value associated with
+      // it, but we don't bother to check because there's nothing we can do about it at this point.
+      //
       return;
     }
-    EvaluationResultImpl result = declaration.initializer.accept(new ConstantVisitor());
+    EvaluationResultImpl result = declaration.initializer.accept(new ConstantVisitor(_typeProvider));
     (variable as VariableElementImpl).evaluationResult = result;
     if (result is ErrorResult) {
       List<AnalysisError> errors = new List<AnalysisError>();
-      for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) {
+      for (ErrorResult_ErrorData data in result.errorData) {
         ASTNode node = data.node;
         Source source = variable.getAncestor(CompilationUnitElement).source;
         errors.add(new AnalysisError.con2(source, node.offset, node.length, data.errorCode, []));
@@ -271,39 +398,70 @@
  * * A literal number.
  * * A literal boolean.
  * * A literal string where any interpolated expression is a compile-time constant that evaluates
- * to a numeric, string or boolean value or to `null`.
- * * `null`.
- * * A reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, a class or a type parameter.
+ * to a numeric, string or boolean value or to <b>null</b>.
+ * * A literal symbol.
+ * * <b>null</b>.
+ * * A qualified reference to a static constant variable.
+ * * An identifier expression that denotes a constant variable, class or type alias.
  * * A constant constructor invocation.
  * * A constant list literal.
  * * A constant map literal.
  * * A simple or qualified identifier denoting a top-level function or a static method.
- * * A parenthesized expression `(e)` where `e` is a constant expression.
- * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,
- * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
- * numeric, string or boolean value or to `null`.
- * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where
- * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
- * to `null`.
- * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,
- * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`
- * are constant expressions that evaluate to an integer value or to `null`.
- * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,
- * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,
- * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`
- * are constant expressions that evaluate to a numeric value or to `null`.
+ * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expression.
+ * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> where
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i>identical()</i> is
+ * statically bound to the predefined dart function <i>identical()</i> discussed above.
+ * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub>
+ * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
+ * that evaluate to a numeric, string or boolean value.
+ * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e<sub>2</sub></i> or
+ * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i>e2</sub></i> are
+ * constant expressions that evaluate to a boolean value.
+ * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> &amp; e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub>
+ * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where <i>e</i>,
+ * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that evaluate to an
+ * integer value or to <b>null</b>.
+ * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</sub></i>,
+ * <i>e<sub>1</sub> - e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
+ * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * expressions that evaluate to a numeric value or to <b>null</b>.
+ * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> where
+ * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are constant expressions, and
+ * <i>e<sub>1</sub></i> evaluates to a boolean value.
  *
  * </blockquote>
  */
 class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
+  /**
+   * The type provider used to access the known types.
+   */
+  TypeProvider _typeProvider;
+
+  /**
+   * An shared object representing the value 'null'.
+   */
+  DartObjectImpl _nullObject;
+
+  /**
+   * Initialize a newly created constant visitor.
+   *
+   * @param typeProvider the type provider used to access known types
+   */
+  ConstantVisitor(TypeProvider typeProvider) {
+    this._typeProvider = typeProvider;
+  }
+
   EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) {
     EvaluationResultImpl result = null;
     for (StringLiteral string in node.strings) {
       if (result == null) {
         result = string.accept(this);
       } else {
-        result = result.concatenate(node, string.accept(this));
+        result = result.concatenate(_typeProvider, node, string.accept(this));
       }
     }
     return result;
@@ -313,111 +471,179 @@
     EvaluationResultImpl leftResult = node.leftOperand.accept(this);
     EvaluationResultImpl rightResult = node.rightOperand.accept(this);
     TokenType operatorType = node.operator.type;
+    // 'null' is almost never good operand
     if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) {
-      if (leftResult is ValidResult && (leftResult as ValidResult).isNull || rightResult is ValidResult && (rightResult as ValidResult).isNull) {
+      if (leftResult is ValidResult && leftResult.isNull || rightResult is ValidResult && rightResult.isNull) {
         return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
       }
     }
+    // evaluate operator
     while (true) {
       if (operatorType == TokenType.AMPERSAND) {
-        return leftResult.bitAnd(node, rightResult);
+        return leftResult.bitAnd(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
-        return leftResult.logicalAnd(node, rightResult);
+        return leftResult.logicalAnd(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.BANG_EQ) {
-        return leftResult.notEqual(node, rightResult);
+        return leftResult.notEqual(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.BAR) {
-        return leftResult.bitOr(node, rightResult);
+        return leftResult.bitOr(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.BAR_BAR) {
-        return leftResult.logicalOr(node, rightResult);
+        return leftResult.logicalOr(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.CARET) {
-        return leftResult.bitXor(node, rightResult);
+        return leftResult.bitXor(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.EQ_EQ) {
-        return leftResult.equalEqual(node, rightResult);
+        return leftResult.equalEqual(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.GT) {
-        return leftResult.greaterThan(node, rightResult);
+        return leftResult.greaterThan(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.GT_EQ) {
-        return leftResult.greaterThanOrEqual(node, rightResult);
+        return leftResult.greaterThanOrEqual(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.GT_GT) {
-        return leftResult.shiftRight(node, rightResult);
+        return leftResult.shiftRight(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.LT) {
-        return leftResult.lessThan(node, rightResult);
+        return leftResult.lessThan(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.LT_EQ) {
-        return leftResult.lessThanOrEqual(node, rightResult);
+        return leftResult.lessThanOrEqual(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.LT_LT) {
-        return leftResult.shiftLeft(node, rightResult);
+        return leftResult.shiftLeft(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.MINUS) {
-        return leftResult.minus(node, rightResult);
+        return leftResult.minus(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.PERCENT) {
-        return leftResult.remainder(node, rightResult);
+        return leftResult.remainder(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.PLUS) {
-        return leftResult.add(node, rightResult);
+        return leftResult.add(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.STAR) {
-        return leftResult.times(node, rightResult);
+        return leftResult.times(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.SLASH) {
-        return leftResult.divide(node, rightResult);
+        return leftResult.divide(_typeProvider, node, rightResult);
       } else if (operatorType == TokenType.TILDE_SLASH) {
-        return leftResult.integerDivide(node, rightResult);
+        return leftResult.integerDivide(_typeProvider, node, rightResult);
       }
       break;
     }
+    // TODO(brianwilkerson) Figure out which error to report.
     return error(node, null);
   }
 
-  EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ? ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE;
+  EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => valid2(_typeProvider.boolType, BoolState.from(node.value));
 
   EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) {
     Expression condition = node.condition;
     EvaluationResultImpl conditionResult = condition.accept(this);
-    conditionResult = conditionResult.applyBooleanConversion(condition);
+    EvaluationResultImpl thenResult = node.thenExpression.accept(this);
+    EvaluationResultImpl elseResult = node.elseExpression.accept(this);
+    if (conditionResult is ErrorResult) {
+      return union(union(conditionResult as ErrorResult, thenResult), elseResult);
+    } else if (!(conditionResult as ValidResult).isBool) {
+      return new ErrorResult.con1(condition, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+    } else if (thenResult is ErrorResult) {
+      return union(thenResult, elseResult);
+    } else if (elseResult is ErrorResult) {
+      return elseResult;
+    }
+    conditionResult = conditionResult.applyBooleanConversion(_typeProvider, condition);
     if (conditionResult is ErrorResult) {
       return conditionResult;
     }
-    EvaluationResultImpl thenResult = node.thenExpression.accept(this);
-    if (thenResult is ErrorResult) {
+    ValidResult validResult = conditionResult as ValidResult;
+    if (validResult.isTrue) {
       return thenResult;
-    }
-    EvaluationResultImpl elseResult = node.elseExpression.accept(this);
-    if (elseResult is ErrorResult) {
+    } else if (validResult.isFalse) {
       return elseResult;
     }
-    return (identical(conditionResult, ValidResult.RESULT_TRUE)) ? thenResult : elseResult;
+    InterfaceType thenType = (thenResult as ValidResult).value.type;
+    InterfaceType elseType = (elseResult as ValidResult).value.type;
+    return valid(thenType.getLeastUpperBound(elseType) as InterfaceType);
   }
 
-  EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult(node.value);
+  EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => valid2(_typeProvider.doubleType, new DoubleState(node.value));
 
   EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpression node) {
     if (!node.isConst) {
+      // TODO(brianwilkerson) Figure out which error to report.
       return error(node, null);
     }
     ConstructorElement constructor = node.staticElement;
     if (constructor != null && constructor.isConst) {
-      node.argumentList.accept(this);
-      return ValidResult.RESULT_OBJECT;
+      NodeList<Expression> arguments = node.argumentList.arguments;
+      int argumentCount = arguments.length;
+      List<DartObjectImpl> argumentValues = new List<DartObjectImpl>(argumentCount);
+      Map<String, DartObjectImpl> namedArgumentValues = new Map<String, DartObjectImpl>();
+      for (int i = 0; i < argumentCount; i++) {
+        Expression argument = arguments[i];
+        if (argument is NamedExpression) {
+          NamedExpression namedExpression = argument;
+          String name = namedExpression.name.label.name;
+          namedArgumentValues[name] = valueOf(namedExpression.expression);
+          argumentValues[i] = null2;
+        } else {
+          argumentValues[i] = valueOf(argument);
+        }
+      }
+      InterfaceType definingClass = constructor.returnType as InterfaceType;
+      if (definingClass.element.library.isDartCore) {
+        String className = definingClass.name;
+        if (className == "Symbol" && argumentCount == 1) {
+          String argumentValue = argumentValues[0].stringValue;
+          if (argumentValue != null) {
+            return valid2(definingClass, new SymbolState(argumentValue));
+          }
+        }
+      }
+      Map<String, DartObjectImpl> fieldMap = new Map<String, DartObjectImpl>();
+      List<ParameterElement> parameters = constructor.parameters;
+      int parameterCount = parameters.length;
+      for (int i = 0; i < parameterCount; i++) {
+        ParameterElement parameter = parameters[i];
+        if (parameter.isInitializingFormal) {
+          String fieldName = (parameter as FieldFormalParameterElement).field.name;
+          if (identical(parameter.parameterKind, ParameterKind.NAMED)) {
+            DartObjectImpl argumentValue = namedArgumentValues[parameter.name];
+            if (argumentValue != null) {
+              fieldMap[fieldName] = argumentValue;
+            }
+          } else if (i < argumentCount) {
+            fieldMap[fieldName] = argumentValues[i];
+          }
+        }
+      }
+      // TODO(brianwilkerson) This doesn't handle fields initialized in an initializer. We should be
+      // able to handle fields initialized by the superclass' constructor fairly easily, but other
+      // initializers will be harder.
+      return valid2(definingClass, new GenericState(fieldMap));
     }
+    // TODO(brianwilkerson) Figure out which error to report.
     return error(node, null);
   }
 
-  EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResult(node.value);
+  EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => valid2(_typeProvider.intType, new IntState(node.value));
 
   EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node) {
     EvaluationResultImpl result = node.expression.accept(this);
-    return result.performToString(node);
+    if (result is ValidResult && !result.isBoolNumStringOrNull) {
+      return error(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+    }
+    return result.performToString(_typeProvider, node);
   }
 
-  EvaluationResultImpl visitInterpolationString(InterpolationString node) => new ValidResult(node.value);
+  EvaluationResultImpl visitInterpolationString(InterpolationString node) => valid2(_typeProvider.stringType, new StringState(node.value));
 
   EvaluationResultImpl visitListLiteral(ListLiteral node) {
     if (node.constKeyword == null) {
       return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL);
     }
     ErrorResult result = null;
+    List<DartObjectImpl> elements = new List<DartObjectImpl>();
     for (Expression element in node.elements) {
-      result = union(result, element.accept(this));
+      EvaluationResultImpl elementResult = element.accept(this);
+      result = union(result, elementResult);
+      if (elementResult is ValidResult) {
+        elements.add(elementResult.value);
+      }
     }
     if (result != null) {
       return result;
     }
-    return ValidResult.RESULT_OBJECT;
+    return valid2(_typeProvider.listType, new ListState(new List.from(elements)));
   }
 
   EvaluationResultImpl visitMapLiteral(MapLiteral node) {
@@ -425,35 +651,42 @@
       return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL);
     }
     ErrorResult result = null;
+    Map<DartObjectImpl, DartObjectImpl> map = new Map<DartObjectImpl, DartObjectImpl>();
     for (MapLiteralEntry entry in node.entries) {
-      result = union(result, entry.key.accept(this));
-      result = union(result, entry.value.accept(this));
+      EvaluationResultImpl keyResult = entry.key.accept(this);
+      EvaluationResultImpl valueResult = entry.value.accept(this);
+      result = union(result, keyResult);
+      result = union(result, valueResult);
+      if (keyResult is ValidResult && valueResult is ValidResult) {
+        map[keyResult.value] = valueResult.value;
+      }
     }
     if (result != null) {
       return result;
     }
-    return ValidResult.RESULT_OBJECT;
+    return valid2(_typeProvider.mapType, new MapState(map));
   }
 
   EvaluationResultImpl visitMethodInvocation(MethodInvocation node) {
     Element element = node.methodName.staticElement;
     if (element is FunctionElement) {
-      FunctionElement function = element as FunctionElement;
+      FunctionElement function = element;
       if (function.name == "identical") {
         NodeList<Expression> arguments = node.argumentList.arguments;
         if (arguments.length == 2) {
           Element enclosingElement = function.enclosingElement;
           if (enclosingElement is CompilationUnitElement) {
-            LibraryElement library = (enclosingElement as CompilationUnitElement).library;
+            LibraryElement library = enclosingElement.library;
             if (library.isDartCore) {
               EvaluationResultImpl leftArgument = arguments[0].accept(this);
               EvaluationResultImpl rightArgument = arguments[1].accept(this);
-              return leftArgument.equalEqual(node, rightArgument);
+              return leftArgument.equalEqual(_typeProvider, node, rightArgument);
             }
           }
         }
       }
     }
+    // TODO(brianwilkerson) Figure out which error to report.
     return error(node, null);
   }
 
@@ -461,11 +694,12 @@
 
   EvaluationResultImpl visitNode(ASTNode node) => error(node, null);
 
-  EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_NULL;
+  EvaluationResultImpl visitNullLiteral(NullLiteral node) => new ValidResult(null2);
 
   EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this);
 
   EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) {
+    // validate prefix
     SimpleIdentifier prefixNode = node.prefix;
     Element prefixElement = prefixNode.staticElement;
     if (prefixElement is! PrefixElement) {
@@ -474,24 +708,26 @@
         return error(node, null);
       }
     }
+    // validate prefixed identifier
     return getConstantValue(node, node.staticElement);
   }
 
   EvaluationResultImpl visitPrefixExpression(PrefixExpression node) {
     EvaluationResultImpl operand = node.operand.accept(this);
-    if (operand is ValidResult && (operand as ValidResult).isNull) {
+    if (operand is ValidResult && operand.isNull) {
       return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
     }
     while (true) {
       if (node.operator.type == TokenType.BANG) {
-        return operand.logicalNot(node);
+        return operand.logicalNot(_typeProvider, node);
       } else if (node.operator.type == TokenType.TILDE) {
-        return operand.bitNot(node);
+        return operand.bitNot(_typeProvider, node);
       } else if (node.operator.type == TokenType.MINUS) {
-        return operand.negated(node);
+        return operand.negated(_typeProvider, node);
       }
       break;
     }
+    // TODO(brianwilkerson) Figure out which error to report.
     return error(node, null);
   }
 
@@ -499,7 +735,7 @@
 
   EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConstantValue(node, node.staticElement);
 
-  EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new ValidResult(node.value);
+  EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => valid2(_typeProvider.stringType, new StringState(node.value));
 
   EvaluationResultImpl visitStringInterpolation(StringInterpolation node) {
     EvaluationResultImpl result = null;
@@ -507,13 +743,23 @@
       if (result == null) {
         result = element.accept(this);
       } else {
-        result = result.concatenate(node, element.accept(this));
+        result = result.concatenate(_typeProvider, node, element.accept(this));
       }
     }
     return result;
   }
 
-  EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) => ValidResult.RESULT_SYMBOL;
+  EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) {
+    JavaStringBuilder builder = new JavaStringBuilder();
+    List<Token> components = node.components;
+    for (int i = 0; i < components.length; i++) {
+      if (i > 0) {
+        builder.appendChar(0x2E);
+      }
+      builder.append(components[i].lexeme);
+    }
+    return valid2(_typeProvider.symbolType, new SymbolState(builder.toString()));
+  }
 
   /**
    * Return a result object representing an error associated with the given node.
@@ -536,22 +782,36 @@
       element = (element as PropertyAccessorElement).variable;
     }
     if (element is VariableElementImpl) {
-      VariableElementImpl variableElementImpl = element as VariableElementImpl;
+      VariableElementImpl variableElementImpl = element;
       EvaluationResultImpl value = variableElementImpl.evaluationResult;
       if (variableElementImpl.isConst && value != null) {
         return value;
       }
     } else if (element is ExecutableElement) {
-      if ((element as ExecutableElement).isStatic) {
-        return new ValidResult(element);
+      ExecutableElement function = element;
+      if (function.isStatic) {
+        return valid2(_typeProvider.functionType, new FunctionState(function));
       }
     } else if (element is ClassElement || element is FunctionTypeAliasElement) {
-      return ValidResult.RESULT_OBJECT;
+      return valid2(_typeProvider.typeType, new TypeState(element));
     }
+    // TODO(brianwilkerson) Figure out which error to report.
     return error(node, null);
   }
 
   /**
+   * Return an object representing the value 'null'.
+   *
+   * @return an object representing the value 'null'
+   */
+  DartObjectImpl get null2 {
+    if (_nullObject == null) {
+      _nullObject = new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
+    }
+    return _nullObject;
+  }
+
+  /**
    * Return the union of the errors encoded in the given results.
    *
    * @param leftResult the first set of errors, or `null` if there was no previous collection
@@ -563,13 +823,46 @@
   ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) {
     if (rightResult is ErrorResult) {
       if (leftResult != null) {
-        return new ErrorResult.con2(leftResult, rightResult as ErrorResult);
+        return new ErrorResult.con2(leftResult, rightResult);
       } else {
-        return rightResult as ErrorResult;
+        return rightResult;
       }
     }
     return leftResult;
   }
+
+  ValidResult valid(InterfaceType type) {
+    if (type.element.library.isDartCore) {
+      String typeName = type.name;
+      if (typeName == "bool") {
+        return valid2(type, BoolState.UNKNOWN_VALUE);
+      } else if (typeName == "double") {
+        return valid2(type, DoubleState.UNKNOWN_VALUE);
+      } else if (typeName == "int") {
+        return valid2(type, IntState.UNKNOWN_VALUE);
+      } else if (typeName == "String") {
+        return valid2(type, StringState.UNKNOWN_VALUE);
+      }
+    }
+    return valid2(type, GenericState.UNKNOWN_VALUE);
+  }
+
+  ValidResult valid2(InterfaceType type, InstanceState state) => new ValidResult(new DartObjectImpl(type, state));
+
+  /**
+   * Return the value of the given expression, or a representation of 'null' if the expression
+   * cannot be evaluated.
+   *
+   * @param expression the expression whose value is to be returned
+   * @return the value of the given expression
+   */
+  DartObjectImpl valueOf(Expression expression) {
+    EvaluationResultImpl expressionValue = expression.accept(this);
+    if (expressionValue is ValidResult) {
+      return expressionValue.value;
+    }
+    return null2;
+  }
 }
 
 /**
@@ -596,10 +889,16 @@
    * @param tail the node at the tail of the edge
    */
   void addEdge(N head, N tail) {
+    //
+    // First, ensure that the tail is a node known to the graph.
+    //
     Set<N> tails = _edges[tail];
     if (tails == null) {
       _edges[tail] = new Set<N>();
     }
+    //
+    // Then create the edge.
+    //
     tails = _edges[head];
     if (tails == null) {
       tails = new Set<N>();
@@ -763,97 +1062,97 @@
     _errors.addAll(secondResult._errors);
   }
 
-  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
+  EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToError(node, this);
 
-  EvaluationResultImpl applyBooleanConversion(ASTNode node) => this;
+  EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode node) => this;
 
-  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
+  EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndError(node, this);
 
-  EvaluationResultImpl bitNot(Expression node) => this;
+  EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) => this;
 
-  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
+  EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrError(node, this);
 
-  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
+  EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorError(node, this);
 
-  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
+  EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateError(node, this);
 
-  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
+  EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideError(node, this);
 
-  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
+  EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualError(node, this);
 
-  bool equalValues(EvaluationResultImpl result) => false;
+  bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) => false;
 
   List<ErrorResult_ErrorData> get errorData => _errors;
 
-  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
+  EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanError(node, this);
 
-  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
+  EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
 
-  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
+  EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
 
-  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
-  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
+  EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanError(node, this);
 
-  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
+  EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
 
-  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
+  EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndError(node, this);
 
-  EvaluationResultImpl logicalNot(Expression node) => this;
+  EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) => this;
 
-  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
+  EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrError(node, this);
 
-  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
+  EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusError(node, this);
 
-  EvaluationResultImpl negated(Expression node) => this;
+  EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) => this;
 
-  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
+  EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualError(node, this);
 
-  EvaluationResultImpl performToString(ASTNode node) => this;
+  EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node) => this;
 
-  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
+  EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderError(node, this);
 
-  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
+  EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftError(node, this);
 
-  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
+  EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightError(node, this);
 
-  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
+  EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesError(node, this);
 
   EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
   EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
-  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
@@ -861,41 +1160,41 @@
 
   EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
-  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 
   EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
 
-  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) => this;
+  EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) => this;
 }
 
 class ErrorResult_ErrorData {
@@ -924,143 +1223,144 @@
  * expression.
  */
 abstract class EvaluationResultImpl {
-  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
   /**
    * Return the result of applying boolean conversion to this result.
    *
+   * @param typeProvider the type provider used to access known types
    * @param node the node against which errors should be reported
    * @return the result of applying boolean conversion to the given value
    */
-  EvaluationResultImpl applyBooleanConversion(ASTNode node);
+  EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode node);
 
-  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl bitNot(Expression node);
+  EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node);
 
-  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand);
 
-  bool equalValues(EvaluationResultImpl result);
+  bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result);
 
-  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl logicalNot(Expression node);
+  EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node);
 
-  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl negated(Expression node);
+  EvaluationResultImpl negated(TypeProvider typeProvider, Expression node);
 
-  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl performToString(ASTNode node);
+  EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node);
 
-  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
-  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand);
+  EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand);
 
   EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand);
+  EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
 
   EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand);
+  EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand);
 
   EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand);
 
   EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
-  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand);
 
   EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
-  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 
   EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand);
 
-  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand);
+  EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand);
 }
 
 /**
@@ -1113,66 +1413,9 @@
  */
 class ValidResult extends EvaluationResultImpl {
   /**
-   * A result object representing the value 'false'.
-   */
-  static ValidResult RESULT_FALSE = new ValidResult(false);
-
-  /**
-   * A result object representing the an object without specific type on which no further operations
-   * can be performed.
-   */
-  static ValidResult RESULT_DYNAMIC = new ValidResult(null);
-
-  /**
-   * A result object representing the an arbitrary integer on which no further operations can be
-   * performed.
-   */
-  static ValidResult RESULT_INT = new ValidResult(0);
-
-  /**
-   * A result object representing the `null` value.
-   */
-  static ValidResult RESULT_NULL = new ValidResult(null);
-
-  /**
-   * A result object representing the an arbitrary numeric on which no further operations can be
-   * performed.
-   */
-  static ValidResult RESULT_NUM = new ValidResult(null);
-
-  /**
-   * A result object representing the an arbitrary boolean on which no further operations can be
-   * performed.
-   */
-  static ValidResult RESULT_BOOL = new ValidResult(null);
-
-  /**
-   * A result object representing the an arbitrary object on which no further operations can be
-   * performed.
-   */
-  static ValidResult RESULT_OBJECT = new ValidResult(new Object());
-
-  /**
-   * A result object representing the an arbitrary symbol on which no further operations can be
-   * performed.
-   */
-  static ValidResult RESULT_SYMBOL = new ValidResult(new Object());
-
-  /**
-   * A result object representing the an arbitrary string on which no further operations can be
-   * performed.
-   */
-  static ValidResult RESULT_STRING = new ValidResult("<string>");
-
-  /**
-   * A result object representing the value 'true'.
-   */
-  static ValidResult RESULT_TRUE = new ValidResult(true);
-
-  /**
    * The value of the expression.
    */
-  final Object value;
+  final DartObjectImpl value;
 
   /**
    * Initialize a newly created result to represent the given value.
@@ -1181,7 +1424,7 @@
    */
   ValidResult(this.value);
 
-  EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(node, this);
+  EvaluationResultImpl add(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.addToValid(typeProvider, node, this);
 
   /**
    * Return the result of applying boolean conversion to this result.
@@ -1189,106 +1432,133 @@
    * @param node the node against which errors should be reported
    * @return the result of applying boolean conversion to the given value
    */
-  EvaluationResultImpl applyBooleanConversion(ASTNode node) => booleanConversion(node, value);
-
-  EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(node, this);
-
-  EvaluationResultImpl bitNot(Expression node) {
-    if (isSomeInt) {
-      return RESULT_INT;
+  EvaluationResultImpl applyBooleanConversion(TypeProvider typeProvider, ASTNode node) {
+    try {
+      return valueOf(value.convertToBool(typeProvider));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (value == null) {
-      return error(node);
-    } else if (value is int) {
-      return valueOf(~(value as int));
-    }
-    return error(node);
   }
 
-  EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(node, this);
+  EvaluationResultImpl bitAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitAndValid(typeProvider, node, this);
 
-  EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(node, this);
-
-  EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(node, this);
-
-  EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(node, this);
-
-  EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(node, this);
-
-  bool equalValues(EvaluationResultImpl result) => identical(equalEqual(null, result), RESULT_TRUE);
-
-  EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(node, this);
-
-  EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this);
-
-  EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(node, this);
-
-  EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(node, this);
-
-  EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(node, this);
-
-  EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(node, this);
-
-  EvaluationResultImpl logicalNot(Expression node) {
-    if (isSomeBool) {
-      return RESULT_BOOL;
+  EvaluationResultImpl bitNot(TypeProvider typeProvider, Expression node) {
+    try {
+      return valueOf(value.bitNot(typeProvider));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (value == null) {
-      return RESULT_TRUE;
-    } else if (value is bool) {
-      return (value as bool) ? RESULT_FALSE : RESULT_TRUE;
-    }
-    return error(node);
   }
 
-  EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(node, this);
+  EvaluationResultImpl bitOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitOrValid(typeProvider, node, this);
 
-  EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(node, this);
+  EvaluationResultImpl bitXor(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.bitXorValid(typeProvider, node, this);
 
-  EvaluationResultImpl negated(Expression node) {
-    if (isSomeNum) {
-      return RESULT_INT;
+  EvaluationResultImpl concatenate(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.concatenateValid(typeProvider, node, this);
+
+  EvaluationResultImpl divide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.divideValid(typeProvider, node, this);
+
+  EvaluationResultImpl equalEqual(TypeProvider typeProvider, Expression node, EvaluationResultImpl rightOperand) => rightOperand.equalEqualValid(typeProvider, node, this);
+
+  bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
+    if (result is! ValidResult) {
+      return false;
     }
-    if (value == null) {
-      return error(node);
-    } else if (value is int) {
-      return valueOf(-(value as int));
-    } else if (value is double) {
-      return valueOf3(-(value as double));
-    }
-    return error(node);
+    return value == (result as ValidResult).value;
   }
 
-  EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(node, this);
+  EvaluationResultImpl greaterThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanValid(typeProvider, node, this);
 
-  EvaluationResultImpl performToString(ASTNode node) {
-    if (value == null) {
-      return valueOf4("null");
-    } else if (value is bool) {
-      return valueOf4((value as bool).toString());
-    } else if (value is int) {
-      return valueOf4((value as int).toString());
-    } else if (value is double) {
-      return valueOf4((value as double).toString());
-    } else if (value is String) {
-      return this;
-    } else if (isSomeBool) {
-      return valueOf4("<some bool>");
-    } else if (isSomeInt) {
-      return valueOf4("<some int>");
-    } else if (isSomeNum) {
-      return valueOf4("<some num>");
+  EvaluationResultImpl greaterThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.greaterThanOrEqualValid(typeProvider, node, this);
+
+  EvaluationResultImpl integerDivide(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(typeProvider, node, this);
+
+  /**
+   * Return `true` if this object represents an object whose type is 'bool'.
+   *
+   * @return `true` if this object represents a boolean value
+   */
+  bool get isBool => value.isBool;
+
+  /**
+   * Return `true` if this object represents an object whose type is either 'bool', 'num',
+   * 'String', or 'Null'.
+   *
+   * @return `true` if this object represents either a boolean, numeric, string or null value
+   */
+  bool get isBoolNumStringOrNull => value.isBoolNumStringOrNull;
+
+  /**
+   * Return `true` if this result represents the value 'false'.
+   *
+   * @return `true` if this result represents the value 'false'
+   */
+  bool get isFalse => value.isFalse;
+
+  /**
+   * Return `true` if this result represents the value 'null'.
+   *
+   * @return `true` if this result represents the value 'null'
+   */
+  bool get isNull => value.isNull;
+
+  /**
+   * Return `true` if this result represents the value 'true'.
+   *
+   * @return `true` if this result represents the value 'true'
+   */
+  bool get isTrue => value.isTrue;
+
+  /**
+   * Return `true` if this object represents an instance of a user-defined class.
+   *
+   * @return `true` if this object represents an instance of a user-defined class
+   */
+  bool get isUserDefinedObject => value.isUserDefinedObject;
+
+  EvaluationResultImpl lessThan(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanValid(typeProvider, node, this);
+
+  EvaluationResultImpl lessThanOrEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.lessThanOrEqualValid(typeProvider, node, this);
+
+  EvaluationResultImpl logicalAnd(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalAndValid(typeProvider, node, this);
+
+  EvaluationResultImpl logicalNot(TypeProvider typeProvider, Expression node) {
+    try {
+      return valueOf(value.logicalNot(typeProvider));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    return error(node);
   }
 
-  EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(node, this);
+  EvaluationResultImpl logicalOr(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.logicalOrValid(typeProvider, node, this);
 
-  EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(node, this);
+  EvaluationResultImpl minus(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.minusValid(typeProvider, node, this);
 
-  EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(node, this);
+  EvaluationResultImpl negated(TypeProvider typeProvider, Expression node) {
+    try {
+      return valueOf(value.negated(typeProvider));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
+    }
+  }
 
-  EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(node, this);
+  EvaluationResultImpl notEqual(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.notEqualValid(typeProvider, node, this);
+
+  EvaluationResultImpl performToString(TypeProvider typeProvider, ASTNode node) {
+    try {
+      return valueOf(value.performToString(typeProvider));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
+    }
+  }
+
+  EvaluationResultImpl remainder(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.remainderValid(typeProvider, node, this);
+
+  EvaluationResultImpl shiftLeft(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftLeftValid(typeProvider, node, this);
+
+  EvaluationResultImpl shiftRight(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.shiftRightValid(typeProvider, node, this);
+
+  EvaluationResultImpl times(TypeProvider typeProvider, BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.timesValid(typeProvider, node, this);
 
   String toString() {
     if (value == null) {
@@ -1299,188 +1569,71 @@
 
   EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl addToValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.add(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    } else if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_NUM;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) + (value as int));
-      } else if (value is double) {
-        return valueOf3((leftValue as int).toDouble() + (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf3((leftValue as double) + (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf3((leftValue as double) + (value as double));
-      }
-    } else if (leftValue is String) {
-      if (value is String) {
-        return valueOf4("${(leftValue as String)}${(value as String)}");
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyInt || !leftOperand.isAnyInt) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+  EvaluationResultImpl bitAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.bitAnd(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) & (value as int));
-      }
-      return error(node.leftOperand);
-    }
-    if (value is int) {
-      return error(node.rightOperand);
-    }
-    return union(error(node.leftOperand), error(node.rightOperand));
   }
 
   EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyInt || !leftOperand.isAnyInt) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+  EvaluationResultImpl bitOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.bitOr(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) | (value as int));
-      }
-      return error(node.leftOperand);
-    }
-    if (value is int) {
-      return error(node.rightOperand);
-    }
-    return union(error(node.leftOperand), error(node.rightOperand));
   }
 
   EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyInt || !leftOperand.isAnyInt) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+  EvaluationResultImpl bitXorValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.bitXor(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) ^ (value as int));
-      }
-      return error(node.leftOperand);
-    }
-    if (value is int) {
-      return error(node.rightOperand);
-    }
-    return union(error(node.leftOperand), error(node.rightOperand));
   }
 
   EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand) {
-    Object leftValue = leftOperand.value;
-    if (leftValue is String && value is String) {
-      return valueOf4("${(leftValue as String)}${(value as String)}");
+  EvaluationResultImpl concatenateValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.concatenate(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    return error(node);
   }
 
   EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl divideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.divide(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_NUM;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        if ((value as int) == 0) {
-          return valueOf3((leftValue as int).toDouble() / (value as int).toDouble());
-        }
-        return valueOf((leftValue as int) ~/ (value as int));
-      } else if (value is double) {
-        return valueOf3((leftValue as int).toDouble() / (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf3((leftValue as double) / (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf3((leftValue as double) / (value as double));
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) {
-    if (node is BinaryExpression) {
-      if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
-        return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
-      }
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return valueOf2(value == null);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf2((leftValue as int) == value);
-      } else if (value is double) {
-        return valueOf2(toDouble(leftValue as int) == value);
-      }
-      return RESULT_FALSE;
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf2((leftValue as double) == toDouble(value as int));
-      } else if (value is double) {
-        return valueOf2((leftValue as double) == value);
-      }
-      return RESULT_FALSE;
-    } else {
-      return valueOf2(leftValue == value);
+  EvaluationResultImpl equalEqualValid(TypeProvider typeProvider, Expression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.equalEqual(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
   }
 
@@ -1488,403 +1641,132 @@
 
   EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl greaterThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.greaterThanOrEqual(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_BOOL;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf2((leftValue as int).compareTo(value as int) >= 0);
-      } else if (value is double) {
-        return valueOf2((leftValue as int).toDouble() >= (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf2((leftValue as double) >= (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf2((leftValue as double) >= (value as double));
-      }
-    }
-    return error(node);
   }
 
-  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl greaterThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.greaterThan(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_BOOL;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf2((leftValue as int).compareTo(value as int) > 0);
-      } else if (value is double) {
-        return valueOf2((leftValue as int).toDouble() > (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf2((leftValue as double) > (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf2((leftValue as double) > (value as double));
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl integerDivideValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.integerDivide(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_INT;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        if ((value as int) == 0) {
-          return error2(node, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
-        }
-        return valueOf((leftValue as int) ~/ (value as int));
-      } else if (value is double) {
-        double result = (leftValue as int).toDouble() / (value as double);
-        return valueOf(result.toInt());
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        double result = (leftValue as double) / (value as int).toDouble();
-        return valueOf(result.toInt());
-      } else if (value is double) {
-        double result = (leftValue as double) / (value as double);
-        return valueOf(result.toInt());
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
   EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl lessThanOrEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.lessThanOrEqual(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_BOOL;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf2((leftValue as int).compareTo(value as int) <= 0);
-      } else if (value is double) {
-        return valueOf2((leftValue as int).toDouble() <= (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf2((leftValue as double) <= (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf2((leftValue as double) <= (value as double));
-      }
-    }
-    return error(node);
   }
 
-  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl lessThanValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.lessThan(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_BOOL;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf2((leftValue as int).compareTo(value as int) < 0);
-      } else if (value is double) {
-        return valueOf2((leftValue as int).toDouble() < (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf2((leftValue as double) < (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf2((leftValue as double) < (value as double));
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyBool || !leftOperand.isAnyBool) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+  EvaluationResultImpl logicalAndValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.logicalAnd(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeBool || leftOperand.isSomeBool) {
-      return RESULT_BOOL;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue is bool) {
-      if (leftValue as bool) {
-        return booleanConversion(node.rightOperand, value);
-      }
-      return RESULT_FALSE;
-    }
-    return error(node);
   }
 
   EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyBool || !leftOperand.isAnyBool) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+  EvaluationResultImpl logicalOrValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.logicalOr(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeBool || leftOperand.isSomeBool) {
-      return RESULT_BOOL;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue is bool && (leftValue as bool)) {
-      return RESULT_TRUE;
-    }
-    return booleanConversion(node.rightOperand, value);
   }
 
   EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl minusValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.minus(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    } else if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_NUM;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) - (value as int));
-      } else if (value is double) {
-        return valueOf3((leftValue as int).toDouble() - (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf3((leftValue as double) - (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf3((leftValue as double) - (value as double));
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+  EvaluationResultImpl notEqualValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.notEqual(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return valueOf2(value != null);
-    } else if (leftValue is bool) {
-      if (value is bool) {
-        return valueOf2((leftValue as bool) != (value as bool));
-      }
-      return RESULT_TRUE;
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf2((leftValue as int) != value);
-      } else if (value is double) {
-        return valueOf2(toDouble(leftValue as int) != value);
-      }
-      return RESULT_TRUE;
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf2((leftValue as double) != toDouble(value as int));
-      } else if (value is double) {
-        return valueOf2((leftValue as double) != value);
-      }
-      return RESULT_TRUE;
-    } else if (leftValue is String) {
-      if (value is String) {
-        return valueOf2((leftValue as String) != value);
-      }
-      return RESULT_TRUE;
-    }
-    return RESULT_TRUE;
   }
 
   EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl remainderValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.remainder(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    } else if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_NUM;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        if ((value as int) == 0) {
-          return valueOf3((leftValue as int).toDouble() % (value as int).toDouble());
-        }
-        return valueOf((leftValue as int).remainder(value as int));
-      } else if (value is double) {
-        return valueOf3((leftValue as int).toDouble() % (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf3((leftValue as double) % (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf3((leftValue as double) % (value as double));
-      }
-    }
-    return error(node);
   }
 
   EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyInt || !leftOperand.isAnyInt) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+  EvaluationResultImpl shiftLeftValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.shiftLeft(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return RESULT_INT;
-      }
-      return error(node.rightOperand);
-    }
-    if (value is int) {
-      return error(node.leftOperand);
-    }
-    return union(error(node.leftOperand), error(node.rightOperand));
   }
 
   EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyInt || !leftOperand.isAnyInt) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+  EvaluationResultImpl shiftRightValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.shiftRight(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) >> (value as int));
-      }
-      return error(node.rightOperand);
-    }
-    if (value is int) {
-      return error(node.leftOperand);
-    }
-    return union(error(node.leftOperand), error(node.rightOperand));
   }
 
   EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
 
-  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) {
-    if (!isAnyNum || !leftOperand.isAnyNum) {
-      return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+  EvaluationResultImpl timesValid(TypeProvider typeProvider, BinaryExpression node, ValidResult leftOperand) {
+    try {
+      return valueOf(leftOperand.value.times(typeProvider, value));
+    } on EvaluationException catch (exception) {
+      return error(node, exception.errorCode);
     }
-    if (isSomeInt || leftOperand.isSomeInt) {
-      return RESULT_INT;
-    } else if (isSomeNum || leftOperand.isSomeNum) {
-      return RESULT_NUM;
-    }
-    Object leftValue = leftOperand.value;
-    if (leftValue == null) {
-      return error(node.leftOperand);
-    } else if (value == null) {
-      return error(node.rightOperand);
-    } else if (leftValue is int) {
-      if (value is int) {
-        return valueOf((leftValue as int) * (value as int));
-      } else if (value is double) {
-        return valueOf3((leftValue as int).toDouble() * (value as double));
-      }
-    } else if (leftValue is double) {
-      if (value is int) {
-        return valueOf3((leftValue as double) * (value as int).toDouble());
-      } else if (value is double) {
-        return valueOf3((leftValue as double) * (value as double));
-      }
-    }
-    return error(node);
   }
 
-  bool get isNull => identical(this, RESULT_NULL);
-
-  /**
-   * Return the result of applying boolean conversion to the given value.
-   *
-   * @param node the node against which errors should be reported
-   * @param value the value to be converted to a boolean
-   * @return the result of applying boolean conversion to the given value
-   */
-  EvaluationResultImpl booleanConversion(ASTNode node, Object value) {
-    if (value is bool) {
-      if (value as bool) {
-        return RESULT_TRUE;
-      } else {
-        return RESULT_FALSE;
-      }
-    }
-    return error(node);
-  }
-
-  ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_CONSTANT);
-
   /**
    * Return a result object representing an error associated with the given node.
    *
@@ -1892,53 +1774,7 @@
    * @param code the error code indicating the nature of the error
    * @return a result object representing an error associated with the given node
    */
-  ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code);
-
-  /**
-   * Checks if this result has type "bool", with known or unknown value.
-   */
-  bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(this, RESULT_FALSE);
-
-  /**
-   * Checks if this result has type "int", with known or unknown value.
-   */
-  bool get isAnyInt => identical(this, RESULT_INT) || value is int;
-
-  /**
-   * Checks if this result has one of the types - "bool", "num" or "string"; or may be `null`.
-   */
-  bool get isAnyNullBoolNumString => isNull || isAnyBool || isAnyNum || value is String;
-
-  /**
-   * Checks if this result has type "num", with known or unknown value.
-   */
-  bool get isAnyNum => isSomeNum || value is num;
-
-  /**
-   * Checks if this result has type "bool", exact value of which we don't know.
-   */
-  bool get isSomeBool => identical(this, RESULT_BOOL);
-
-  /**
-   * Checks if this result has type "int", exact value of which we don't know.
-   */
-  bool get isSomeInt => identical(this, RESULT_INT);
-
-  /**
-   * Checks if this result has type "num" (or "int"), exact value of which we don't know.
-   */
-  bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_INT) || identical(this, RESULT_NUM);
-
-  double toDouble(int value) => value.toDouble();
-
-  /**
-   * Return an error result that is the union of the two given error results.
-   *
-   * @param firstError the first error to be combined
-   * @param secondError the second error to be combined
-   * @return an error result that is the union of the two given error results
-   */
-  ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new ErrorResult.con2(firstError, secondError);
+  ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code);
 
   /**
    * Return a result object representing the given value.
@@ -1946,29 +1782,2414 @@
    * @param value the value to be represented as a result object
    * @return a result object representing the given value
    */
-  ValidResult valueOf(int value) => new ValidResult(value);
+  ValidResult valueOf(DartObjectImpl value) => new ValidResult(value);
+}
+
+/**
+ * Instances of the class `BoolState` represent the state of an object representing a boolean
+ * value.
+ */
+class BoolState extends InstanceState {
+  /**
+   * The value of this instance.
+   */
+  final bool value;
 
   /**
-   * Return a result object representing the given value.
-   *
-   * @param value the value to be represented as a result object
-   * @return a result object representing the given value
+   * An instance representing the boolean value 'false'.
    */
-  ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE;
+  static BoolState FALSE_STATE = new BoolState(false);
 
   /**
-   * Return a result object representing the given value.
-   *
-   * @param value the value to be represented as a result object
-   * @return a result object representing the given value
+   * An instance representing the boolean value 'true'.
    */
-  ValidResult valueOf3(double value) => new ValidResult(value);
+  static BoolState TRUE_STATE = new BoolState(true);
 
   /**
-   * Return a result object representing the given value.
-   *
-   * @param value the value to be represented as a result object
-   * @return a result object representing the given value
+   * A state that can be used to represent a boolean whose value is not known.
    */
-  ValidResult valueOf4(String value) => new ValidResult(value);
+  static BoolState UNKNOWN_VALUE = new BoolState(null);
+
+  /**
+   * Return the boolean state representing the given boolean value.
+   *
+   * @param value the value to be represented
+   * @return the boolean state representing the given boolean value
+   */
+  static BoolState from(bool value) => value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
+
+  /**
+   * Initialize a newly created state to represent the given value.
+   *
+   * @param value the value of this instance
+   */
+  BoolState(this.value);
+
+  BoolState convertToBool() => this;
+
+  StringState convertToString() {
+    if (value == null) {
+      return StringState.UNKNOWN_VALUE;
+    }
+    return new StringState(value ? "true" : "false");
+  }
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is BoolState) {
+      bool rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return BoolState.from(identical(value, rightValue));
+    } else if (rightOperand is DynamicState) {
+      return UNKNOWN_VALUE;
+    }
+    return FALSE_STATE;
+  }
+
+  bool operator ==(Object object) => object is BoolState && identical(value, object.value);
+
+  String get typeName => "bool";
+
+  bool hasExactValue() => true;
+
+  int get hashCode => value == null ? 0 : (value ? 2 : 3);
+
+  /**
+   * Return `true` if this object represents an object whose type is 'bool'.
+   *
+   * @return `true` if this object represents a boolean value
+   */
+  bool get isBool => true;
+
+  bool get isBoolNumStringOrNull => true;
+
+  BoolState logicalAnd(InstanceState rightOperand) {
+    assertBool(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    return value ? rightOperand.convertToBool() : FALSE_STATE;
+  }
+
+  BoolState logicalNot() {
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    return value ? FALSE_STATE : TRUE_STATE;
+  }
+
+  BoolState logicalOr(InstanceState rightOperand) {
+    assertBool(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    return value ? TRUE_STATE : rightOperand.convertToBool();
+  }
+
+  String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
+}
+
+/**
+ * Instances of the class `DartObjectImpl` represent an instance of a Dart class.
+ */
+class DartObjectImpl implements DartObject {
+  /**
+   * The run-time type of this object.
+   */
+  final InterfaceType type;
+
+  /**
+   * The state of the object.
+   */
+  InstanceState _state;
+
+  /**
+   * Initialize a newly created object to have the given type and state.
+   *
+   * @param type the run-time type of this object
+   * @param state the state of the object
+   */
+  DartObjectImpl(this.type, InstanceState state) {
+    this._state = state;
+  }
+
+  /**
+   * Return the result of invoking the '+' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '+' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    InstanceState result = _state.add(rightOperand._state);
+    if (result is IntState) {
+      return new DartObjectImpl(typeProvider.intType, result);
+    } else if (result is DoubleState) {
+      return new DartObjectImpl(typeProvider.doubleType, result);
+    } else if (result is NumState) {
+      return new DartObjectImpl(typeProvider.numType, result);
+    }
+    // We should never get here.
+    throw new IllegalStateException("add returned a ${result.runtimeType.toString()}");
+  }
+
+  /**
+   * Return the result of invoking the '&' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl bitAnd(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitAnd(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '~' operator on this object.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @return the result of invoking the '~' operator on this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl bitNot(TypeProvider typeProvider) => new DartObjectImpl(typeProvider.intType, _state.bitNot());
+
+  /**
+   * Return the result of invoking the '|' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '|' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl bitOr(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitOr(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '^' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '^' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl bitXor(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.bitXor(rightOperand._state));
+
+  /**
+   * Return the result of invoking the ' ' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the ' ' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl concatenate(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.stringType, _state.concatenate(rightOperand._state));
+
+  /**
+   * Return the result of applying boolean conversion to this object.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @return the result of applying boolean conversion to this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl convertToBool(TypeProvider typeProvider) {
+    InterfaceType boolType = typeProvider.boolType;
+    if (identical(type, boolType)) {
+      return this;
+    }
+    return new DartObjectImpl(boolType, _state.convertToBool());
+  }
+
+  /**
+   * Return the result of invoking the '/' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '/' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl divide(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    InstanceState result = _state.divide(rightOperand._state);
+    if (result is IntState) {
+      return new DartObjectImpl(typeProvider.intType, result);
+    } else if (result is DoubleState) {
+      return new DartObjectImpl(typeProvider.doubleType, result);
+    } else if (result is NumState) {
+      return new DartObjectImpl(typeProvider.numType, result);
+    }
+    // We should never get here.
+    throw new IllegalStateException("divide returned a ${result.runtimeType.toString()}");
+  }
+
+  /**
+   * Return the result of invoking the '==' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '==' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl equalEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    if (type != rightOperand.type) {
+      String typeName = type.name;
+      if (!(typeName == "bool" || typeName == "double" || typeName == "int" || typeName == "num" || typeName == "String" || typeName == "Null" || type.isDynamic)) {
+        throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+      }
+    }
+    return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOperand._state));
+  }
+
+  bool operator ==(Object object) {
+    if (object is! DartObjectImpl) {
+      return false;
+    }
+    DartObjectImpl dartObject = object as DartObjectImpl;
+    return type == dartObject.type && _state == dartObject._state;
+  }
+
+  bool get boolValue {
+    if (_state is BoolState) {
+      return (_state as BoolState).value;
+    }
+    return null;
+  }
+
+  double get doubleValue {
+    if (_state is DoubleState) {
+      return (_state as DoubleState).value;
+    }
+    return null;
+  }
+
+  int get intValue {
+    if (_state is IntState) {
+      return (_state as IntState).value;
+    }
+    return null;
+  }
+
+  String get stringValue {
+    if (_state is StringState) {
+      return (_state as StringState).value;
+    }
+    return null;
+  }
+
+  Object get value => _state.value;
+
+  /**
+   * Return the result of invoking the '&gt;' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&gt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl greaterThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThan(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '&gt;=' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&gt;=' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state));
+
+  bool hasExactValue() => _state.hasExactValue();
+
+  int get hashCode => ObjectUtilities.combineHashCodes(type.hashCode, _state.hashCode);
+
+  /**
+   * Return the result of invoking the '~/' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '~/' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl integerDivide(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.integerDivide(rightOperand._state));
+
+  /**
+   * Return `true` if this object represents an object whose type is 'bool'.
+   *
+   * @return `true` if this object represents a boolean value
+   */
+  bool get isBool => _state.isBool;
+
+  /**
+   * Return `true` if this object represents an object whose type is either 'bool', 'num',
+   * 'String', or 'Null'.
+   *
+   * @return `true` if this object represents either a boolean, numeric, string or null value
+   */
+  bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
+
+  bool get isFalse => _state is BoolState && identical((_state as BoolState).value, false);
+
+  bool get isNull => _state is NullState;
+
+  bool get isTrue => _state is BoolState && identical((_state as BoolState).value, true);
+
+  /**
+   * Return `true` if this object represents an instance of a user-defined class.
+   *
+   * @return `true` if this object represents an instance of a user-defined class
+   */
+  bool get isUserDefinedObject => _state is GenericState;
+
+  /**
+   * Return the result of invoking the '&lt;' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&lt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl lessThan(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThan(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '&lt;=' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&lt;=' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl lessThanOrEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '&&' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&&' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl logicalAnd(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.logicalAnd(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '!' operator on this object.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @return the result of invoking the '!' operator on this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl logicalNot(TypeProvider typeProvider) => new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
+
+  /**
+   * Return the result of invoking the '||' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '||' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl logicalOr(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.boolType, _state.logicalOr(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '-' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '-' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    InstanceState result = _state.minus(rightOperand._state);
+    if (result is IntState) {
+      return new DartObjectImpl(typeProvider.intType, result);
+    } else if (result is DoubleState) {
+      return new DartObjectImpl(typeProvider.doubleType, result);
+    } else if (result is NumState) {
+      return new DartObjectImpl(typeProvider.numType, result);
+    }
+    // We should never get here.
+    throw new IllegalStateException("minus returned a ${result.runtimeType.toString()}");
+  }
+
+  /**
+   * Return the result of invoking the '-' operator on this object.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @return the result of invoking the '-' operator on this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl negated(TypeProvider typeProvider) {
+    InstanceState result = _state.negated();
+    if (result is IntState) {
+      return new DartObjectImpl(typeProvider.intType, result);
+    } else if (result is DoubleState) {
+      return new DartObjectImpl(typeProvider.doubleType, result);
+    } else if (result is NumState) {
+      return new DartObjectImpl(typeProvider.numType, result);
+    }
+    // We should never get here.
+    throw new IllegalStateException("negated returned a ${result.runtimeType.toString()}");
+  }
+
+  /**
+   * Return the result of invoking the '!=' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '!=' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl notEqual(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    if (type != rightOperand.type) {
+      String typeName = type.name;
+      if (typeName != "bool" && typeName != "double" && typeName != "int" && typeName != "num" && typeName != "String") {
+        return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
+      }
+    }
+    return new DartObjectImpl(typeProvider.boolType, _state.equalEqual(rightOperand._state).logicalNot());
+  }
+
+  /**
+   * Return the result of converting this object to a String.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @return the result of converting this object to a String
+   * @throws EvaluationException if the object cannot be converted to a String
+   */
+  DartObjectImpl performToString(TypeProvider typeProvider) {
+    InterfaceType stringType = typeProvider.stringType;
+    if (identical(type, stringType)) {
+      return this;
+    }
+    return new DartObjectImpl(stringType, _state.convertToString());
+  }
+
+  /**
+   * Return the result of invoking the '%' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '%' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl remainder(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    InstanceState result = _state.remainder(rightOperand._state);
+    if (result is IntState) {
+      return new DartObjectImpl(typeProvider.intType, result);
+    } else if (result is DoubleState) {
+      return new DartObjectImpl(typeProvider.doubleType, result);
+    } else if (result is NumState) {
+      return new DartObjectImpl(typeProvider.numType, result);
+    }
+    // We should never get here.
+    throw new IllegalStateException("remainder returned a ${result.runtimeType.toString()}");
+  }
+
+  /**
+   * Return the result of invoking the '&lt;&lt;' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl shiftLeft(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftLeft(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '&gt;&gt;' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl shiftRight(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.shiftRight(rightOperand._state));
+
+  /**
+   * Return the result of invoking the '*' operator on this object with the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '*' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    InstanceState result = _state.times(rightOperand._state);
+    if (result is IntState) {
+      return new DartObjectImpl(typeProvider.intType, result);
+    } else if (result is DoubleState) {
+      return new DartObjectImpl(typeProvider.doubleType, result);
+    } else if (result is NumState) {
+      return new DartObjectImpl(typeProvider.numType, result);
+    }
+    // We should never get here.
+    throw new IllegalStateException("times returned a ${result.runtimeType.toString()}");
+  }
+
+  String toString() => "${type.displayName} (${_state.toString()})";
+}
+
+/**
+ * Instances of the class `DoubleState` represent the state of an object representing a
+ * double.
+ */
+class DoubleState extends NumState {
+  /**
+   * The value of this instance.
+   */
+  final double value;
+
+  /**
+   * A state that can be used to represent a double whose value is not known.
+   */
+  static DoubleState UNKNOWN_VALUE = new DoubleState(null);
+
+  /**
+   * Initialize a newly created state to represent a double with the given value.
+   *
+   * @param value the value of this instance
+   */
+  DoubleState(this.value);
+
+  NumState add(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value + rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value + rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  StringState convertToString() {
+    if (value == null) {
+      return StringState.UNKNOWN_VALUE;
+    }
+    return new StringState(value.toString());
+  }
+
+  NumState divide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value / rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value / rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value == rightValue);
+    } else if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value == rightValue.toDouble());
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.FALSE_STATE;
+  }
+
+  bool operator ==(Object object) => object is DoubleState && (value == object.value);
+
+  String get typeName => "double";
+
+  BoolState greaterThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value > rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value > rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  BoolState greaterThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value >= rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value >= rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  bool hasExactValue() => true;
+
+  int get hashCode => value == null ? 0 : value.hashCode;
+
+  IntState integerDivide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return IntState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return IntState.UNKNOWN_VALUE;
+      }
+      double result = value / rightValue.toDouble();
+      return new IntState(result.toInt());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return IntState.UNKNOWN_VALUE;
+      }
+      double result = value / rightValue;
+      return new IntState(result.toInt());
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return IntState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  bool get isBoolNumStringOrNull => true;
+
+  BoolState lessThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value < rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value < rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  BoolState lessThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value <= rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value <= rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  NumState minus(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value - rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value - rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  NumState negated() {
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    return new DoubleState(-(value));
+  }
+
+  NumState remainder(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value % rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value % rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  NumState times(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value * rightValue.toDouble());
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new DoubleState(value * rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  String toString() => value == null ? "-unknown-" : value.toString();
+}
+
+/**
+ * Instances of the class `DynamicState` represent the state of an object representing a Dart
+ * object for which there is no type information.
+ */
+class DynamicState extends InstanceState {
+  /**
+   * The unique instance of this class.
+   */
+  static DynamicState DYNAMIC_STATE = new DynamicState();
+
+  NumState add(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return unknownNum(rightOperand);
+  }
+
+  IntState bitAnd(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  IntState bitNot() => IntState.UNKNOWN_VALUE;
+
+  IntState bitOr(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  IntState bitXor(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  StringState concatenate(InstanceState rightOperand) {
+    assertString(rightOperand);
+    return StringState.UNKNOWN_VALUE;
+  }
+
+  BoolState convertToBool() => BoolState.UNKNOWN_VALUE;
+
+  StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+  NumState divide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return unknownNum(rightOperand);
+  }
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  String get typeName => "dynamic";
+
+  BoolState greaterThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  BoolState greaterThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  IntState integerDivide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  bool get isBool => true;
+
+  bool get isBoolNumStringOrNull => true;
+
+  BoolState lessThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  BoolState lessThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  BoolState logicalAnd(InstanceState rightOperand) {
+    assertBool(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
+
+  BoolState logicalOr(InstanceState rightOperand) {
+    assertBool(rightOperand);
+    return rightOperand.convertToBool();
+  }
+
+  NumState minus(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return unknownNum(rightOperand);
+  }
+
+  NumState negated() => NumState.UNKNOWN_VALUE;
+
+  NumState remainder(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return unknownNum(rightOperand);
+  }
+
+  IntState shiftLeft(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  IntState shiftRight(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  NumState times(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return unknownNum(rightOperand);
+  }
+
+  /**
+   * Return an object representing an unknown numeric value whose type is based on the type of the
+   * right-hand operand.
+   *
+   * @param rightOperand the operand whose type will determine the type of the result
+   * @return an object representing an unknown numeric value
+   */
+  NumState unknownNum(InstanceState rightOperand) {
+    if (rightOperand is IntState) {
+      return IntState.UNKNOWN_VALUE;
+    } else if (rightOperand is DoubleState) {
+      return DoubleState.UNKNOWN_VALUE;
+    }
+    return NumState.UNKNOWN_VALUE;
+  }
+}
+
+/**
+ * Instances of the class `EvaluationException` represent a run-time exception that would be
+ * thrown during the evaluation of Dart code.
+ */
+class EvaluationException extends JavaException {
+  /**
+   * The error code associated with the exception.
+   */
+  final ErrorCode errorCode;
+
+  /**
+   * Initialize a newly created exception to have the given error code.
+   *
+   * @param errorCode the error code associated with the exception
+   */
+  EvaluationException(this.errorCode);
+}
+
+/**
+ * Instances of the class `FunctionState` represent the state of an object representing a
+ * function.
+ */
+class FunctionState extends InstanceState {
+  /**
+   * The element representing the function being modeled.
+   */
+  ExecutableElement _element;
+
+  /**
+   * Initialize a newly created state to represent the given function.
+   *
+   * @param element the element representing the function being modeled
+   */
+  FunctionState(ExecutableElement element) {
+    this._element = element;
+  }
+
+  StringState convertToString() {
+    if (_element == null) {
+      return StringState.UNKNOWN_VALUE;
+    }
+    return new StringState(_element.name);
+  }
+
+  bool operator ==(Object object) => object is FunctionState && (_element == object._element);
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    if (_element == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is FunctionState) {
+      ExecutableElement rightElement = rightOperand._element;
+      if (rightElement == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(_element == rightElement);
+    } else if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.FALSE_STATE;
+  }
+
+  String get typeName => "Function";
+
+  int get hashCode => _element == null ? 0 : _element.hashCode;
+
+  String toString() => _element == null ? "-unknown-" : _element.name;
+}
+
+/**
+ * Instances of the class `GenericState` represent the state of an object representing a Dart
+ * object for which there is no more specific state.
+ */
+class GenericState extends InstanceState {
+  /**
+   * The values of the fields of this instance.
+   */
+  Map<String, DartObjectImpl> _fieldMap = new Map<String, DartObjectImpl>();
+
+  /**
+   * A state that can be used to represent an object whose state is not known.
+   */
+  static GenericState UNKNOWN_VALUE = new GenericState(new Map<String, DartObjectImpl>());
+
+  /**
+   * Initialize a newly created state to represent a newly created object.
+   *
+   * @param fieldMap the values of the fields of this instance
+   */
+  GenericState(Map<String, DartObjectImpl> fieldMap) {
+    this._fieldMap = fieldMap;
+  }
+
+  StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+  bool operator ==(Object object) {
+    if (object is! GenericState) {
+      return false;
+    }
+    GenericState state = object as GenericState;
+    Set<String> otherFields = new Set<String>();
+    for (String fieldName in _fieldMap.keys.toSet()) {
+      if (_fieldMap[fieldName] != state._fieldMap[fieldName]) {
+        return false;
+      }
+      otherFields.remove(fieldName);
+    }
+    for (String fieldName in otherFields) {
+      if (state._fieldMap[fieldName] != _fieldMap[fieldName]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.from(this == rightOperand);
+  }
+
+  String get typeName => "user defined type";
+
+  int get hashCode {
+    int hashCode = 0;
+    for (DartObjectImpl value in _fieldMap.values) {
+      hashCode += value.hashCode;
+    }
+    return hashCode;
+  }
+}
+
+/**
+ * The class `InstanceState` defines the behavior of objects representing the state of a Dart
+ * object.
+ */
+abstract class InstanceState {
+  /**
+   * Return the result of invoking the '+' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '+' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  NumState add(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '&' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState bitAnd(InstanceState rightOperand) {
+    assertIntOrNull(this);
+    assertIntOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '~' operator on this object.
+   *
+   * @return the result of invoking the '~' operator on this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState bitNot() {
+    assertIntOrNull(this);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '|' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '|' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState bitOr(InstanceState rightOperand) {
+    assertIntOrNull(this);
+    assertIntOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '^' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '^' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState bitXor(InstanceState rightOperand) {
+    assertIntOrNull(this);
+    assertIntOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the ' ' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the ' ' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  StringState concatenate(InstanceState rightOperand) {
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of applying boolean conversion to this object.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @return the result of applying boolean conversion to this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState convertToBool() => BoolState.FALSE_STATE;
+
+  /**
+   * Return the result of converting this object to a String.
+   *
+   * @return the result of converting this object to a String
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  StringState convertToString();
+
+  /**
+   * Return the result of invoking the '/' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '/' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  NumState divide(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '==' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '==' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState equalEqual(InstanceState rightOperand);
+
+  /**
+   * Return the name of the type of this value.
+   *
+   * @return the name of the type of this value
+   */
+  String get typeName;
+
+  /**
+   * Return this object's value if it can be represented exactly, or `null` if either the
+   * value cannot be represented exactly or if the value is `null`. Clients should use
+   * [hasExactValue] to distinguish between these two cases.
+   *
+   * @return this object's value
+   */
+  Object get value => null;
+
+  /**
+   * Return the result of invoking the '&gt;' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&gt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState greaterThan(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '&gt;=' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&gt;=' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState greaterThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return `true` if this object's value can be represented exactly.
+   *
+   * @return `true` if this object's value can be represented exactly
+   */
+  bool hasExactValue() => false;
+
+  /**
+   * Return the result of invoking the '~/' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '~/' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState integerDivide(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return `true` if this object represents an object whose type is 'bool'.
+   *
+   * @return `true` if this object represents a boolean value
+   */
+  bool get isBool => false;
+
+  /**
+   * Return `true` if this object represents an object whose type is either 'bool', 'num',
+   * 'String', or 'Null'.
+   *
+   * @return `true` if this object represents either a boolean, numeric, string or null value
+   */
+  bool get isBoolNumStringOrNull => false;
+
+  /**
+   * Return the result of invoking the '&lt;' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&lt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState lessThan(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '&lt;=' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&lt;=' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState lessThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '&&' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&&' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState logicalAnd(InstanceState rightOperand) {
+    assertBool(this);
+    assertBool(rightOperand);
+    return BoolState.FALSE_STATE;
+  }
+
+  /**
+   * Return the result of invoking the '!' operator on this object.
+   *
+   * @return the result of invoking the '!' operator on this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState logicalNot() {
+    assertBool(this);
+    return BoolState.TRUE_STATE;
+  }
+
+  /**
+   * Return the result of invoking the '||' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '||' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  BoolState logicalOr(InstanceState rightOperand) {
+    assertBool(this);
+    assertBool(rightOperand);
+    return rightOperand.convertToBool();
+  }
+
+  /**
+   * Return the result of invoking the '-' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '-' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  NumState minus(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '-' operator on this object.
+   *
+   * @return the result of invoking the '-' operator on this object
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  NumState negated() {
+    assertNumOrNull(this);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '%' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '%' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  NumState remainder(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '&lt;&lt;' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState shiftLeft(InstanceState rightOperand) {
+    assertIntOrNull(this);
+    assertIntOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '&gt;&gt;' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  IntState shiftRight(InstanceState rightOperand) {
+    assertIntOrNull(this);
+    assertIntOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Return the result of invoking the '*' operator on this object with the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the '*' operator on this object with the given argument
+   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   */
+  NumState times(InstanceState rightOperand) {
+    assertNumOrNull(this);
+    assertNumOrNull(rightOperand);
+    throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+  }
+
+  /**
+   * Throw an exception if the given state does not represent a boolean value.
+   *
+   * @param state the state being tested
+   * @throws EvaluationException if the given state does not represent a boolean value
+   */
+  void assertBool(InstanceState state) {
+    if (!(state is BoolState || state is DynamicState)) {
+      throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+    }
+  }
+
+  /**
+   * Throw an exception if the given state does not represent a boolean, numeric, string or null
+   * value.
+   *
+   * @param state the state being tested
+   * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
+   *           null value
+   */
+  void assertBoolNumStringOrNull(InstanceState state) {
+    if (!(state is BoolState || state is DoubleState || state is IntState || state is NumState || state is StringState || state is NullState || state is DynamicState)) {
+      throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+    }
+  }
+
+  /**
+   * Throw an exception if the given state does not represent an integer or null value.
+   *
+   * @param state the state being tested
+   * @throws EvaluationException if the given state does not represent an integer or null value
+   */
+  void assertIntOrNull(InstanceState state) {
+    if (!(state is IntState || state is NumState || state is NullState || state is DynamicState)) {
+      throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
+    }
+  }
+
+  /**
+   * Throw an exception if the given state does not represent a boolean, numeric, string or null
+   * value.
+   *
+   * @param state the state being tested
+   * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
+   *           null value
+   */
+  void assertNumOrNull(InstanceState state) {
+    if (!(state is DoubleState || state is IntState || state is NumState || state is NullState || state is DynamicState)) {
+      throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
+    }
+  }
+
+  /**
+   * Throw an exception if the given state does not represent a String value.
+   *
+   * @param state the state being tested
+   * @throws EvaluationException if the given state does not represent a String value
+   */
+  void assertString(InstanceState state) {
+    if (!(state is StringState || state is DynamicState)) {
+      throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
+    }
+  }
+}
+
+/**
+ * Instances of the class `IntState` represent the state of an object representing an int.
+ */
+class IntState extends NumState {
+  /**
+   * The value of this instance.
+   */
+  final int value;
+
+  /**
+   * A state that can be used to represent an int whose value is not known.
+   */
+  static IntState UNKNOWN_VALUE = new IntState(null);
+
+  /**
+   * Initialize a newly created state to represent an int with the given value.
+   *
+   * @param value the value of this instance
+   */
+  IntState(this.value);
+
+  NumState add(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      if (rightOperand is DoubleState) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value + rightValue);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return new DoubleState(value.toDouble() + rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  IntState bitAnd(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value & rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  IntState bitNot() {
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    return new IntState(~value);
+  }
+
+  IntState bitOr(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value | rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  IntState bitXor(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value ^ rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  StringState convertToString() {
+    if (value == null) {
+      return StringState.UNKNOWN_VALUE;
+    }
+    return new StringState(value.toString());
+  }
+
+  NumState divide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      if (rightOperand is DoubleState) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      } else if (rightValue == 0) {
+        return new DoubleState(value.toDouble() / rightValue.toDouble());
+      }
+      return new IntState(value ~/ rightValue);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return new DoubleState(value.toDouble() / rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value == rightValue);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(rightValue == value.toDouble());
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.FALSE_STATE;
+  }
+
+  bool operator ==(Object object) => object is IntState && (value == object.value);
+
+  String get typeName => "int";
+
+  BoolState greaterThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.compareTo(rightValue) > 0);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.toDouble() > rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  BoolState greaterThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.compareTo(rightValue) >= 0);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.toDouble() >= rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  bool hasExactValue() => true;
+
+  int get hashCode => value == null ? 0 : value.hashCode;
+
+  IntState integerDivide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      } else if (rightValue == 0) {
+        throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
+      }
+      return new IntState(value ~/ rightValue);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      double result = value.toDouble() / rightValue;
+      return new IntState(result.toInt());
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  bool get isBoolNumStringOrNull => true;
+
+  BoolState lessThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.compareTo(rightValue) < 0);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.toDouble() < rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  BoolState lessThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.compareTo(rightValue) <= 0);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value.toDouble() <= rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  NumState minus(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      if (rightOperand is DoubleState) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value - rightValue);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return new DoubleState(value.toDouble() - rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  NumState negated() {
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    return new IntState(-value);
+  }
+
+  NumState remainder(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      if (rightOperand is DoubleState) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      } else if (rightValue == 0) {
+        return new DoubleState(value.toDouble() % rightValue.toDouble());
+      }
+      return new IntState(value.remainder(rightValue));
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return new DoubleState(value.toDouble() % rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  IntState shiftLeft(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      } else if (rightValue.bitLength > 31) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value << rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  IntState shiftRight(InstanceState rightOperand) {
+    assertIntOrNull(rightOperand);
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      } else if (rightValue.bitLength > 31) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value >> rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  NumState times(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (value == null) {
+      if (rightOperand is DoubleState) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new IntState(value * rightValue);
+    } else if (rightOperand is DoubleState) {
+      double rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return DoubleState.UNKNOWN_VALUE;
+      }
+      return new DoubleState(value.toDouble() * rightValue);
+    } else if (rightOperand is DynamicState || rightOperand is NumState) {
+      return UNKNOWN_VALUE;
+    }
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  String toString() => value == null ? "-unknown-" : value.toString();
+}
+
+/**
+ * The unique instance of the class `ListState` represents the state of an object representing
+ * a list.
+ */
+class ListState extends InstanceState {
+  /**
+   * The elements of the list.
+   */
+  List<DartObjectImpl> _elements;
+
+  /**
+   * Initialize a newly created state to represent a list with the given elements.
+   *
+   * @param elements the elements of the list
+   */
+  ListState(List<DartObjectImpl> elements) {
+    this._elements = elements;
+  }
+
+  StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.from(this == rightOperand);
+  }
+
+  bool operator ==(Object object) {
+    if (object is! ListState) {
+      return false;
+    }
+    List<DartObjectImpl> otherElements = (object as ListState)._elements;
+    int count = _elements.length;
+    if (otherElements.length != count) {
+      return false;
+    } else if (count == 0) {
+      return true;
+    }
+    for (int i = 0; i < count; i++) {
+      if (_elements[i] != otherElements[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  String get typeName => "List";
+
+  List<Object> get value {
+    int count = _elements.length;
+    List<Object> result = new List<Object>(count);
+    for (int i = 0; i < count; i++) {
+      DartObjectImpl element = _elements[i];
+      if (!element.hasExactValue()) {
+        return null;
+      }
+      result[i] = element.value;
+    }
+    return result;
+  }
+
+  bool hasExactValue() {
+    int count = _elements.length;
+    for (int i = 0; i < count; i++) {
+      if (!_elements[i].hasExactValue()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  int get hashCode {
+    int value = 0;
+    int count = _elements.length;
+    for (int i = 0; i < count; i++) {
+      value = (value << 3) ^ _elements[i].hashCode;
+    }
+    return value;
+  }
+}
+
+/**
+ * The unique instance of the class `ListState` represents the state of an object representing
+ * a map.
+ */
+class MapState extends InstanceState {
+  /**
+   * The entries in the map.
+   */
+  Map<DartObjectImpl, DartObjectImpl> _entries;
+
+  /**
+   * Initialize a newly created state to represent a map with the given entries.
+   *
+   * @param entries the entries in the map
+   */
+  MapState(Map<DartObjectImpl, DartObjectImpl> entries) {
+    this._entries = entries;
+  }
+
+  StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.from(this == rightOperand);
+  }
+
+  bool operator ==(Object object) {
+    if (object is! MapState) {
+      return false;
+    }
+    Map<DartObjectImpl, DartObjectImpl> otherElements = (object as MapState)._entries;
+    int count = _entries.length;
+    if (otherElements.length != count) {
+      return false;
+    } else if (count == 0) {
+      return true;
+    }
+    for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
+      DartObjectImpl key = entry.getKey();
+      DartObjectImpl value = entry.getValue();
+      DartObjectImpl otherValue = otherElements[key];
+      if (value != otherValue) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  String get typeName => "Map";
+
+  Map<Object, Object> get value {
+    Map<Object, Object> result = new Map<Object, Object>();
+    for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
+      DartObjectImpl key = entry.getKey();
+      DartObjectImpl value = entry.getValue();
+      if (!key.hasExactValue() || !value.hasExactValue()) {
+        return null;
+      }
+      result[key.value] = value.value;
+    }
+    return result;
+  }
+
+  bool hasExactValue() {
+    for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
+      if (!entry.getKey().hasExactValue() || !entry.getValue().hasExactValue()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  int get hashCode {
+    int value = 0;
+    for (DartObjectImpl key in _entries.keys.toSet()) {
+      value = (value << 3) ^ key.hashCode;
+    }
+    return value;
+  }
+}
+
+/**
+ * The unique instance of the class `NullState` represents the state of the value 'null'.
+ */
+class NullState extends InstanceState {
+  /**
+   * An instance representing the boolean value 'true'.
+   */
+  static NullState NULL_STATE = new NullState();
+
+  BoolState convertToBool() {
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  StringState convertToString() => new StringState("null");
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.from(rightOperand is NullState);
+  }
+
+  bool operator ==(Object object) => object is NullState;
+
+  String get typeName => "Null";
+
+  bool hasExactValue() => true;
+
+  int get hashCode => 0;
+
+  bool get isBoolNumStringOrNull => true;
+
+  BoolState logicalNot() {
+    throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+  }
+
+  String toString() => "null";
+}
+
+/**
+ * Instances of the class `NumState` represent the state of an object representing a number of
+ * an unknown type (a 'num').
+ */
+class NumState extends InstanceState {
+  /**
+   * A state that can be used to represent a number whose value is not known.
+   */
+  static NumState UNKNOWN_VALUE = new NumState();
+
+  NumState add(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return UNKNOWN_VALUE;
+  }
+
+  StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+  NumState divide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return UNKNOWN_VALUE;
+  }
+
+  bool operator ==(Object object) => object is NumState;
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  String get typeName => "num";
+
+  BoolState greaterThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  BoolState greaterThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  int get hashCode => 7;
+
+  IntState integerDivide(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    if (rightOperand is IntState) {
+      int rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return IntState.UNKNOWN_VALUE;
+      } else if (rightValue == 0) {
+        throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
+      }
+    } else if (rightOperand is DynamicState) {
+      return IntState.UNKNOWN_VALUE;
+    }
+    return IntState.UNKNOWN_VALUE;
+  }
+
+  bool get isBoolNumStringOrNull => true;
+
+  BoolState lessThan(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  BoolState lessThanOrEqual(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  NumState minus(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return UNKNOWN_VALUE;
+  }
+
+  NumState negated() => UNKNOWN_VALUE;
+
+  NumState remainder(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return UNKNOWN_VALUE;
+  }
+
+  NumState times(InstanceState rightOperand) {
+    assertNumOrNull(rightOperand);
+    return UNKNOWN_VALUE;
+  }
+
+  String toString() => "-unknown-";
+}
+
+/**
+ * Instances of the class `StringState` represent the state of an object representing a
+ * string.
+ */
+class StringState extends InstanceState {
+  /**
+   * The value of this instance.
+   */
+  final String value;
+
+  /**
+   * A state that can be used to represent a double whose value is not known.
+   */
+  static StringState UNKNOWN_VALUE = new StringState(null);
+
+  /**
+   * Initialize a newly created state to represent the given value.
+   *
+   * @param value the value of this instance
+   */
+  StringState(this.value);
+
+  StringState concatenate(InstanceState rightOperand) {
+    if (value == null) {
+      return UNKNOWN_VALUE;
+    }
+    if (rightOperand is StringState) {
+      String rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return UNKNOWN_VALUE;
+      }
+      return new StringState("${value}${rightValue}");
+    } else if (rightOperand is DynamicState) {
+      return UNKNOWN_VALUE;
+    }
+    return super.concatenate(rightOperand);
+  }
+
+  StringState convertToString() => this;
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is StringState) {
+      String rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value == rightValue);
+    } else if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.FALSE_STATE;
+  }
+
+  bool operator ==(Object object) => object is StringState && (value == object.value);
+
+  String get typeName => "String";
+
+  bool hasExactValue() => true;
+
+  int get hashCode => value == null ? 0 : value.hashCode;
+
+  bool get isBoolNumStringOrNull => true;
+
+  String toString() => value == null ? "-unknown-" : "'${value}'";
+}
+
+/**
+ * Instances of the class `StringState` represent the state of an object representing a
+ * symbol.
+ */
+class SymbolState extends InstanceState {
+  /**
+   * The value of this instance.
+   */
+  final String value;
+
+  /**
+   * Initialize a newly created state to represent the given value.
+   *
+   * @param value the value of this instance
+   */
+  SymbolState(this.value);
+
+  StringState convertToString() {
+    if (value == null) {
+      return StringState.UNKNOWN_VALUE;
+    }
+    return new StringState(value);
+  }
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (value == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is SymbolState) {
+      String rightValue = rightOperand.value;
+      if (rightValue == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(value == rightValue);
+    } else if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.FALSE_STATE;
+  }
+
+  bool operator ==(Object object) => object is SymbolState && (value == object.value);
+
+  String get typeName => "Symbol";
+
+  bool hasExactValue() => true;
+
+  int get hashCode => value == null ? 0 : value.hashCode;
+
+  String toString() => value == null ? "-unknown-" : "#${value}";
+}
+
+/**
+ * Instances of the class `TypeState` represent the state of an object representing a type.
+ */
+class TypeState extends InstanceState {
+  /**
+   * The element representing the type being modeled.
+   */
+  Element _element;
+
+  /**
+   * Initialize a newly created state to represent the given value.
+   *
+   * @param element the element representing the type being modeled
+   */
+  TypeState(Element element) {
+    this._element = element;
+  }
+
+  StringState convertToString() {
+    if (_element == null) {
+      return StringState.UNKNOWN_VALUE;
+    }
+    return new StringState(_element.name);
+  }
+
+  bool operator ==(Object object) => object is TypeState && (_element == object._element);
+
+  BoolState equalEqual(InstanceState rightOperand) {
+    assertBoolNumStringOrNull(rightOperand);
+    if (_element == null) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    if (rightOperand is TypeState) {
+      Element rightElement = rightOperand._element;
+      if (rightElement == null) {
+        return BoolState.UNKNOWN_VALUE;
+      }
+      return BoolState.from(_element == rightElement);
+    } else if (rightOperand is DynamicState) {
+      return BoolState.UNKNOWN_VALUE;
+    }
+    return BoolState.FALSE_STATE;
+  }
+
+  String get typeName => "Type";
+
+  int get hashCode => _element == null ? 0 : _element.hashCode;
+
+  String toString() => _element == null ? "-unknown-" : _element.name;
 }
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 147a861..92c67cd 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -9,7 +13,7 @@
 import 'utilities_collection.dart';
 import 'source.dart';
 import 'scanner.dart' show Keyword;
-import 'ast.dart' show Identifier, LibraryIdentifier;
+import 'ast.dart';
 import 'sdk.dart' show DartSdk;
 import 'html.dart' show XmlTagNode;
 import 'engine.dart' show AnalysisContext;
@@ -45,6 +49,15 @@
   List<ConstructorElement> get constructors;
 
   /**
+   * Return the field (synthetic or explicit) defined in this class that has the given name, or
+   * `null` if this class does not define a field with the given name.
+   *
+   * @param fieldName the name of the field to be returned
+   * @return the field with the given name that is defined in this class
+   */
+  FieldElement getField(String fieldName);
+
+  /**
    * Return an array containing all of the fields declared in this class.
    *
    * @return the fields declared in this class
@@ -111,6 +124,16 @@
   ConstructorElement getNamedConstructor(String name);
 
   /**
+   * Return the resolved [ClassDeclaration] node that declares this [ClassElement].
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [ClassDeclaration], not `null`.
+   */
+  ClassDeclaration get node;
+
+  /**
    * Return the element representing the setter with the given name that is declared in this class,
    * or `null` if this class does not declare a setter with the given name.
    *
@@ -134,6 +157,13 @@
   InterfaceType get supertype;
 
   /**
+   * Return an array containing all of the toolkit specific objects attached to this class.
+   *
+   * @return the toolkit objects attached to this class
+   */
+  List<ToolkitObjectElement> get toolkitObjects;
+
+  /**
    * Return the type defined by the class.
    *
    * @return the type defined by the class
@@ -331,6 +361,16 @@
   List<FunctionTypeAliasElement> get functionTypeAliases;
 
   /**
+   * Return the resolved [CompilationUnit] node that declares this element.
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [CompilationUnit], not `null`.
+   */
+  CompilationUnit get node;
+
+  /**
    * Return an array containing all of the top-level variables contained in this compilation unit.
    *
    * @return the top-level variables contained in this compilation unit
@@ -362,6 +402,17 @@
  */
 abstract class ConstructorElement implements ClassMemberElement, ExecutableElement {
   /**
+   * Return the resolved [ConstructorDeclaration] node that declares this
+   * [ConstructorElement] .
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [ConstructorDeclaration], not `null`.
+   */
+  ConstructorDeclaration get node;
+
+  /**
    * Return the constructor to which this constructor is redirecting.
    *
    * @return the constructor to which this constructor is redirecting
@@ -528,6 +579,17 @@
   int get nameOffset;
 
   /**
+   * Return the resolved [ASTNode] node that declares this [Element].
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [ASTNode], maybe `null` if [Element] is synthetic or
+   *         isn't contained in a compilation unit, such as a [LibraryElement].
+   */
+  ASTNode get node;
+
+  /**
    * Return the source that contains this element, or `null` if this element is not contained
    * in a source.
    *
@@ -536,6 +598,16 @@
   Source get source;
 
   /**
+   * Return the resolved [CompilationUnit] that declares this [Element].
+   *
+   * This method is expensive, because resolved AST might have been already evicted from cache, so
+   * parsing and resolving will be performed.
+   *
+   * @return the resolved [CompilationUnit], maybe `null` if synthetic [Element].
+   */
+  CompilationUnit get unit;
+
+  /**
    * Return `true` if this element, assuming that it is within scope, is accessible to code in
    * the given library. This is defined by the Dart Language Specification in section 3.2:
    * <blockquote> A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is declared
@@ -555,6 +627,22 @@
   bool get isDeprecated;
 
   /**
+   * Return `true` if this element is private. Private elements are visible only within the
+   * library in which they are declared.
+   *
+   * @return `true` if this element is private
+   */
+  bool get isPrivate;
+
+  /**
+   * Return `true` if this element is public. Public elements are visible within any library
+   * that imports the library in which they are declared.
+   *
+   * @return `true` if this element is public
+   */
+  bool get isPublic;
+
+  /**
    * Return `true` if this element is synthetic. A synthetic element is an element that is not
    * represented in the source code explicitly, but is implied by the source code, such as the
    * default constructor for a class that does not explicitly define any constructors.
@@ -619,57 +707,78 @@
  * @coverage dart.engine.element
  */
 class ElementKind extends Enum<ElementKind> {
-  static final ElementKind CLASS = new ElementKind('CLASS', 0, "class");
+  static final ElementKind ANGULAR_FILTER = new ElementKind('ANGULAR_FILTER', 0, "Angular filter");
 
-  static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 1, "compilation unit");
+  static final ElementKind ANGULAR_COMPONENT = new ElementKind('ANGULAR_COMPONENT', 1, "Angular component");
 
-  static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 2, "constructor");
+  static final ElementKind ANGULAR_CONTROLLER = new ElementKind('ANGULAR_CONTROLLER', 2, "Angular controller");
 
-  static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 3, "<dynamic>");
+  static final ElementKind ANGULAR_DIRECTIVE = new ElementKind('ANGULAR_DIRECTIVE', 3, "Angular directive");
 
-  static final ElementKind EMBEDDED_HTML_SCRIPT = new ElementKind('EMBEDDED_HTML_SCRIPT', 4, "embedded html script");
+  static final ElementKind ANGULAR_MODULE = new ElementKind('ANGULAR_MODULE', 4, "Angular module");
 
-  static final ElementKind ERROR = new ElementKind('ERROR', 5, "<error>");
+  static final ElementKind ANGULAR_PROPERTY = new ElementKind('ANGULAR_PROPERTY', 5, "Angular property");
 
-  static final ElementKind EXPORT = new ElementKind('EXPORT', 6, "export directive");
+  static final ElementKind ANGULAR_SELECTOR = new ElementKind('ANGULAR_SELECTOR', 6, "Angular selector");
 
-  static final ElementKind EXTERNAL_HTML_SCRIPT = new ElementKind('EXTERNAL_HTML_SCRIPT', 7, "external html script");
+  static final ElementKind CLASS = new ElementKind('CLASS', 7, "class");
 
-  static final ElementKind FIELD = new ElementKind('FIELD', 8, "field");
+  static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 8, "compilation unit");
 
-  static final ElementKind FUNCTION = new ElementKind('FUNCTION', 9, "function");
+  static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 9, "constructor");
 
-  static final ElementKind GETTER = new ElementKind('GETTER', 10, "getter");
+  static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 10, "<dynamic>");
 
-  static final ElementKind HTML = new ElementKind('HTML', 11, "html");
+  static final ElementKind EMBEDDED_HTML_SCRIPT = new ElementKind('EMBEDDED_HTML_SCRIPT', 11, "embedded html script");
 
-  static final ElementKind IMPORT = new ElementKind('IMPORT', 12, "import directive");
+  static final ElementKind ERROR = new ElementKind('ERROR', 12, "<error>");
 
-  static final ElementKind LABEL = new ElementKind('LABEL', 13, "label");
+  static final ElementKind EXPORT = new ElementKind('EXPORT', 13, "export directive");
 
-  static final ElementKind LIBRARY = new ElementKind('LIBRARY', 14, "library");
+  static final ElementKind EXTERNAL_HTML_SCRIPT = new ElementKind('EXTERNAL_HTML_SCRIPT', 14, "external html script");
 
-  static final ElementKind LOCAL_VARIABLE = new ElementKind('LOCAL_VARIABLE', 15, "local variable");
+  static final ElementKind FIELD = new ElementKind('FIELD', 15, "field");
 
-  static final ElementKind METHOD = new ElementKind('METHOD', 16, "method");
+  static final ElementKind FUNCTION = new ElementKind('FUNCTION', 16, "function");
 
-  static final ElementKind NAME = new ElementKind('NAME', 17, "<name>");
+  static final ElementKind GETTER = new ElementKind('GETTER', 17, "getter");
 
-  static final ElementKind PARAMETER = new ElementKind('PARAMETER', 18, "parameter");
+  static final ElementKind HTML = new ElementKind('HTML', 18, "html");
 
-  static final ElementKind PREFIX = new ElementKind('PREFIX', 19, "import prefix");
+  static final ElementKind IMPORT = new ElementKind('IMPORT', 19, "import directive");
 
-  static final ElementKind SETTER = new ElementKind('SETTER', 20, "setter");
+  static final ElementKind LABEL = new ElementKind('LABEL', 20, "label");
 
-  static final ElementKind TOP_LEVEL_VARIABLE = new ElementKind('TOP_LEVEL_VARIABLE', 21, "top level variable");
+  static final ElementKind LIBRARY = new ElementKind('LIBRARY', 21, "library");
 
-  static final ElementKind FUNCTION_TYPE_ALIAS = new ElementKind('FUNCTION_TYPE_ALIAS', 22, "function type alias");
+  static final ElementKind LOCAL_VARIABLE = new ElementKind('LOCAL_VARIABLE', 22, "local variable");
 
-  static final ElementKind TYPE_PARAMETER = new ElementKind('TYPE_PARAMETER', 23, "type parameter");
+  static final ElementKind METHOD = new ElementKind('METHOD', 23, "method");
 
-  static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 24, "<universe>");
+  static final ElementKind NAME = new ElementKind('NAME', 24, "<name>");
+
+  static final ElementKind PARAMETER = new ElementKind('PARAMETER', 25, "parameter");
+
+  static final ElementKind PREFIX = new ElementKind('PREFIX', 26, "import prefix");
+
+  static final ElementKind SETTER = new ElementKind('SETTER', 27, "setter");
+
+  static final ElementKind TOP_LEVEL_VARIABLE = new ElementKind('TOP_LEVEL_VARIABLE', 28, "top level variable");
+
+  static final ElementKind FUNCTION_TYPE_ALIAS = new ElementKind('FUNCTION_TYPE_ALIAS', 29, "function type alias");
+
+  static final ElementKind TYPE_PARAMETER = new ElementKind('TYPE_PARAMETER', 30, "type parameter");
+
+  static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 31, "<universe>");
 
   static final List<ElementKind> values = [
+      ANGULAR_FILTER,
+      ANGULAR_COMPONENT,
+      ANGULAR_CONTROLLER,
+      ANGULAR_DIRECTIVE,
+      ANGULAR_MODULE,
+      ANGULAR_PROPERTY,
+      ANGULAR_SELECTOR,
       CLASS,
       COMPILATION_UNIT,
       CONSTRUCTOR,
@@ -746,6 +855,20 @@
  * @coverage dart.engine.element
  */
 abstract class ElementVisitor<R> {
+  R visitAngularComponentElement(AngularComponentElement element);
+
+  R visitAngularControllerElement(AngularControllerElement element);
+
+  R visitAngularDirectiveElement(AngularDirectiveElement element);
+
+  R visitAngularFilterElement(AngularFilterElement element);
+
+  R visitAngularModuleElement(AngularModuleElement element);
+
+  R visitAngularPropertyElement(AngularPropertyElement element);
+
+  R visitAngularSelectorElement(AngularSelectorElement element);
+
   R visitClassElement(ClassElement element);
 
   R visitCompilationUnitElement(CompilationUnitElement element);
@@ -947,6 +1070,16 @@
  * @coverage dart.engine.element
  */
 abstract class FunctionElement implements ExecutableElement, LocalElement {
+  /**
+   * Return the resolved [FunctionDeclaration] node that declares this [FunctionElement]
+   * .
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [FunctionDeclaration], not `null`.
+   */
+  FunctionDeclaration get node;
 }
 
 /**
@@ -964,6 +1097,17 @@
   CompilationUnitElement get enclosingElement;
 
   /**
+   * Return the resolved [FunctionTypeAlias] node that declares this
+   * [FunctionTypeAliasElement] .
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [FunctionTypeAlias], not `null`.
+   */
+  FunctionTypeAlias get node;
+
+  /**
    * Return an array containing all of the parameters defined by this type alias.
    *
    * @return the parameters defined by this type alias
@@ -1182,6 +1326,13 @@
   ClassElement getType(String className);
 
   /**
+   * Return an array containing all directly and indirectly imported libraries.
+   *
+   * @return all directly and indirectly imported libraries
+   */
+  List<LibraryElement> get visibleLibraries;
+
+  /**
    * Answer `true` if this library is an application that can be run in the browser.
    *
    * @return `true` if this library is an application that can be run in the browser
@@ -1246,6 +1397,12 @@
  * @coverage dart.engine.element
  */
 abstract class LocalVariableElement implements LocalElement, VariableElement {
+  /**
+   * Return an array containing all of the toolkit specific objects attached to this variable.
+   *
+   * @return the toolkit objects attached to this variable
+   */
+  List<ToolkitObjectElement> get toolkitObjects;
 }
 
 /**
@@ -1256,6 +1413,16 @@
  */
 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
   /**
+   * Return the resolved [MethodDeclaration] node that declares this [MethodElement].
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [MethodDeclaration], not `null`.
+   */
+  MethodDeclaration get node;
+
+  /**
    * Return `true` if this method is abstract. Methods are abstract if they are not external
    * and have no body.
    *
@@ -1508,6 +1675,20 @@
 }
 
 /**
+ * The interface `ToolkitObjectElement` defines the behavior of elements that represent a
+ * toolkit specific object, such as Angular controller or component. These elements are not based on
+ * the Dart syntax, but on some semantic agreement, such as a special annotation.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class ToolkitObjectElement implements Element {
+  /**
+   * An empty array of toolkit object elements.
+   */
+  static final List<ToolkitObjectElement> EMPTY_ARRAY = new List<ToolkitObjectElement>(0);
+}
+
+/**
  * The interface `TopLevelVariableElement` defines the behavior of elements representing a
  * top-level variable.
  *
@@ -1583,6 +1764,17 @@
   FunctionElement get initializer;
 
   /**
+   * Return the resolved [VariableDeclaration] node that declares this [VariableElement]
+   * .
+   *
+   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
+   * resolving will be performed.
+   *
+   * @return the resolved [VariableDeclaration], not `null`.
+   */
+  VariableDeclaration get node;
+
+  /**
    * Return the declared type of this variable, or `null` if the variable did not have a
    * declared type (such as if it was declared using the keyword 'var').
    *
@@ -1608,6 +1800,235 @@
 }
 
 /**
+ * The interface `AngularControllerElement` defines the Angular component described by
+ * <code>NgComponent</code> annotation.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularComponentElement implements AngularHasSelectorElement {
+  /**
+   * Return an array containing all of the properties declared by this component.
+   */
+  List<AngularPropertyElement> get properties;
+
+  /**
+   * Returns the CSS file URI.
+   */
+  String get styleUri;
+
+  /**
+   * Return the offset of the [getStyleUri] in the [getSource].
+   *
+   * @return the offset of the style URI
+   */
+  int get styleUriOffset;
+
+  /**
+   * Returns the HTML template URI.
+   */
+  String get templateUri;
+
+  /**
+   * Return the offset of the [getTemplateUri] in the [getSource].
+   *
+   * @return the offset of the template URI
+   */
+  int get templateUriOffset;
+}
+
+/**
+ * The interface `AngularControllerElement` defines the Angular controller described by
+ * <code>NgController</code> annotation.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularControllerElement implements AngularHasSelectorElement {
+}
+
+/**
+ * The interface `AngularDirectiveElement` defines the Angular controller described by
+ * <code>NgDirective</code> annotation.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularDirectiveElement implements AngularHasSelectorElement {
+  /**
+   * Return an array containing all of the properties declared by this directive.
+   */
+  List<AngularPropertyElement> get properties;
+}
+
+/**
+ * The interface `AngularElement` defines the behavior of objects representing information
+ * about an Angular specific element.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularElement implements ToolkitObjectElement {
+}
+
+/**
+ * The interface `AngularFilterElement` defines the Angular filter described by
+ * <code>NgFilter</code> annotation.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularFilterElement implements AngularElement {
+}
+
+/**
+ * The interface `AngularElement` defines the behavior of objects representing information
+ * about an Angular element which is applied conditionally using some [AngularSelectorElement].
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularHasSelectorElement implements AngularElement {
+  /**
+   * Returns the selector specified for this element.
+   *
+   * @return the [AngularSelectorElement] specified for this element
+   */
+  AngularSelectorElement get selector;
+}
+
+/**
+ * The interface `AngularModuleElement` defines a single DI <code>Module</code>.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularModuleElement implements AngularElement {
+  /**
+   * An empty array of module elements.
+   */
+  static final List<AngularModuleElement> EMPTY_ARRAY = [];
+
+  /**
+   * Returns the child modules installed into this module using <code>install</code>.
+   *
+   * @return the installed child modules
+   */
+  List<AngularModuleElement> get childModules;
+
+  /**
+   * Returns the keys injected into this module using <code>type()</code> and <code>value()</code>
+   * invocations.
+   *
+   * @return the injected types
+   */
+  List<ClassElement> get keyTypes;
+}
+
+/**
+ * The interface `AngularPropertyElement` defines a single property in
+ * [AngularComponentElement].
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularPropertyElement implements AngularElement {
+  /**
+   * An empty array of property elements.
+   */
+  static final List<AngularPropertyElement> EMPTY_ARRAY = [];
+
+  /**
+   * Returns the field this property is mapped to.
+   *
+   * @return the field this property is mapped to.
+   */
+  FieldElement get field;
+
+  /**
+   * Return the offset of the field name of this property in the property map.
+   *
+   * @return the offset of the field name of this property
+   */
+  int get fieldNameOffset;
+
+  /**
+   * Returns the kind of this property.
+   *
+   * @return the kind of this property
+   */
+  AngularPropertyKind get propertyKind;
+}
+
+/**
+ * The enumeration `AngularPropertyKind` defines the different kinds of property bindings.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularPropertyKind extends Enum<AngularPropertyKind> {
+  /**
+   * `@` - Map the DOM attribute string. The attribute string will be taken literally or
+   * interpolated if it contains binding {{}} syntax and assigned to the expression. (cost: 0
+   * watches)
+   */
+  static final AngularPropertyKind ATTR = new AngularPropertyKind('ATTR', 0);
+
+  /**
+   * `&` - Treat the DOM attribute value as an expression. Assign a closure function into the field.
+   * This allows the component to control the invocation of the closure. This is useful for passing
+   * expressions into controllers which act like callbacks. (cost: 0 watches)
+   */
+  static final AngularPropertyKind CALLBACK = new AngularPropertyKind('CALLBACK', 1);
+
+  /**
+   * `=>` - Treat the DOM attribute value as an expression. Set up a watch, which will read the
+   * expression in the attribute and assign the value to destination expression. (cost: 1 watch)
+   */
+  static final AngularPropertyKind ONE_WAY = new AngularPropertyKind('ONE_WAY', 2);
+
+  /**
+   * `=>!` - Treat the DOM attribute value as an expression. Set up a one time watch on expression.
+   * Once the expression turns not null it will no longer update. (cost: 1 watches until not null,
+   * then 0 watches)
+   */
+  static final AngularPropertyKind ONE_WAY_ONE_TIME = new AngularPropertyKind('ONE_WAY_ONE_TIME', 3);
+
+  /**
+   * `<=>` - Treat the DOM attribute value as an expression. Set up a watch on both outside as well
+   * as component scope to keep the source and destination in sync. (cost: 2 watches)
+   */
+  static final AngularPropertyKind TWO_WAY = new AngularPropertyKind_TWO_WAY('TWO_WAY', 4);
+
+  static final List<AngularPropertyKind> values = [ATTR, CALLBACK, ONE_WAY, ONE_WAY_ONE_TIME, TWO_WAY];
+
+  /**
+   * Returns `true` if property of this kind calls field getter.
+   */
+  bool callsGetter() => false;
+
+  /**
+   * Returns `true` if property of this kind calls field setter.
+   */
+  bool callsSetter() => true;
+
+  AngularPropertyKind(String name, int ordinal) : super(name, ordinal);
+}
+
+class AngularPropertyKind_TWO_WAY extends AngularPropertyKind {
+  AngularPropertyKind_TWO_WAY(String name, int ordinal) : super(name, ordinal);
+
+  bool callsGetter() => true;
+}
+
+/**
+ * [AngularSelectorElement] is used to decide when Angular object should be applied.
+ *
+ * This class is an [Element] to support renaming component tag names, which are identifiers
+ * in selectors.
+ */
+abstract class AngularSelectorElement implements AngularElement {
+  /**
+   * Checks if the given [XmlTagNode] matches this selector.
+   *
+   * @param node the [XmlTagNode] to check
+   * @return `true` if the given [XmlTagNode] matches, or `false` otherwise
+   */
+  bool apply(XmlTagNode node);
+}
+
+/**
  * Instances of the class `GeneralizingElementVisitor` implement an element visitor that will
  * recursively visit all of the elements in an element model (like instances of the class
  * [RecursiveElementVisitor]). In addition, when an element of a specific type is visited not
@@ -1665,6 +2086,24 @@
  * @coverage dart.engine.element
  */
 class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
+  R visitAngularComponentElement(AngularComponentElement element) => visitAngularHasSelectorElement(element);
+
+  R visitAngularControllerElement(AngularControllerElement element) => visitAngularHasSelectorElement(element);
+
+  R visitAngularDirectiveElement(AngularDirectiveElement element) => visitAngularHasSelectorElement(element);
+
+  R visitAngularElement(AngularElement element) => visitToolkitObjectElement(element);
+
+  R visitAngularFilterElement(AngularFilterElement element) => visitAngularElement(element);
+
+  R visitAngularHasSelectorElement(AngularHasSelectorElement element) => visitAngularElement(element);
+
+  R visitAngularModuleElement(AngularModuleElement element) => visitAngularElement(element);
+
+  R visitAngularPropertyElement(AngularPropertyElement element) => visitAngularElement(element);
+
+  R visitAngularSelectorElement(AngularSelectorElement element) => visitAngularElement(element);
+
   R visitClassElement(ClassElement element) => visitElement(element);
 
   R visitCompilationUnitElement(CompilationUnitElement element) => visitElement(element);
@@ -1704,11 +2143,11 @@
 
   R visitLocalElement(LocalElement element) {
     if (element is LocalVariableElement) {
-      return visitVariableElement(element as LocalVariableElement);
+      return visitVariableElement(element);
     } else if (element is ParameterElement) {
-      return visitVariableElement(element as ParameterElement);
+      return visitVariableElement(element);
     } else if (element is FunctionElement) {
-      return visitExecutableElement(element as FunctionElement);
+      return visitExecutableElement(element);
     }
     return null;
   }
@@ -1727,6 +2166,8 @@
 
   R visitPropertyInducingElement(PropertyInducingElement element) => visitVariableElement(element);
 
+  R visitToolkitObjectElement(ToolkitObjectElement element) => visitElement(element);
+
   R visitTopLevelVariableElement(TopLevelVariableElement element) => visitPropertyInducingElement(element);
 
   R visitTypeParameterElement(TypeParameterElement element) => visitElement(element);
@@ -1747,6 +2188,41 @@
  * @coverage dart.engine.element
  */
 class RecursiveElementVisitor<R> implements ElementVisitor<R> {
+  R visitAngularComponentElement(AngularComponentElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitAngularControllerElement(AngularControllerElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitAngularDirectiveElement(AngularDirectiveElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitAngularFilterElement(AngularFilterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitAngularModuleElement(AngularModuleElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitAngularPropertyElement(AngularPropertyElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitAngularSelectorElement(AngularSelectorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
   R visitClassElement(ClassElement element) {
     element.visitChildren(this);
     return null;
@@ -1867,6 +2343,20 @@
  * @coverage dart.engine.element
  */
 class SimpleElementVisitor<R> implements ElementVisitor<R> {
+  R visitAngularComponentElement(AngularComponentElement element) => null;
+
+  R visitAngularControllerElement(AngularControllerElement element) => null;
+
+  R visitAngularDirectiveElement(AngularDirectiveElement element) => null;
+
+  R visitAngularFilterElement(AngularFilterElement element) => null;
+
+  R visitAngularModuleElement(AngularModuleElement element) => null;
+
+  R visitAngularPropertyElement(AngularPropertyElement element) => null;
+
+  R visitAngularSelectorElement(AngularSelectorElement element) => null;
+
   R visitClassElement(ClassElement element) => null;
 
   R visitCompilationUnitElement(CompilationUnitElement element) => null;
@@ -1984,6 +2474,11 @@
   InterfaceType supertype;
 
   /**
+   * An array containing all of the toolkit objects attached to this class.
+   */
+  List<ToolkitObjectElement> _toolkitObjects = ToolkitObjectElement.EMPTY_ARRAY;
+
+  /**
    * The type defined by the class.
    */
   InterfaceType type;
@@ -2016,6 +2511,10 @@
   }
 
   ElementImpl getChild(String identifier) {
+    //
+    // The casts in this method are safe because the set methods would have thrown a CCE if any of
+    // the elements in the arrays were not of the expected types.
+    //
     for (PropertyAccessorElement accessor in _accessors) {
       if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
         return accessor as PropertyAccessorElementImpl;
@@ -2046,13 +2545,6 @@
 
   List<ConstructorElement> get constructors => _constructors;
 
-  /**
-   * Given some name, this returns the [FieldElement] with the matching name, if there is no
-   * such field, then `null` is returned.
-   *
-   * @param name some name to lookup a field element with
-   * @return the matching field element, or `null` if no such element was found
-   */
   FieldElement getField(String name) {
     for (FieldElement fieldElement in _fields) {
       if (name == fieldElement.name) {
@@ -2096,7 +2588,11 @@
     return null;
   }
 
+  ClassDeclaration get node => getNode2(ClassDeclaration);
+
   PropertyAccessorElement getSetter(String setterName) {
+    // TODO (jwren) revisit- should we append '=' here or require clients to include it?
+    // Do we need the check for isSetter below?
     if (!setterName.endsWith("=")) {
       setterName += '=';
     }
@@ -2108,6 +2604,8 @@
     return null;
   }
 
+  List<ToolkitObjectElement> get toolkitObjects => _toolkitObjects;
+
   List<TypeParameterElement> get typeParameters => _typeParameters;
 
   ConstructorElement get unnamedConstructor {
@@ -2127,15 +2625,18 @@
     while (!classesToVisit.isEmpty) {
       ClassElement currentElement = classesToVisit.removeAt(0);
       if (visitedClasses.add(currentElement)) {
+        // check fields
         for (FieldElement field in currentElement.fields) {
           if (!field.isFinal && !field.isConst && !field.isStatic && !field.isSynthetic) {
             return true;
           }
         }
+        // check mixins
         for (InterfaceType mixinType in currentElement.mixins) {
           ClassElement mixinElement = mixinType.element;
           classesToVisit.add(mixinElement);
         }
+        // check super
         InterfaceType supertype = currentElement.supertype;
         if (supertype != null) {
           ClassElement superElement = supertype.element;
@@ -2145,6 +2646,7 @@
         }
       }
     }
+    // not found
     return false;
   }
 
@@ -2313,6 +2815,18 @@
   }
 
   /**
+   * Set the toolkit specific information objects attached to this class.
+   *
+   * @param toolkitObjects the toolkit objects attached to this class
+   */
+  void set toolkitObjects(List<ToolkitObjectElement> toolkitObjects) {
+    for (ToolkitObjectElement toolkitObject in toolkitObjects) {
+      (toolkitObject as ToolkitObjectElementImpl).enclosingElement = this;
+    }
+    this._toolkitObjects = toolkitObjects;
+  }
+
+  /**
    * Set whether this class is defined by a typedef construct to correspond to the given value.
    *
    * @param isTypedef `true` if the class is defined by a typedef construct
@@ -2348,6 +2862,7 @@
     safelyVisitChildren(_constructors, visitor);
     safelyVisitChildren(_fields, visitor);
     safelyVisitChildren(_methods, visitor);
+    safelyVisitChildren(_toolkitObjects, visitor);
     safelyVisitChildren(_typeParameters, visitor);
   }
 
@@ -2414,6 +2929,11 @@
   static List<CompilationUnitElement> EMPTY_ARRAY = new List<CompilationUnitElement>(0);
 
   /**
+   * The source that corresponds to this compilation unit.
+   */
+  Source source;
+
+  /**
    * An array containing all of the top-level accessors (getters and setters) contained in this
    * compilation unit.
    */
@@ -2425,14 +2945,9 @@
   List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the variables contained in this compilation unit.
+   * A table mapping elements to associated toolkit objects.
    */
-  List<TopLevelVariableElement> _variables = TopLevelVariableElementImpl.EMPTY_ARRAY;
-
-  /**
-   * The source that corresponds to this compilation unit.
-   */
-  Source source;
+  Map<Element, List<ToolkitObjectElement>> _toolkitObjects = {};
 
   /**
    * An array containing all of the function type aliases contained in this compilation unit.
@@ -2445,6 +2960,11 @@
   List<ClassElement> _types = ClassElementImpl.EMPTY_ARRAY;
 
   /**
+   * An array containing all of the variables contained in this compilation unit.
+   */
+  List<TopLevelVariableElement> _variables = TopLevelVariableElementImpl.EMPTY_ARRAY;
+
+  /**
    * The URI that is specified by the "part" directive in the enclosing library, or `null` if
    * this is the defining compilation unit of a library.
    */
@@ -2464,6 +2984,10 @@
   List<PropertyAccessorElement> get accessors => _accessors;
 
   ElementImpl getChild(String identifier) {
+    //
+    // The casts in this method are safe because the set methods would have thrown a CCE if any of
+    // the elements in the arrays were not of the expected types.
+    //
     for (PropertyAccessorElement accessor in _accessors) {
       if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
         return accessor as PropertyAccessorElementImpl;
@@ -2500,6 +3024,8 @@
 
   ElementKind get kind => ElementKind.COMPILATION_UNIT;
 
+  CompilationUnit get node => unit;
+
   List<TopLevelVariableElement> get topLevelVariables => _variables;
 
   ClassElement getType(String className) {
@@ -2594,6 +3120,33 @@
   }
 
   String get identifier => source.encoding;
+
+  /**
+   * Returns the associated toolkit objects.
+   *
+   * @param element the [Element] to get toolkit objects for
+   * @return the associated toolkit objects, may be empty, but not `null`
+   */
+  List<ToolkitObjectElement> getToolkitObjects(Element element) {
+    List<ToolkitObjectElement> objects = _toolkitObjects[element];
+    if (objects != null) {
+      return objects;
+    }
+    return ToolkitObjectElement.EMPTY_ARRAY;
+  }
+
+  /**
+   * Sets the toolkit objects that are associated with the given [Element].
+   *
+   * @param element the [Element] to associate toolkit objects with
+   * @param objects the toolkit objects to associate
+   */
+  void setToolkitObjects(Element element, List<ToolkitObjectElement> objects) {
+    for (ToolkitObjectElement toolkitObject in objects) {
+      (toolkitObject as ToolkitObjectElementImpl).enclosingElement = element;
+    }
+    _toolkitObjects[element] = objects;
+  }
 }
 
 /**
@@ -2699,18 +3252,23 @@
 
   ElementKind get kind => ElementKind.CONSTRUCTOR;
 
+  ConstructorDeclaration get node => getNode2(ConstructorDeclaration);
+
   bool get isConst => hasModifier(Modifier.CONST);
 
   bool get isDefaultConstructor {
+    // unnamed
     String name = this.name;
     if (name != null && name.length != 0) {
       return false;
     }
+    // no required parameters
     for (ParameterElement parameter in parameters) {
       if (identical(parameter.parameterKind, ParameterKind.REQUIRED)) {
         return false;
       }
     }
+    // OK, can be used as default constructor
     return true;
   }
 
@@ -3001,7 +3559,7 @@
     while (ancestor != null && !isInstanceOf(ancestor, elementClass)) {
       ancestor = ancestor.enclosingElement;
     }
-    return ancestor as Element;
+    return ancestor;
   }
 
   /**
@@ -3030,6 +3588,8 @@
 
   String get name => _name;
 
+  ASTNode get node => getNode2(ASTNode);
+
   Source get source {
     if (_enclosingElement == null) {
       return null;
@@ -3037,7 +3597,11 @@
     return _enclosingElement.source;
   }
 
+  CompilationUnit get unit => context.resolveCompilationUnit(source, library);
+
   int get hashCode {
+    // TODO: We might want to re-visit this optimization in the future.
+    // We cache the hash code value as this is a very frequently called method.
     if (_cachedHashCode == 0) {
       _cachedHashCode = location.hashCode;
     }
@@ -3060,6 +3624,16 @@
     return false;
   }
 
+  bool get isPrivate {
+    String name = displayName;
+    if (name == null) {
+      return true;
+    }
+    return Identifier.isPrivateName(name);
+  }
+
+  bool get isPublic => !isPrivate;
+
   bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
 
   /**
@@ -3096,6 +3670,15 @@
   }
 
   /**
+   * Set this [Element] as an enclosing for given.
+   *
+   * @param element the element to enclose, must be [ElementImpl]
+   */
+  void encloseElement(ElementImpl element) {
+    element.enclosingElement = this;
+  }
+
+  /**
    * Return an identifier that uniquely identifies this element among the children of this element's
    * parent.
    *
@@ -3104,6 +3687,22 @@
   String get identifier => name;
 
   /**
+   * Return the resolved [ASTNode] of the given type enclosing [getNameOffset].
+   */
+  ASTNode getNode2(Type clazz) {
+    CompilationUnit unit = this.unit;
+    if (unit == null) {
+      return null;
+    }
+    int offset = nameOffset;
+    ASTNode node = new NodeLocator.con1(offset).searchWithin(unit);
+    if (node == null) {
+      return null;
+    }
+    return node.getAncestor(clazz);
+  }
+
+  /**
    * Return `true` if this element has the given modifier associated with it.
    *
    * @param modifier the modifier being tested for
@@ -3320,6 +3919,7 @@
    * @return `true` if the given components are equal when the source type's are ignored
    */
   bool equalSourceComponents(String left, String right) {
+    // TODO(brianwilkerson) This method can go away when sources no longer have a URI kind.
     if (left == null) {
       return right == null;
     } else if (right == null) {
@@ -3342,6 +3942,7 @@
    * @return the hash code of the given encoded source component
    */
   int hashSourceComponent(String sourceComponent) {
+    // TODO(brianwilkerson) This method can go away when sources no longer have a URI kind.
     if (sourceComponent.length <= 1) {
       return sourceComponent.hashCode;
     }
@@ -3350,6 +3951,60 @@
 }
 
 /**
+ * The class `ElementPair` is a pair of [Element]s. [Object#equals] and
+ * [Object#hashCode] so this class can be used in hashed data structures.
+ */
+class ElementPair {
+  /**
+   * The first [Element]
+   */
+  Element _first;
+
+  /**
+   * The second [Element]
+   */
+  Element _second;
+
+  /**
+   * The sole constructor for this class, taking two [Element]s.
+   *
+   * @param first the first element
+   * @param second the second element
+   */
+  ElementPair(Element first, Element second) {
+    this._first = first;
+    this._second = second;
+  }
+
+  bool operator ==(Object object) {
+    if (identical(object, this)) {
+      return true;
+    }
+    if (object is ElementPair) {
+      ElementPair elementPair = object;
+      return (_first == elementPair._first) && (_second == elementPair._second);
+    }
+    return false;
+  }
+
+  /**
+   * Return the first element.
+   *
+   * @return the first element
+   */
+  Element get firstElt => _first;
+
+  /**
+   * Return the second element
+   *
+   * @return the second element
+   */
+  Element get secondElt => _second;
+
+  int get hashCode => ObjectUtilities.combineHashCodes(_first.hashCode, _second.hashCode);
+}
+
+/**
  * Instances of the class `EmbeddedHtmlScriptElementImpl` implement an
  * [EmbeddedHtmlScriptElement].
  *
@@ -3539,12 +4194,34 @@
 
   void appendTo(JavaStringBuilder builder) {
     builder.append("(");
+    String closing = null;
+    ParameterKind kind = ParameterKind.REQUIRED;
     int parameterCount = _parameters.length;
     for (int i = 0; i < parameterCount; i++) {
       if (i > 0) {
         builder.append(", ");
       }
-      (_parameters[i] as ParameterElementImpl).appendTo(builder);
+      ParameterElementImpl parameter = _parameters[i] as ParameterElementImpl;
+      ParameterKind parameterKind = parameter.parameterKind;
+      if (parameterKind != kind) {
+        if (closing != null) {
+          builder.append(closing);
+        }
+        if (identical(parameterKind, ParameterKind.POSITIONAL)) {
+          builder.append("[");
+          closing = "]";
+        } else if (identical(parameterKind, ParameterKind.NAMED)) {
+          builder.append("{");
+          closing = "}";
+        } else {
+          closing = null;
+        }
+      }
+      kind = parameterKind;
+      parameter.appendToWithoutDelimiters(builder);
+    }
+    if (closing != null) {
+      builder.append(closing);
     }
     builder.append(")");
     if (type != null) {
@@ -3727,6 +4404,8 @@
 
   ElementKind get kind => ElementKind.FUNCTION;
 
+  FunctionDeclaration get node => getNode2(FunctionDeclaration);
+
   SourceRange get visibleRange {
     if (_visibleRangeLength < 0) {
       return null;
@@ -3819,6 +4498,8 @@
 
   ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
 
+  FunctionTypeAlias get node => getNode2(FunctionTypeAlias);
+
   List<ParameterElement> get parameters => _parameters;
 
   List<TypeParameterElement> get typeParameters => _typeParameters;
@@ -4023,7 +4704,7 @@
    *
    * @param node the XML node from which this element is derived (not `null`)
    */
-  HtmlScriptElementImpl(XmlTagNode node) : super.con2(node.tag.lexeme, node.tag.offset);
+  HtmlScriptElementImpl(XmlTagNode node) : super.con2(node.tag, node.tagToken.offset);
 }
 
 /**
@@ -4033,11 +4714,6 @@
  */
 class ImportElementImpl extends ElementImpl implements ImportElement {
   /**
-   * The offset of this directive, may be `-1` if synthetic.
-   */
-  int _offset = -1;
-
-  /**
    * The offset of the character immediately following the last character of this node's URI, may be
    * `-1` if synthetic.
    */
@@ -4073,20 +4749,15 @@
 
   /**
    * Initialize a newly created import element.
+   *
+   * @param offset the directive offset, may be `-1` if synthetic.
    */
-  ImportElementImpl() : super.con1(null);
+  ImportElementImpl(int offset) : super.con2(null, offset);
 
   accept(ElementVisitor visitor) => visitor.visitImportElement(this);
 
   ElementKind get kind => ElementKind.IMPORT;
 
-  /**
-   * Set the offset of this directive.
-   */
-  void set offset(int offset) {
-    this._offset = offset;
-  }
-
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     safelyVisitChild(prefix, visitor);
@@ -4097,7 +4768,7 @@
     (importedLibrary as LibraryElementImpl).appendTo(builder);
   }
 
-  String get identifier => "${(importedLibrary as LibraryElementImpl).identifier}@${_offset}";
+  String get identifier => "${(importedLibrary as LibraryElementImpl).identifier}@${nameOffset}";
 }
 
 /**
@@ -4178,19 +4849,23 @@
   static bool isUpToDate(LibraryElement library, int timeStamp, Set<LibraryElement> visitedLibraries) {
     if (!visitedLibraries.contains(library)) {
       visitedLibraries.add(library);
+      // Check the defining compilation unit.
       if (timeStamp < library.definingCompilationUnit.source.modificationStamp) {
         return false;
       }
+      // Check the parted compilation units.
       for (CompilationUnitElement element in library.parts) {
         if (timeStamp < element.source.modificationStamp) {
           return false;
         }
       }
+      // Check the imported libraries.
       for (LibraryElement importedLibrary in library.importedLibraries) {
         if (!isUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
           return false;
         }
       }
+      // Check the exported libraries.
       for (LibraryElement exportedLibrary in library.exportedLibraries) {
         if (!isUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
           return false;
@@ -4331,6 +5006,12 @@
     return null;
   }
 
+  List<LibraryElement> get visibleLibraries {
+    Set<LibraryElement> visibleLibraries = new Set();
+    addVisibleLibraries(visibleLibraries, false);
+    return new List.from(visibleLibraries);
+  }
+
   int get hashCode => _definingCompilationUnit.hashCode;
 
   bool get isBrowserApplication => entryPoint != null && isOrImportsBrowserLibrary;
@@ -4406,6 +5087,32 @@
   String get identifier => _definingCompilationUnit.source.encoding;
 
   /**
+   * Recursively fills set of visible libraries for [getVisibleElementsLibraries].
+   */
+  void addVisibleLibraries(Set<LibraryElement> visibleLibraries, bool includeExports) {
+    // maybe already processed
+    if (!visibleLibraries.add(this)) {
+      return;
+    }
+    // add imported libraries
+    for (ImportElement importElement in _imports) {
+      LibraryElement importedLibrary = importElement.importedLibrary;
+      if (importedLibrary != null) {
+        (importedLibrary as LibraryElementImpl).addVisibleLibraries(visibleLibraries, true);
+      }
+    }
+    // add exported libraries
+    if (includeExports) {
+      for (ExportElement exportElement in _exports) {
+        LibraryElement exportedLibrary = exportElement.exportedLibrary;
+        if (exportedLibrary != null) {
+          (exportedLibrary as LibraryElementImpl).addVisibleLibraries(visibleLibraries, true);
+        }
+      }
+    }
+  }
+
+  /**
    * Answer `true` if the receiver directly or indirectly imports the dart:html libraries.
    *
    * @return `true` if the receiver directly or indirectly imports the dart:html libraries
@@ -4478,6 +5185,14 @@
 
   ElementKind get kind => ElementKind.LOCAL_VARIABLE;
 
+  List<ToolkitObjectElement> get toolkitObjects {
+    CompilationUnitElementImpl unit = getAncestor(CompilationUnitElementImpl);
+    if (unit == null) {
+      return ToolkitObjectElement.EMPTY_ARRAY;
+    }
+    return unit.getToolkitObjects(this);
+  }
+
   SourceRange get visibleRange {
     if (_visibleRangeLength < 0) {
       return null;
@@ -4504,6 +5219,19 @@
   }
 
   /**
+   * Set the toolkit specific information objects attached to this variable.
+   *
+   * @param toolkitObjects the toolkit objects attached to this variable
+   */
+  void set toolkitObjects(List<ToolkitObjectElement> toolkitObjects) {
+    CompilationUnitElementImpl unit = getAncestor(CompilationUnitElementImpl);
+    if (unit == null) {
+      return;
+    }
+    unit.setToolkitObjects(this, toolkitObjects);
+  }
+
+  /**
    * Set the visible range for this element to the range starting at the given offset with the given
    * length.
    *
@@ -4568,6 +5296,8 @@
     return super.name;
   }
 
+  MethodDeclaration get node => getNode2(MethodDeclaration);
+
   bool get isAbstract => hasModifier(Modifier.ABSTRACT);
 
   bool get isOperator {
@@ -4686,7 +5416,7 @@
    */
   static void add(Set<Element> elements, Element element) {
     if (element is MultiplyDefinedElementImpl) {
-      for (Element conflictingElement in (element as MultiplyDefinedElementImpl).conflictingElements) {
+      for (Element conflictingElement in element.conflictingElements) {
         elements.add(conflictingElement);
       }
     } else {
@@ -4757,10 +5487,14 @@
 
   int get nameOffset => -1;
 
+  ASTNode get node => null;
+
   Source get source => null;
 
   Type2 get type => DynamicTypeImpl.instance;
 
+  CompilationUnit get unit => null;
+
   bool isAccessibleIn(LibraryElement library) {
     for (Element element in conflictingElements) {
       if (element.isAccessibleIn(library)) {
@@ -4772,6 +5506,16 @@
 
   bool get isDeprecated => false;
 
+  bool get isPrivate {
+    String name = displayName;
+    if (name == null) {
+      return false;
+    }
+    return Identifier.isPrivateName(name);
+  }
+
+  bool get isPublic => !isPrivate;
+
   bool get isSynthetic => true;
 
   String toString() {
@@ -4959,10 +5703,19 @@
       break;
     }
     builder.append(left);
+    appendToWithoutDelimiters(builder);
+    builder.append(right);
+  }
+
+  /**
+   * Append the type and name of this parameter to the given builder.
+   *
+   * @param builder the builder to which the type and name are to be appended
+   */
+  void appendToWithoutDelimiters(JavaStringBuilder builder) {
     builder.append(type);
     builder.append(" ");
     builder.append(displayName);
-    builder.append(right);
   }
 }
 
@@ -5084,6 +5837,19 @@
     return super.name;
   }
 
+  ASTNode get node {
+    if (isSynthetic) {
+      return null;
+    }
+    if (enclosingElement is ClassElement) {
+      return getNode2(MethodDeclaration);
+    }
+    if (enclosingElement is CompilationUnitElement) {
+      return getNode2(FunctionDeclaration);
+    }
+    return null;
+  }
+
   int get hashCode => ObjectUtilities.combineHashCodes(super.hashCode, isGetter ? 1 : 2);
 
   bool get isAbstract => hasModifier(Modifier.ABSTRACT);
@@ -5215,6 +5981,22 @@
 }
 
 /**
+ * Instances of the class `ToolkitObjectElementImpl` implement a `ToolkitObjectElement`.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class ToolkitObjectElementImpl extends ElementImpl implements ToolkitObjectElement {
+  /**
+   * Initialize a newly created toolkit object element to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  ToolkitObjectElementImpl(String name, int nameOffset) : super.con2(name, nameOffset);
+}
+
+/**
  * Instances of the class `TopLevelVariableElementImpl` implement a
  * `TopLevelVariableElement`.
  *
@@ -5338,6 +6120,8 @@
 
   FunctionElement get initializer => _initializer;
 
+  VariableDeclaration get node => getNode2(VariableDeclaration);
+
   bool get isConst => hasModifier(Modifier.CONST);
 
   bool get isFinal => hasModifier(Modifier.FINAL);
@@ -5411,6 +6195,321 @@
 }
 
 /**
+ * Implementation of `AngularComponentElement`.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularComponentElementImpl extends AngularHasSelectorElementImpl implements AngularComponentElement {
+  /**
+   * The array containing all of the properties declared by this component.
+   */
+  List<AngularPropertyElement> _properties = AngularPropertyElement.EMPTY_ARRAY;
+
+  /**
+   * The the CSS file URI.
+   */
+  String styleUri;
+
+  /**
+   * The offset of the [styleUri] in the [getSource].
+   */
+  int styleUriOffset = 0;
+
+  /**
+   * The HTML template URI.
+   */
+  String templateUri;
+
+  /**
+   * The offset of the [templateUri] in the [getSource].
+   */
+  int templateUriOffset = 0;
+
+  /**
+   * Initialize a newly created Angular component to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularComponentElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  accept(ElementVisitor visitor) => visitor.visitAngularComponentElement(this);
+
+  ElementKind get kind => ElementKind.ANGULAR_COMPONENT;
+
+  List<AngularPropertyElement> get properties => _properties;
+
+  /**
+   * Set an array containing all of the properties declared by this component.
+   *
+   * @param properties the properties to set
+   */
+  void set properties(List<AngularPropertyElement> properties) {
+    for (AngularPropertyElement property in properties) {
+      encloseElement(property as AngularPropertyElementImpl);
+    }
+    this._properties = properties;
+  }
+
+  void visitChildren(ElementVisitor visitor) {
+    safelyVisitChildren(_properties, visitor);
+    super.visitChildren(visitor);
+  }
+}
+
+/**
+ * Implementation of `AngularControllerElement`.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularControllerElementImpl extends AngularHasSelectorElementImpl implements AngularControllerElement {
+  /**
+   * Initialize a newly created Angular controller to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularControllerElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  accept(ElementVisitor visitor) => visitor.visitAngularControllerElement(this);
+
+  ElementKind get kind => ElementKind.ANGULAR_CONTROLLER;
+}
+
+/**
+ * Implementation of `AngularDirectiveElement`.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularDirectiveElementImpl extends AngularHasSelectorElementImpl implements AngularDirectiveElement {
+  /**
+   * The offset of the annotation that defines this directive.
+   */
+  int _offset = 0;
+
+  /**
+   * The array containing all of the properties declared by this directive.
+   */
+  List<AngularPropertyElement> _properties = AngularPropertyElement.EMPTY_ARRAY;
+
+  /**
+   * Initialize a newly created Angular directive to have the given name.
+   *
+   * @param offset the offset of the annotation that defines this directive
+   */
+  AngularDirectiveElementImpl(int offset) : super(null, -1) {
+    this._offset = offset;
+  }
+
+  accept(ElementVisitor visitor) => visitor.visitAngularDirectiveElement(this);
+
+  String get displayName => selector.displayName;
+
+  ElementKind get kind => ElementKind.ANGULAR_DIRECTIVE;
+
+  List<AngularPropertyElement> get properties => _properties;
+
+  /**
+   * Set an array containing all of the properties declared by this directive.
+   *
+   * @param properties the properties to set
+   */
+  void set properties(List<AngularPropertyElement> properties) {
+    for (AngularPropertyElement property in properties) {
+      encloseElement(property as AngularPropertyElementImpl);
+    }
+    this._properties = properties;
+  }
+
+  void visitChildren(ElementVisitor visitor) {
+    safelyVisitChildren(_properties, visitor);
+    super.visitChildren(visitor);
+  }
+
+  String get identifier => "NgDirective@${_offset}";
+}
+
+/**
+ * Implementation of `AngularElement`.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularElementImpl extends ToolkitObjectElementImpl implements AngularElement {
+  /**
+   * Initialize a newly created Angular element to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularElementImpl(String name, int nameOffset) : super(name, nameOffset);
+}
+
+/**
+ * Implementation of `AngularFilterElement`.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularFilterElementImpl extends AngularElementImpl implements AngularFilterElement {
+  /**
+   * Initialize a newly created Angular filter to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularFilterElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  accept(ElementVisitor visitor) => visitor.visitAngularFilterElement(this);
+
+  ElementKind get kind => ElementKind.ANGULAR_FILTER;
+}
+
+/**
+ * Implementation of `AngularSelectorElement`.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularHasSelectorElementImpl extends AngularElementImpl implements AngularHasSelectorElement {
+  /**
+   * The selector of this element.
+   */
+  AngularSelectorElement _selector;
+
+  /**
+   * Initialize a newly created Angular element to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularHasSelectorElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  AngularSelectorElement get selector => _selector;
+
+  /**
+   * Set the selector of this selector-based element.
+   *
+   * @param selector the selector to set
+   */
+  void set selector(AngularSelectorElement selector) {
+    encloseElement(selector as AngularSelectorElementImpl);
+    this._selector = selector;
+  }
+
+  void visitChildren(ElementVisitor visitor) {
+    safelyVisitChild(_selector, visitor);
+    super.visitChildren(visitor);
+  }
+}
+
+/**
+ * Implementation of `AngularModuleElement`.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularModuleElementImpl extends AngularElementImpl implements AngularModuleElement {
+  /**
+   * The array containing all of the child modules.
+   */
+  List<AngularModuleElement> childModules = AngularModuleElement.EMPTY_ARRAY;
+
+  /**
+   * The array containing all of the types used as injection keys.
+   */
+  List<ClassElement> keyTypes = ClassElementImpl.EMPTY_ARRAY;
+
+  /**
+   * Initialize a newly created Angular module.
+   */
+  AngularModuleElementImpl() : super(null, -1);
+
+  accept(ElementVisitor visitor) => visitor.visitAngularModuleElement(this);
+
+  ElementKind get kind => ElementKind.ANGULAR_MODULE;
+}
+
+/**
+ * Implementation of `AngularPropertyElement`.
+ *
+ * @coverage dart.engine.element
+ */
+class AngularPropertyElementImpl extends AngularElementImpl implements AngularPropertyElement {
+  /**
+   * The [FieldElement] to which this property is bound.
+   */
+  FieldElement field;
+
+  /**
+   * The offset of the field name in the property map.
+   */
+  int fieldNameOffset = -1;
+
+  AngularPropertyKind propertyKind;
+
+  /**
+   * Initialize a newly created Angular property to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularPropertyElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  accept(ElementVisitor visitor) => visitor.visitAngularPropertyElement(this);
+
+  ElementKind get kind => ElementKind.ANGULAR_PROPERTY;
+}
+
+/**
+ * Implementation of `AngularFilterElement`.
+ *
+ * @coverage dart.engine.element
+ */
+abstract class AngularSelectorElementImpl extends AngularElementImpl implements AngularSelectorElement {
+  /**
+   * Initialize a newly created Angular selector to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  AngularSelectorElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  accept(ElementVisitor visitor) => visitor.visitAngularSelectorElement(this);
+
+  ElementKind get kind => ElementKind.ANGULAR_SELECTOR;
+}
+
+/**
+ * Implementation of [AngularSelectorElement] based on presence of attribute.
+ */
+class HasAttributeSelectorElementImpl extends AngularSelectorElementImpl {
+  HasAttributeSelectorElementImpl(String attributeName, int offset) : super(attributeName, offset);
+
+  bool apply(XmlTagNode node) {
+    String attributeName = name;
+    return node.getAttribute(attributeName) != null;
+  }
+
+  String get displayName => "[${super.displayName}]";
+}
+
+/**
+ * Implementation of [AngularSelectorElement] based on tag name.
+ */
+class IsTagSelectorElementImpl extends AngularSelectorElementImpl {
+  IsTagSelectorElementImpl(String name, int offset) : super(name, offset);
+
+  bool apply(XmlTagNode node) {
+    String tagName = name;
+    return node.tag == tagName;
+  }
+}
+
+/**
  * Instances of the class `ConstructorMember` represent a constructor element defined in a
  * parameterized type where the values of the type parameters are known.
  */
@@ -5432,6 +6531,7 @@
     }
     FunctionType baseType = baseConstructor.type;
     if (baseType == null) {
+      // TODO(brianwilkerson) We need to understand when this can happen.
       return baseConstructor;
     }
     List<Type2> argumentTypes = definingType.typeArguments;
@@ -5440,6 +6540,8 @@
     if (baseType == substitutedType) {
       return baseConstructor;
     }
+    // TODO(brianwilkerson) Consider caching the substituted type in the instance. It would use more
+    // memory but speed up some operations. We need to see how often the type is being re-computed.
     return new ConstructorMember(baseConstructor, definingType);
   }
 
@@ -5457,6 +6559,8 @@
 
   ClassElement get enclosingElement => baseElement.enclosingElement;
 
+  ConstructorDeclaration get node => baseElement.node;
+
   ConstructorElement get redirectedConstructor => from(baseElement.redirectedConstructor, definingType);
 
   bool get isConst => baseElement.isConst;
@@ -5513,12 +6617,18 @@
   ExecutableElement get baseElement => super.baseElement as ExecutableElement;
 
   List<FunctionElement> get functions {
+    //
+    // Elements within this element should have type parameters substituted, just like this element.
+    //
     throw new UnsupportedOperationException();
   }
 
   List<LabelElement> get labels => baseElement.labels;
 
   List<LocalVariableElement> get localVariables {
+    //
+    // Elements within this element should have type parameters substituted, just like this element.
+    //
     throw new UnsupportedOperationException();
   }
 
@@ -5544,6 +6654,8 @@
   bool get isStatic => baseElement.isStatic;
 
   void visitChildren(ElementVisitor visitor) {
+    // TODO(brianwilkerson) We need to finish implementing the accessors used below so that we can
+    // safely invoke them.
     super.visitChildren(visitor);
     safelyVisitChildren(baseElement.functions, visitor);
     safelyVisitChildren(labels, visitor);
@@ -5600,6 +6712,8 @@
     if (baseType == substitutedType) {
       return baseField;
     }
+    // TODO(brianwilkerson) Consider caching the substituted type in the instance. It would use more
+    // memory but speed up some operations. We need to see how often the type is being re-computed.
     return new FieldMember(baseField, definingType);
   }
 
@@ -5679,12 +6793,20 @@
 
   int get nameOffset => _baseElement.nameOffset;
 
+  ASTNode get node => _baseElement.node;
+
   Source get source => _baseElement.source;
 
+  CompilationUnit get unit => _baseElement.unit;
+
   bool isAccessibleIn(LibraryElement library) => _baseElement.isAccessibleIn(library);
 
   bool get isDeprecated => _baseElement.isDeprecated;
 
+  bool get isPrivate => _baseElement.isPrivate;
+
+  bool get isPublic => _baseElement.isPublic;
+
   bool get isSynthetic => _baseElement.isSynthetic;
 
   void visitChildren(ElementVisitor visitor) {
@@ -5733,7 +6855,7 @@
   Type2 substituteFor(Type2 type) {
     List<Type2> argumentTypes = _definingType.typeArguments;
     List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
-    return type.substitute2(argumentTypes, parameterTypes) as Type2;
+    return type.substitute2(argumentTypes, parameterTypes);
   }
 
   /**
@@ -5780,6 +6902,8 @@
     if (baseType == substitutedType) {
       return baseMethod;
     }
+    // TODO(brianwilkerson) Consider caching the substituted type in the instance. It would use more
+    // memory but speed up some operations. We need to see how often the type is being re-computed.
     return new MethodMember(baseMethod, definingType);
   }
 
@@ -5797,6 +6921,8 @@
 
   ClassElement get enclosingElement => baseElement.enclosingElement;
 
+  MethodDeclaration get node => baseElement.node;
+
   bool get isAbstract => baseElement.isAbstract;
 
   String toString() {
@@ -5844,6 +6970,8 @@
     if (baseParameter == null || definingType.typeArguments.length == 0) {
       return baseParameter;
     }
+    // Check if parameter type depends on defining type type arguments.
+    // It is possible that we did not resolve field formal parameter yet, so skip this check for it.
     bool isFieldFormal = baseParameter is FieldFormalParameterElement;
     if (!isFieldFormal) {
       Type2 baseType = baseParameter.type;
@@ -5854,6 +6982,8 @@
         return baseParameter;
       }
     }
+    // TODO(brianwilkerson) Consider caching the substituted type in the instance. It would use more
+    // memory but speed up some operations. We need to see how often the type is being re-computed.
     if (isFieldFormal) {
       return new FieldFormalParameterMember(baseParameter as FieldFormalParameterElement, definingType);
     }
@@ -5874,13 +7004,13 @@
     Element element = baseElement.getAncestor(elementClass);
     ParameterizedType definingType = this.definingType;
     if (definingType is InterfaceType) {
-      InterfaceType definingInterfaceType = definingType as InterfaceType;
+      InterfaceType definingInterfaceType = definingType;
       if (element is ConstructorElement) {
-        return ConstructorMember.from(element as ConstructorElement, definingInterfaceType) as Element;
+        return ConstructorMember.from(element, definingInterfaceType);
       } else if (element is MethodElement) {
-        return MethodMember.from(element as MethodElement, definingInterfaceType) as Element;
+        return MethodMember.from(element, definingInterfaceType);
       } else if (element is PropertyAccessorElement) {
-        return PropertyAccessorMember.from(element as PropertyAccessorElement, definingInterfaceType) as Element;
+        return PropertyAccessorMember.from(element, definingInterfaceType);
       }
     }
     return element;
@@ -5967,6 +7097,8 @@
     if (baseType == substitutedType) {
       return baseAccessor;
     }
+    // TODO(brianwilkerson) Consider caching the substituted type in the instance. It would use more
+    // memory but speed up some operations. We need to see how often the type is being re-computed.
     return new PropertyAccessorMember(baseAccessor, definingType);
   }
 
@@ -5992,7 +7124,7 @@
   PropertyInducingElement get variable {
     PropertyInducingElement variable = baseElement.variable;
     if (variable is FieldElement) {
-      return FieldMember.from(variable as FieldElement, definingType);
+      return FieldMember.from(variable, definingType);
     }
     return variable;
   }
@@ -6053,9 +7185,14 @@
   VariableElement get baseElement => super.baseElement as VariableElement;
 
   FunctionElement get initializer {
+    //
+    // Elements within this element should have type parameters substituted, just like this element.
+    //
     throw new UnsupportedOperationException();
   }
 
+  VariableDeclaration get node => baseElement.node;
+
   Type2 get type => substituteFor(baseElement.type);
 
   bool get isConst => baseElement.isConst;
@@ -6063,6 +7200,8 @@
   bool get isFinal => baseElement.isFinal;
 
   void visitChildren(ElementVisitor visitor) {
+    // TODO(brianwilkerson) We need to finish implementing the accessors used below so that we can
+    // safely invoke them.
     super.visitChildren(visitor);
     safelyVisitChild(baseElement.initializer, visitor);
   }
@@ -6101,6 +7240,8 @@
 
   BottomTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => identical(object, this);
+
   bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) => true;
 
   bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => true;
@@ -6149,10 +7290,14 @@
     return this;
   }
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => identical(object, this);
+
   bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    // T is S
     if (identical(this, type)) {
       return true;
     }
+    // else
     return withDynamic;
   }
 
@@ -6173,10 +7318,11 @@
    *
    * @param firstTypes the first map of name/type pairs being compared
    * @param secondTypes the second map of name/type pairs being compared
+   * @param visitedElementPairs a set of visited element pairs
    * @return `true` if all of the name/type pairs in the first map are equal to the
    *         corresponding name/type pairs in the second map
    */
-  static bool equals2(Map<String, Type2> firstTypes, Map<String, Type2> secondTypes) {
+  static bool equals2(Map<String, Type2> firstTypes, Map<String, Type2> secondTypes, Set<ElementPair> visitedElementPairs) {
     if (secondTypes.length != firstTypes.length) {
       return false;
     }
@@ -6185,7 +7331,7 @@
     while (firstIterator.hasNext) {
       MapEntry<String, Type2> firstEntry = firstIterator.next();
       MapEntry<String, Type2> secondEntry = secondIterator.next();
-      if (firstEntry.getKey() != secondEntry.getKey() || firstEntry.getValue() != secondEntry.getValue()) {
+      if (firstEntry.getKey() != secondEntry.getKey() || !(firstEntry.getValue() as TypeImpl).internalEquals(secondEntry.getValue(), visitedElementPairs)) {
         return false;
       }
     }
@@ -6213,17 +7359,12 @@
    */
   FunctionTypeImpl.con2(FunctionTypeAliasElement element) : super(element, element == null ? null : element.name);
 
-  bool operator ==(Object object) {
-    if (object is! FunctionTypeImpl) {
-      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);
-  }
+  bool operator ==(Object object) => internalEquals(object, new Set<ElementPair>());
 
   String get displayName {
     String name = this.name;
     if (name == null || name.length == 0) {
+      // TODO(brianwilkerson) Determine whether function types should ever have an empty name.
       List<Type2> normalParameterTypes = this.normalParameterTypes;
       List<Type2> optionalParameterTypes = this.optionalParameterTypes;
       Map<String, Type2> namedParameterTypes = this.namedParameterTypes;
@@ -6336,10 +7477,12 @@
 
   List<ParameterElement> get parameters {
     List<ParameterElement> baseParameters = this.baseParameters;
+    // no parameters, quick return
     int parameterCount = baseParameters.length;
     if (parameterCount == 0) {
       return baseParameters;
     }
+    // create specialized parameters
     List<ParameterElement> specializedParameters = new List<ParameterElement>(parameterCount);
     for (int i = 0; i < parameterCount; i++) {
       specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
@@ -6350,6 +7493,8 @@
   Type2 get returnType {
     Type2 baseReturnType = this.baseReturnType;
     if (baseReturnType == null) {
+      // TODO(brianwilkerson) This is a patch. The return type should never be null and we need to
+      // understand why it is and fix it.
       return DynamicTypeImpl.instance;
     }
     return baseReturnType.substitute2(typeArguments, TypeParameterTypeImpl.getTypes(typeParameters));
@@ -6358,7 +7503,7 @@
   List<TypeParameterElement> get typeParameters {
     Element element = this.element;
     if (element is FunctionTypeAliasElement) {
-      return (element as FunctionTypeAliasElement).typeParameters;
+      return element.typeParameters;
     }
     ClassElement definingClass = element.getAncestor(ClassElement);
     if (definingClass != null) {
@@ -6368,14 +7513,29 @@
   }
 
   int get hashCode {
-    Element element = this.element;
     if (element == null) {
       return 0;
     }
-    return element.hashCode;
+    // Reference the arrays of parameters
+    List<Type2> normalParameterTypes = this.normalParameterTypes;
+    List<Type2> optionalParameterTypes = this.optionalParameterTypes;
+    Iterable<Type2> namedParameterTypes = this.namedParameterTypes.values;
+    // Generate the hashCode
+    int hashCode = returnType.hashCode;
+    for (int i = 0; i < normalParameterTypes.length; i++) {
+      hashCode = (hashCode << 1) + normalParameterTypes[i].hashCode;
+    }
+    for (int i = 0; i < optionalParameterTypes.length; i++) {
+      hashCode = (hashCode << 1) + optionalParameterTypes[i].hashCode;
+    }
+    for (Type2 type in namedParameterTypes) {
+      hashCode = (hashCode << 1) + type.hashCode;
+    }
+    return hashCode;
   }
 
   bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    // trivial base cases
     if (type == null) {
       return false;
     } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunction || type.isObject) {
@@ -6391,10 +7551,14 @@
     List<Type2> tOpTypes = t.optionalParameterTypes;
     List<Type2> sTypes = s.normalParameterTypes;
     List<Type2> sOpTypes = s.optionalParameterTypes;
+    // If one function has positional and the other has named parameters, return false.
     if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
       return false;
     }
+    // named parameters case
     if (t.namedParameterTypes.length > 0) {
+      // check that the number of required parameters are equal, and check that every t_i is
+      // more specific than every s_i
       if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
         return false;
       } else if (t.normalParameterTypes.length > 0) {
@@ -6406,9 +7570,12 @@
       }
       Map<String, Type2> namedTypesT = t.namedParameterTypes;
       Map<String, Type2> namedTypesS = s.namedParameterTypes;
+      // if k >= m is false, return false: the passed function type has more named parameter types than this
       if (namedTypesT.length < namedTypesS.length) {
         return false;
       }
+      // Loop through each element in S verifying that T has a matching parameter name and that the
+      // corresponding type is more specific then the type in S.
       JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
       while (iteratorS.hasNext) {
         MapEntry<String, Type2> entryS = iteratorS.next();
@@ -6423,18 +7590,25 @@
     } else if (s.namedParameterTypes.length > 0) {
       return false;
     } else {
+      // positional parameter case
       int tArgLength = tTypes.length + tOpTypes.length;
       int sArgLength = sTypes.length + sOpTypes.length;
+      // Check that the total number of parameters in t is greater than or equal to the number of
+      // parameters in s and that the number of required parameters in s is greater than or equal to
+      // the number of required parameters in t.
       if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
         return false;
       }
       if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        // No positional arguments, don't copy contents to new array
         for (int i = 0; i < sTypes.length; i++) {
           if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynamic, visitedTypePairs)) {
             return false;
           }
         }
       } else {
+        // Else, we do have positional parameters, copy required and positional parameter types into
+        // arrays to do the compare (for loop below).
         List<Type2> tAllTypes = new List<Type2>(sArgLength);
         for (int i = 0; i < tTypes.length; i++) {
           tAllTypes[i] = tTypes[i];
@@ -6473,7 +7647,7 @@
       return this;
     }
     Element element = this.element;
-    FunctionTypeImpl newType = (element is ExecutableElement) ? new FunctionTypeImpl.con1(element as ExecutableElement) : new FunctionTypeImpl.con2(element as FunctionTypeAliasElement);
+    FunctionTypeImpl newType = (element is ExecutableElement) ? new FunctionTypeImpl.con1(element) : new FunctionTypeImpl.con2(element as FunctionTypeAliasElement);
     newType.typeArguments = TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
     return newType;
   }
@@ -6546,13 +7720,32 @@
   List<ParameterElement> get baseParameters {
     Element element = this.element;
     if (element is ExecutableElement) {
-      return (element as ExecutableElement).parameters;
+      return element.parameters;
     } else {
       return (element as FunctionTypeAliasElement).parameters;
     }
   }
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) {
+    if (object is! FunctionTypeImpl) {
+      return false;
+    }
+    FunctionTypeImpl otherType = object as FunctionTypeImpl;
+    // If the visitedTypePairs already has the pair (this, type), use the elements to determine equality
+    ElementPair elementPair = new ElementPair(element, otherType.element);
+    if (!visitedElementPairs.add(elementPair)) {
+      return elementPair.firstElt == elementPair.secondElt;
+    }
+    // Compute the result
+    bool result = TypeImpl.equalArrays(normalParameterTypes, otherType.normalParameterTypes, visitedElementPairs) && TypeImpl.equalArrays(optionalParameterTypes, otherType.optionalParameterTypes, visitedElementPairs) && equals2(namedParameterTypes, otherType.namedParameterTypes, visitedElementPairs) && (returnType as TypeImpl).internalEquals(otherType.returnType, visitedElementPairs);
+    // Remove the pair from our visited pairs list
+    visitedElementPairs.remove(elementPair);
+    // Return the result
+    return result;
+  }
+
   bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) {
+    // trivial base cases
     if (type == null) {
       return false;
     } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunction || type.isObject) {
@@ -6568,10 +7761,14 @@
     List<Type2> tOpTypes = t.optionalParameterTypes;
     List<Type2> sTypes = s.normalParameterTypes;
     List<Type2> sOpTypes = s.optionalParameterTypes;
+    // If one function has positional and the other has named parameters, return false.
     if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
       return false;
     }
+    // named parameters case
     if (t.namedParameterTypes.length > 0) {
+      // check that the number of required parameters are equal, and check that every t_i is
+      // assignable to every s_i
       if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
         return false;
       } else if (t.normalParameterTypes.length > 0) {
@@ -6583,9 +7780,12 @@
       }
       Map<String, Type2> namedTypesT = t.namedParameterTypes;
       Map<String, Type2> namedTypesS = s.namedParameterTypes;
+      // if k >= m is false, return false: the passed function type has more named parameter types than this
       if (namedTypesT.length < namedTypesS.length) {
         return false;
       }
+      // Loop through each element in S verifying that T has a matching parameter name and that the
+      // corresponding type is assignable to the type in S.
       JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
       while (iteratorS.hasNext) {
         MapEntry<String, Type2> entryS = iteratorS.next();
@@ -6600,18 +7800,25 @@
     } else if (s.namedParameterTypes.length > 0) {
       return false;
     } else {
+      // positional parameter case
       int tArgLength = tTypes.length + tOpTypes.length;
       int sArgLength = sTypes.length + sOpTypes.length;
+      // Check that the total number of parameters in t is greater than or equal to the number of
+      // parameters in s and that the number of required parameters in s is greater than or equal to
+      // the number of required parameters in t.
       if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
         return false;
       }
       if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        // No positional arguments, don't copy contents to new array
         for (int i = 0; i < sTypes.length; i++) {
           if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePairs)) {
             return false;
           }
         }
       } else {
+        // Else, we do have positional parameters, copy required and positional parameter types into
+        // arrays to do the compare (for loop below).
         List<Type2> tAllTypes = new List<Type2>(sArgLength);
         for (int i = 0; i < tTypes.length; i++) {
           tAllTypes[i] = tTypes[i];
@@ -6646,7 +7853,7 @@
   Type2 get baseReturnType {
     Element element = this.element;
     if (element is ExecutableElement) {
-      return (element as ExecutableElement).returnType;
+      return element.returnType;
     } else {
       return (element as FunctionTypeAliasElement).returnType;
     }
@@ -6700,6 +7907,7 @@
    */
   static int computeLongestInheritancePathToObject2(InterfaceType type, int depth, Set<ClassElement> visitedClasses) {
     ClassElement classElement = type.element;
+    // Object case
     if (classElement.supertype == null || visitedClasses.contains(classElement)) {
       return depth;
     }
@@ -6709,6 +7917,8 @@
       List<InterfaceType> superinterfaces = classElement.interfaces;
       int pathLength;
       if (superinterfaces.length > 0) {
+        // loop through each of the superinterfaces recursively calling this method and keeping track
+        // of the longest path to return
         for (InterfaceType superinterface in superinterfaces) {
           pathLength = computeLongestInheritancePathToObject2(superinterface, depth + 1, visitedClasses);
           if (pathLength > longestPath) {
@@ -6716,6 +7926,8 @@
           }
         }
       }
+      // finally, perform this same check on the super type
+      // TODO(brianwilkerson) Does this also need to add in the number of mixin classes?
       InterfaceType supertype = classElement.supertype;
       pathLength = computeLongestInheritancePathToObject2(supertype, depth + 1, visitedClasses);
       if (pathLength > longestPath) {
@@ -6740,7 +7952,7 @@
   static Set<InterfaceType> computeSuperinterfaceSet2(InterfaceType type, Set<InterfaceType> set) {
     Element element = type.element;
     if (element != null && element is ClassElement) {
-      ClassElement classElement = element as ClassElement;
+      ClassElement classElement = element;
       List<InterfaceType> superinterfaces = classElement.interfaces;
       for (InterfaceType superinterface in superinterfaces) {
         if (set.add(superinterface)) {
@@ -6805,6 +8017,10 @@
     }
     List<Type2> lubArguments = new List<Type2>(argumentCount);
     for (int i = 0; i < argumentCount; i++) {
+      //
+      // Ideally we would take the least upper bound of the two argument types, but this can cause
+      // an infinite recursion (such as when finding the least upper bound of String and num).
+      //
       if (firstArguments[i] == secondArguments[i]) {
         lubArguments[i] = firstArguments[i];
       }
@@ -6837,13 +8053,7 @@
    */
   InterfaceTypeImpl.con2(String name) : super(null, name);
 
-  bool operator ==(Object object) {
-    if (object is! InterfaceTypeImpl) {
-      return false;
-    }
-    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
-    return (element == otherType.element) && JavaArrays.equals(typeArguments, otherType.typeArguments);
-  }
+  bool operator ==(Object object) => internalEquals(object, new Set<ElementPair>());
 
   List<PropertyAccessorElement> get accessors {
     List<PropertyAccessorElement> accessors = element.accessors;
@@ -6864,6 +8074,7 @@
         break;
       }
     }
+    // If there is at least one non-dynamic type, then list them out
     if (!allDynamic) {
       JavaStringBuilder builder = new JavaStringBuilder();
       builder.append(name);
@@ -6902,23 +8113,31 @@
   }
 
   Type2 getLeastUpperBound(Type2 type) {
+    // quick check for self
     if (identical(type, this)) {
       return this;
     }
+    // dynamic
     Type2 dynamicType = DynamicTypeImpl.instance;
     if (identical(this, dynamicType) || identical(type, dynamicType)) {
       return dynamicType;
     }
+    // TODO (jwren) opportunity here for a better, faster algorithm if this turns out to be a bottle-neck
     if (type is! InterfaceType) {
       return null;
     }
+    // new names to match up with the spec
     InterfaceType i = this;
     InterfaceType j = type as InterfaceType;
+    // compute set of supertypes
     Set<InterfaceType> si = computeSuperinterfaceSet(i);
     Set<InterfaceType> sj = computeSuperinterfaceSet(j);
+    // union si with i and sj with j
     si.add(i);
     sj.add(j);
+    // compute intersection, reference as set 's'
     List<InterfaceType> s = intersection(si, sj);
+    // for each element in Set s, compute the largest inheritance path to Object
     List<int> depths = new List<int>.filled(s.length, 0);
     int maxDepth = 0;
     for (int n = 0; n < s.length; n++) {
@@ -6927,6 +8146,8 @@
         maxDepth = depths[n];
       }
     }
+    // ensure that the currently computed maxDepth is unique,
+    // otherwise, decrement and test for uniqueness again
     for (; maxDepth >= 0; maxDepth--) {
       int indexOfLeastUpperBound = -1;
       int numberOfTypesAtMaxDepth = 0;
@@ -6940,6 +8161,9 @@
         return s[indexOfLeastUpperBound];
       }
     }
+    // illegal state, log and return null- Object at maxDepth == 0 should always return itself as
+    // the least upper bound.
+    // TODO (jwren) log the error state
     return null;
   }
 
@@ -7004,42 +8228,62 @@
     InterfaceType j = type;
     ClassElement jElement = j.element;
     InterfaceType supertype = jElement.supertype;
+    //
+    // If J has no direct supertype then it is Object, and Object has no direct supertypes.
+    //
     if (supertype == null) {
       return false;
     }
+    //
+    // I is listed in the extends clause of J.
+    //
     List<Type2> jArgs = j.typeArguments;
     List<Type2> jVars = jElement.type.typeArguments;
     supertype = supertype.substitute2(jArgs, jVars);
     if (supertype == i) {
       return true;
     }
+    //
+    // I is listed in the implements clause of J.
+    //
     for (InterfaceType interfaceType in jElement.interfaces) {
       interfaceType = interfaceType.substitute2(jArgs, jVars);
       if (interfaceType == i) {
         return true;
       }
     }
+    //
+    // I is listed in the with clause of J.
+    //
     for (InterfaceType mixinType in jElement.mixins) {
       mixinType = mixinType.substitute2(jArgs, jVars);
       if (mixinType == i) {
         return true;
       }
     }
+    //
+    // J is a mixin application of the mixin of I.
+    //
+    // TODO(brianwilkerson) Determine whether this needs to be implemented or whether it is covered
+    // by the case above.
     return false;
   }
 
   bool get isObject => element.supertype == null;
 
   ConstructorElement lookUpConstructor(String constructorName, LibraryElement library) {
+    // prepare base ConstructorElement
     ConstructorElement constructorElement;
     if (constructorName == null) {
       constructorElement = element.unnamedConstructor;
     } else {
       constructorElement = element.getNamedConstructor(constructorName);
     }
+    // not found or not accessible
     if (constructorElement == null || !constructorElement.isAccessibleIn(library)) {
       return null;
     }
+    // return member
     return ConstructorMember.from(constructorElement, this);
   }
 
@@ -7184,7 +8428,20 @@
     }
   }
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) {
+    if (object is! InterfaceTypeImpl) {
+      return false;
+    }
+    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
+    return (element == otherType.element) && TypeImpl.equalArrays(typeArguments, otherType.typeArguments, visitedElementPairs);
+  }
+
   bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    //
+    // S is dynamic.
+    // The test to determine whether S is dynamic is done here because dynamic is not an instance of
+    // InterfaceType.
+    //
     if (identical(type, DynamicTypeImpl.instance)) {
       return true;
     } else if (type is! InterfaceType) {
@@ -7194,6 +8451,9 @@
   }
 
   bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) {
+    //
+    // T is a subtype of S, written T <: S, iff [bottom/dynamic]T << S
+    //
     if (identical(type, DynamicTypeImpl.instance)) {
       return true;
     } else if (type is TypeParameterType) {
@@ -7214,12 +8474,26 @@
   }
 
   bool isMoreSpecificThan2(InterfaceType s, Set<ClassElement> visitedClasses, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    //
+    // A type T is more specific than a type S, written T << S,  if one of the following conditions
+    // is met:
+    //
+    // Reflexivity: T is S.
+    //
     if (this == s) {
       return true;
     }
+    //
+    // T is bottom. (This case is handled by the class BottomTypeImpl.)
+    //
+    // Direct supertype: S is a direct supertype of T.
+    //
     if (s.isDirectSupertypeOf(this)) {
       return true;
     }
+    //
+    // Covariance: T is of the form I<T1, ..., Tn> and S is of the form I<S1, ..., Sn> and Ti << Si, 1 <= i <= n.
+    //
     ClassElement tElement = this.element;
     ClassElement sElement = s.element;
     if (tElement == sElement) {
@@ -7235,11 +8509,17 @@
       }
       return true;
     }
+    //
+    // Transitivity: T << U and U << S.
+    //
+    // First check for infinite loops
     ClassElement element = this.element;
     if (element == null || visitedClasses.contains(element)) {
       return false;
     }
     visitedClasses.add(element);
+    // Iterate over all of the types U that are more specific than T because they are direct
+    // supertypes of T and return true if any of them are more specific than S.
     InterfaceType supertype = superclass;
     if (supertype != null && (supertype as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic, visitedTypePairs)) {
       return true;
@@ -7268,12 +8548,18 @@
     if (typeT == typeS) {
       return true;
     } else if (elementT == typeS.element) {
+      // For each of the type arguments return true if all type args from T is a subtype of all
+      // types from S.
       List<Type2> typeTArgs = typeT.typeArguments;
       List<Type2> typeSArgs = typeS.typeArguments;
       if (typeTArgs.length != typeSArgs.length) {
+        // This case covers the case where two objects are being compared that have a different
+        // number of parameterized types.
         return false;
       }
       for (int i = 0; i < typeTArgs.length; i++) {
+        // Recursively call isSubtypeOf the type arguments and return false if the T argument is not
+        // a subtype of the S argument.
         if (!(typeTArgs[i] as TypeImpl).isSubtypeOf3(typeSArgs[i], visitedTypePairs)) {
           return false;
         }
@@ -7283,6 +8569,7 @@
       return true;
     }
     InterfaceType supertype = superclass;
+    // The type is Object, return false.
     if (supertype != null && (supertype as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses, visitedTypePairs)) {
       return true;
     }
@@ -7309,6 +8596,18 @@
  * @coverage dart.engine.type
  */
 abstract class TypeImpl implements Type2 {
+  static bool equalArrays(List<Type2> typeArgs1, List<Type2> typeArgs2, Set<ElementPair> visitedElementPairs) {
+    if (typeArgs1.length != typeArgs2.length) {
+      return false;
+    }
+    for (int i = 0; i < typeArgs1.length; i++) {
+      if (!(typeArgs1[i] as TypeImpl).internalEquals(typeArgs2[i], visitedElementPairs)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   /**
    * Return an array containing the results of using the given argument types and parameter types to
    * perform a substitution on all of the given types.
@@ -7400,6 +8699,7 @@
    * @return `true` if this type is more specific than the given type
    */
   bool isMoreSpecificThan3(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    // If the visitedTypePairs already has the pair (this, type), return false
     TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type);
     if (!visitedTypePairs.add(typePair)) {
       return false;
@@ -7425,6 +8725,7 @@
    * @return `true` if this type is a subtype of the given type
    */
   bool isSubtypeOf3(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) {
+    // If the visitedTypePairs already has the pair (this, type), return false
     TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type);
     if (!visitedTypePairs.add(typePair)) {
       return false;
@@ -7457,6 +8758,8 @@
     }
   }
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs);
+
   bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs);
 
   bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs);
@@ -7477,7 +8780,7 @@
       return true;
     }
     if (object is TypeImpl_TypePair) {
-      TypeImpl_TypePair typePair = object as TypeImpl_TypePair;
+      TypeImpl_TypePair typePair = object;
       return _firstType == typePair._firstType && _secondType != null && _secondType == typePair._secondType;
     }
     return false;
@@ -7536,7 +8839,7 @@
    */
   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.element);
 
   TypeParameterElement get element => super.element as TypeParameterElement;
 
@@ -7552,13 +8855,25 @@
     return this;
   }
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => this == object;
+
   bool internalIsMoreSpecificThan(Type2 s, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    //
+    // A type T is more specific than a type S, written T << S,  if one of the following conditions
+    // is met:
+    //
+    // Reflexivity: T is S.
+    //
     if (this == s) {
       return true;
     }
+    // S is bottom.
+    //
     if (s.isBottom) {
       return true;
     }
+    // S is dynamic.
+    //
     if (s.isDynamic) {
       return true;
     }
@@ -7568,24 +8883,35 @@
   bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => isMoreSpecificThan3(type, true, new Set<TypeImpl_TypePair>());
 
   bool isMoreSpecificThan4(Type2 s, Set<Type2> visitedTypes, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+    // T is a type parameter and S is the upper bound of T.
+    //
     Type2 bound = element.bound;
     if (s == bound) {
       return true;
     }
+    // T is a type parameter and S is Object.
+    //
     if (s.isObject) {
       return true;
     }
+    // We need upper bound to continue.
     if (bound == null) {
       return false;
     }
+    //
+    // Transitivity: T << U and U << S.
+    //
     if (bound is TypeParameterTypeImpl) {
-      TypeParameterTypeImpl boundTypeParameter = bound as TypeParameterTypeImpl;
+      TypeParameterTypeImpl boundTypeParameter = bound;
+      // First check for infinite loops
       if (visitedTypes.contains(bound)) {
         return false;
       }
       visitedTypes.add(bound);
+      // Then check upper bound.
       return boundTypeParameter.isMoreSpecificThan4(s, visitedTypes, withDynamic, visitedTypePairs);
     }
+    // Check interface type.
     return (bound as TypeImpl).isMoreSpecificThan3(s, withDynamic, visitedTypePairs);
   }
 }
@@ -7621,6 +8947,8 @@
 
   VoidTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 
+  bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => identical(object, this);
+
   bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) => isSubtypeOf(type);
 
   bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => identical(type, this) || identical(type, DynamicTypeImpl.instance);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 8d7eed5..1e1c3b4 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -90,6 +94,9 @@
    * @return the analysis context that was created
    */
   AnalysisContext createAnalysisContext() {
+    //
+    // If instrumentation is ignoring data, return an uninstrumented analysis context.
+    //
     if (Instrumentation.isNullLogger) {
       return new DelegatingAnalysisContextImpl();
     }
@@ -463,6 +470,16 @@
   CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource);
 
   /**
+   * Return a fully resolved HTML unit, or `null` if the resolved unit is not already
+   * computed.
+   *
+   * @param htmlSource the source of the HTML unit
+   * @return a fully resolved HTML unit
+   * @see #resolveHtmlUnit(Source)
+   */
+  HtmlUnit getResolvedHtmlUnit(Source htmlSource);
+
+  /**
    * Return the source factory used to create the sources that can be analyzed in this context.
    *
    * @return the source factory used to create the sources that can be analyzed in this context
@@ -803,6 +820,14 @@
   CompilationUnit get compilationUnit;
 
   /**
+   * Return the fully resolved HTML that changed as a result of the analysis, or `null` if the
+   * HTML was not changed.
+   *
+   * @return the fully resolved HTML that changed as a result of the analysis
+   */
+  HtmlUnit get htmlUnit;
+
+  /**
    * Return the source for which the result is being reported.
    *
    * @return the source for which the result is being reported
@@ -1065,11 +1090,11 @@
     }
     SourceEntry sourceEntry = _sourceMap[removedSource];
     if (sourceEntry is HtmlEntry) {
-      HtmlEntryImpl htmlCopy = (sourceEntry as HtmlEntry).writableCopy;
+      HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
       htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
       _sourceMap[removedSource] = htmlCopy;
     } else if (sourceEntry is DartEntry) {
-      DartEntryImpl dartCopy = (sourceEntry as DartEntry).writableCopy;
+      DartEntryImpl dartCopy = sourceEntry.writableCopy;
       dartCopy.flushAstStructures();
       _sourceMap[removedSource] = dartCopy;
     }
@@ -1616,26 +1641,26 @@
 
   Object getValue(DataDescriptor descriptor) {
     if (identical(descriptor, DartEntry.ELEMENT)) {
-      return _element as Object;
+      return _element;
     } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
-      return _exportedLibraries as Object;
+      return _exportedLibraries;
     } else if (identical(descriptor, DartEntry.IMPORTED_LIBRARIES)) {
-      return _importedLibraries as Object;
+      return _importedLibraries;
     } else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
-      return _includedParts as Object;
+      return _includedParts;
     } else if (identical(descriptor, DartEntry.IS_CLIENT)) {
-      return (BooleanArray.get2(_bitmask, _CLIENT_CODE_INDEX) as bool) as Object;
+      return BooleanArray.get2(_bitmask, _CLIENT_CODE_INDEX);
     } else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
-      return (BooleanArray.get2(_bitmask, _LAUNCHABLE_INDEX) as bool) as Object;
+      return BooleanArray.get2(_bitmask, _LAUNCHABLE_INDEX);
     } else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
-      return _parseErrors as Object;
+      return _parseErrors;
     } else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
       _parsedUnitAccessed = true;
-      return _parsedUnit as Object;
+      return _parsedUnit;
     } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
-      return _publicNamespace as Object;
+      return _publicNamespace;
     } else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
-      return _sourceKind as Object;
+      return _sourceKind;
     }
     return super.getValue(descriptor);
   }
@@ -1645,13 +1670,13 @@
     while (state != null) {
       if (librarySource == state._librarySource) {
         if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
-          return state._resolutionErrors as Object;
+          return state._resolutionErrors;
         } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
-          return state._resolvedUnit as Object;
+          return state._resolvedUnit;
         } else if (identical(descriptor, DartEntry.VERIFICATION_ERRORS)) {
-          return state._verificationErrors as Object;
+          return state._verificationErrors;
         } else if (identical(descriptor, DartEntry.HINTS)) {
-          return state._hints as Object;
+          return state._hints;
         } else {
           throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
         }
@@ -1660,7 +1685,7 @@
     }
     ;
     if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
-      return AnalysisError.NO_ERRORS as Object;
+      return AnalysisError.NO_ERRORS;
     } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
       return null;
     } else {
@@ -2171,6 +2196,9 @@
     if (identical(state, CacheState.VALID)) {
       throw new IllegalArgumentException("Use setValue() to set the state to VALID");
     } else if (identical(state, CacheState.IN_PROCESS)) {
+      //
+      // We can leave the current value in the cache for any 'get' methods to access.
+      //
       return currentValue;
     }
     return BooleanArray.set2(currentValue, bitIndex, false);
@@ -2530,17 +2558,17 @@
 
   Object getValue(DataDescriptor descriptor) {
     if (identical(descriptor, HtmlEntry.ELEMENT)) {
-      return _element as Object;
+      return _element;
     } else if (identical(descriptor, HtmlEntry.PARSE_ERRORS)) {
-      return _parseErrors as Object;
+      return _parseErrors;
     } else if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
-      return _parsedUnit as Object;
+      return _parsedUnit;
     } else if (identical(descriptor, HtmlEntry.REFERENCED_LIBRARIES)) {
-      return _referencedLibraries as Object;
+      return _referencedLibraries;
     } else if (identical(descriptor, HtmlEntry.RESOLUTION_ERRORS)) {
-      return _resolutionErrors as Object;
+      return _resolutionErrors;
     } else if (identical(descriptor, HtmlEntry.HINTS)) {
-      return _hints as Object;
+      return _hints;
     }
     return super.getValue(descriptor);
   }
@@ -2814,7 +2842,7 @@
 
   Object getValue(DataDescriptor descriptor) {
     if (identical(descriptor, SourceEntry.LINE_INFO)) {
-      return _lineInfo as Object;
+      return _lineInfo;
     } else {
       throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
     }
@@ -2890,6 +2918,9 @@
     if (identical(state, CacheState.VALID)) {
       throw new IllegalArgumentException("Use setValue() to set the state to VALID");
     } else if (identical(state, CacheState.IN_PROCESS)) {
+      //
+      // We can leave the current value in the cache for any 'get' methods to access.
+      //
       return currentValue;
     }
     return defaultValue;
@@ -2964,7 +2995,7 @@
 
   AnalysisContentStatisticsImpl_CacheRowImpl(this.name);
 
-  bool operator ==(Object obj) => obj is AnalysisContentStatisticsImpl_CacheRowImpl && (obj as AnalysisContentStatisticsImpl_CacheRowImpl).name == name;
+  bool operator ==(Object obj) => obj is AnalysisContentStatisticsImpl_CacheRowImpl && obj.name == name;
 
   int get errorCount => _errorCount;
 
@@ -3069,6 +3100,8 @@
   }
 
   void addSourceInfo(Source source, SourceEntry info) {
+    // This implementation assumes that the access to the cache does not need to be synchronized
+    // because no other object can have access to this context while this method is being invoked.
     _cache.put(source, info);
   }
 
@@ -3077,10 +3110,16 @@
       return;
     }
     {
+      //
+      // First, compute the list of sources that have been removed.
+      //
       List<Source> removedSources = new List<Source>.from(changeSet.removed3);
       for (SourceContainer container in changeSet.removedContainers) {
         addSourcesInContainer(removedSources, container);
       }
+      //
+      // Then determine which cached results are no longer valid.
+      //
       bool addedDartSource = false;
       for (Source source in changeSet.added3) {
         if (sourceAvailable(source)) {
@@ -3094,10 +3133,14 @@
         sourceRemoved(source);
       }
       if (addedDartSource) {
+        // TODO(brianwilkerson) This is hugely inefficient, but we need to re-analyze any libraries
+        // that might have been referencing the not-yet-existing source that was just added. Longer
+        // term we need to keep track of which libraries are referencing non-existing sources and
+        // only re-analyze those libraries.
         for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
           SourceEntry sourceEntry = mapEntry.getValue();
           if (!mapEntry.getKey().isInSystemLibrary && sourceEntry is DartEntry) {
-            DartEntryImpl dartCopy = (sourceEntry as DartEntry).writableCopy;
+            DartEntryImpl dartCopy = sourceEntry.writableCopy;
             dartCopy.invalidateAllResolutionInformation();
             mapEntry.setValue(dartCopy);
           }
@@ -3146,7 +3189,7 @@
     SourceEntry sourceEntry = getReadableSourceEntry(source);
     if (sourceEntry is DartEntry) {
       List<AnalysisError> errors = new List<AnalysisError>();
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
       dartEntry = getReadableDartEntry(source);
       if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
@@ -3170,7 +3213,7 @@
       }
       return new List.from(errors);
     } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+      HtmlEntry htmlEntry = sourceEntry;
       return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
     }
     return AnalysisError.NO_ERRORS;
@@ -3188,7 +3231,7 @@
       return SourceKind.UNKNOWN;
     } else if (sourceEntry is DartEntry) {
       try {
-        return getDartParseData(source, sourceEntry as DartEntry, DartEntry.SOURCE_KIND);
+        return getDartParseData(source, sourceEntry, DartEntry.SOURCE_KIND);
       } on AnalysisException catch (exception) {
         return SourceKind.UNKNOWN;
       }
@@ -3244,6 +3287,7 @@
     if (unit == null) {
       throw new AnalysisException.con1("Internal error: computeResolvableHtmlUnit could not parse ${source.fullName}");
     }
+    // If the unit is ever modified by resolution then we will need to create a copy of it.
     return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit);
   }
 
@@ -3252,6 +3296,7 @@
   InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
     List<Source> sourcesToRemove = new List<Source>();
     {
+      // Move sources in the specified directory to the new context
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
         Source source = entry.getKey();
         if (container.contains(source)) {
@@ -3266,6 +3311,7 @@
   AnalysisOptions get analysisOptions => _options;
 
   Element getElement(ElementLocation location) {
+    // TODO(brianwilkerson) This should not be a "get" method.
     try {
       List<String> components = (location as ElementLocationImpl).components;
       Source librarySource = computeSourceFromEncoding(components[0]);
@@ -3285,10 +3331,10 @@
   AnalysisErrorInfo getErrors(Source source) {
     SourceEntry sourceEntry = getReadableSourceEntry(source);
     if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       return new AnalysisErrorInfoImpl(dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
     } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+      HtmlEntry htmlEntry = sourceEntry;
       return new AnalysisErrorInfoImpl(htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
     }
     return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
@@ -3297,7 +3343,7 @@
   HtmlElement getHtmlElement(Source source) {
     SourceEntry sourceEntry = getReadableSourceEntry(source);
     if (sourceEntry is HtmlEntry) {
-      return (sourceEntry as HtmlEntry).getValue(HtmlEntry.ELEMENT);
+      return sourceEntry.getValue(HtmlEntry.ELEMENT);
     }
     return null;
   }
@@ -3343,12 +3389,16 @@
   }
 
   List<Source> get launchableClientLibrarySources {
+    // TODO(brianwilkerson) This needs to filter out libraries that do not reference dart:html,
+    // either directly or indirectly.
     List<Source> sources = new List<Source>();
     {
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
         Source source = entry.getKey();
         SourceEntry sourceEntry = entry.getValue();
         if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
+          //          DartEntry dartEntry = (DartEntry) sourceEntry;
+          //          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && dartEntry.getValue(DartEntry.IS_CLIENT)) {
           sources.add(source);
         }
       }
@@ -3357,12 +3407,16 @@
   }
 
   List<Source> get launchableServerLibrarySources {
+    // TODO(brianwilkerson) This needs to filter out libraries that reference dart:html, either
+    // directly or indirectly.
     List<Source> sources = new List<Source>();
     {
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
         Source source = entry.getKey();
         SourceEntry sourceEntry = entry.getValue();
         if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
+          //          DartEntry dartEntry = (DartEntry) sourceEntry;
+          //          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && !dartEntry.getValue(DartEntry.IS_CLIENT)) {
           sources.add(source);
         }
       }
@@ -3416,7 +3470,7 @@
   LibraryElement getLibraryElement(Source source) {
     SourceEntry sourceEntry = getReadableSourceEntry(source);
     if (sourceEntry is DartEntry) {
-      return (sourceEntry as DartEntry).getValue(DartEntry.ELEMENT);
+      return sourceEntry.getValue(DartEntry.ELEMENT);
     }
     return null;
   }
@@ -3432,6 +3486,8 @@
   }
 
   Namespace getPublicNamespace(LibraryElement library) {
+    // TODO(brianwilkerson) Rename this to not start with 'get'. Note that this is not part of the
+    // API of the interface.
     Source source = library.definingCompilationUnit.source;
     DartEntry dartEntry = getReadableDartEntry(source);
     if (dartEntry == null) {
@@ -3461,6 +3517,8 @@
   }
 
   Namespace getPublicNamespace2(Source source) {
+    // TODO(brianwilkerson) Rename this to not start with 'get'. Note that this is not part of the
+    // API of the interface.
     DartEntry dartEntry = getReadableDartEntry(source);
     if (dartEntry == null) {
       return null;
@@ -3494,7 +3552,7 @@
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
         SourceEntry sourceEntry = entry.getValue();
         if (sourceEntry is DartEntry) {
-          if (!(sourceEntry as DartEntry).isRefactoringSafe) {
+          if (!sourceEntry.isRefactoringSafe) {
             sources.add(entry.getKey());
           }
         }
@@ -3513,7 +3571,18 @@
   CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
     SourceEntry sourceEntry = getReadableSourceEntry(unitSource);
     if (sourceEntry is DartEntry) {
-      return (sourceEntry as DartEntry).getValue2(DartEntry.RESOLVED_UNIT, librarySource);
+      return sourceEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource);
+    }
+    return null;
+  }
+
+  HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
+    SourceEntry sourceEntry = getReadableSourceEntry(htmlSource);
+    if (sourceEntry is HtmlEntry) {
+      HtmlEntry htmlEntry = sourceEntry;
+      if (htmlEntry.getValue(HtmlEntry.ELEMENT) != null) {
+        return htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
+      }
     }
     return null;
   }
@@ -3531,9 +3600,15 @@
     Set<Source> sources = new Set<Source>();
     {
       bool hintsEnabled = _options.hint;
+      //
+      // Look for priority sources that need to be analyzed.
+      //
       for (Source source in _priorityOrder) {
         getSourcesNeedingProcessing2(source, _cache.get(source), true, hintsEnabled, sources);
       }
+      //
+      // Look for non-priority sources that need to be analyzed.
+      //
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
         getSourcesNeedingProcessing2(entry.getKey(), entry.getValue(), false, hintsEnabled, sources);
       }
@@ -3548,8 +3623,9 @@
         SourceEntry entry = mapEntry.getValue();
         if (entry is DartEntry) {
           Source source = mapEntry.getKey();
-          DartEntry dartEntry = entry as DartEntry;
+          DartEntry dartEntry = entry;
           SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
+          // get library independent values
           statistics.putCacheItem(dartEntry, DartEntry.PARSE_ERRORS);
           statistics.putCacheItem(dartEntry, DartEntry.PARSED_UNIT);
           statistics.putCacheItem(dartEntry, DartEntry.SOURCE_KIND);
@@ -3562,6 +3638,7 @@
             statistics.putCacheItem(dartEntry, DartEntry.IS_CLIENT);
             statistics.putCacheItem(dartEntry, DartEntry.IS_LAUNCHABLE);
           }
+          // get library-specific values
           List<Source> librarySources = getLibrariesContaining(source);
           for (Source librarySource in librarySources) {
             statistics.putCacheItem2(dartEntry, librarySource, DartEntry.HINTS);
@@ -3593,7 +3670,7 @@
   bool isClientLibrary(Source librarySource) {
     SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
     if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       return dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
     }
     return false;
@@ -3602,7 +3679,7 @@
   bool isServerLibrary(Source librarySource) {
     SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
     if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       return !dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
     }
     return false;
@@ -3616,10 +3693,12 @@
       return;
     }
     {
+      // TODO(brianwilkerson) This does not lock against the other context's cacheLock.
       for (MapEntry<Source, SourceEntry> entry in (context as AnalysisContextImpl)._cache.entrySet()) {
         Source newSource = entry.getKey();
         SourceEntry existingEntry = getReadableSourceEntry(newSource);
         if (existingEntry == null) {
+          // TODO(brianwilkerson) Decide whether we really need to copy the info.
           _cache.put(newSource, entry.getValue().writableCopy);
         } else {
         }
@@ -3638,6 +3717,7 @@
     if (task == null) {
       return new AnalysisResult(getChangeNotices(true), getEnd - getStart, null, -1);
     }
+    //System.out.println(task);
     int performStart = JavaSystem.currentTimeMillis();
     try {
       task.perform(_resultRecorder);
@@ -3656,6 +3736,9 @@
       for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
         Source librarySource = entry.getKey();
         LibraryElement library = entry.getValue();
+        //
+        // Cache the element in the library's info.
+        //
         DartEntry dartEntry = getReadableDartEntry(librarySource);
         if (dartEntry != null) {
           DartEntryImpl dartCopy = dartEntry.writableCopy;
@@ -3675,7 +3758,10 @@
 
   CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) => getDartResolutionData2(unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
 
-  HtmlUnit resolveHtmlUnit(Source htmlSource) => parseHtmlUnit(htmlSource);
+  HtmlUnit resolveHtmlUnit(Source htmlSource) {
+    computeHtmlElement(htmlSource);
+    return parseHtmlUnit(htmlSource);
+  }
 
   void set analysisOptions(AnalysisOptions options) {
     {
@@ -3684,6 +3770,11 @@
       if (this._options.cacheSize != cacheSize) {
         this._options.cacheSize = cacheSize;
         _cache.maxCacheSize = cacheSize;
+        //
+        // Cap the size of the priority list to being less than the cache size. Failure to do so can
+        // result in an infinite loop in performAnalysisTask() because re-caching one AST structure
+        // can cause another priority source's AST structure to be flushed.
+        //
         int maxPriorityOrderSize = cacheSize - _PRIORITY_ORDER_SIZE_DELTA;
         if (_priorityOrder.length > maxPriorityOrderSize) {
           List<Source> newPriorityOrder = new List<Source>(maxPriorityOrderSize);
@@ -3712,6 +3803,11 @@
         if (sources.isEmpty) {
           _priorityOrder = Source.EMPTY_ARRAY;
         }
+        //
+        // Cap the size of the priority list to being less than the cache size. Failure to do so can
+        // result in an infinite loop in performAnalysisTask() because re-caching one AST structure
+        // can cause another priority source's AST structure to be flushed.
+        //
         int count = Math.min(sources.length, _options.cacheSize - _PRIORITY_ORDER_SIZE_DELTA);
         _priorityOrder = new List<Source>(count);
         for (int i = 0; i < count; i++) {
@@ -3793,8 +3889,15 @@
     DartEntry unitEntry = null;
     Source unitSource = task.unitSource;
     if (resolver != null) {
+      //
+      // The resolver should only be null if an exception was thrown before (or while) it was
+      // being created.
+      //
       Set<Library> resolvedLibraries = resolver.resolvedLibraries;
       if (resolvedLibraries == null) {
+        //
+        // The resolved libraries should only be null if an exception was thrown during resolution.
+        //
         unitEntry = getReadableDartEntry(unitSource);
         if (unitEntry == null) {
           throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
@@ -3821,6 +3924,7 @@
               DartEntry dartEntry = _cache.get(source) as DartEntry;
               int sourceTime = source.modificationStamp;
               if (dartEntry.modificationTime != sourceTime) {
+                // The source has changed without the context being notified. Simulate notification.
                 sourceChanged(source);
                 dartEntry = getReadableDartEntry(source);
                 if (dartEntry == null) {
@@ -3857,8 +3961,17 @@
                 int resultTime = library.getModificationTime(source);
                 DartEntryImpl dartCopy = dartEntry.writableCopy;
                 if (thrownException == null || resultTime >= 0) {
+                  //
+                  // The analysis was performed on out-of-date sources. Mark the cache so that the
+                  // sources will be re-analyzed using the up-to-date sources.
+                  //
                   dartCopy.recordResolutionNotInProcess();
                 } else {
+                  //
+                  // We could not determine whether the sources were up-to-date or out-of-date. Mark
+                  // the cache so that we won't attempt to re-analyze the sources until there's a
+                  // good chance that we'll be able to do so without error.
+                  //
                   dartCopy.recordResolutionError();
                 }
                 dartCopy.exception = thrownException;
@@ -3916,11 +4029,14 @@
       for (Source source in library.compilationUnitSources) {
         DartEntry dartEntry = getReadableDartEntry(source);
         if (dartEntry == null) {
+          // This shouldn't be possible because we should never have performed the task if the
+          // source didn't represent a Dart file, but check to be safe.
           throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${source.fullName}");
         }
         int sourceTime = source.modificationStamp;
         int resultTime = library.getModificationTime(source);
         if (sourceTime != resultTime) {
+          // The source has changed without the context being notified. Simulate notification.
           sourceChanged(source);
           allTimesMatch = false;
         }
@@ -3942,8 +4058,15 @@
    * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry cacheDartHintData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+    //
+    // Check to see whether we already have the information being requested.
+    //
     CacheState state = dartEntry.getState2(descriptor, librarySource);
     while (state != CacheState.ERROR && state != CacheState.VALID) {
+      //
+      // If not, compute the information. Unless the modification date of the source continues to
+      // change, this loop will eventually terminate.
+      //
       dartEntry = new GenerateDartHintsTask(this, getLibraryElement(librarySource)).perform(_resultRecorder) as DartEntry;
       state = dartEntry.getState2(descriptor, librarySource);
     }
@@ -3969,8 +4092,15 @@
         return dartEntry;
       }
     }
+    //
+    // Check to see whether we already have the information being requested.
+    //
     CacheState state = dartEntry.getState(descriptor);
     while (state != CacheState.ERROR && state != CacheState.VALID) {
+      //
+      // If not, compute the information. Unless the modification date of the source continues to
+      // change, this loop will eventually terminate.
+      //
       dartEntry = new ParseDartTask(this, source).perform(_resultRecorder) as DartEntry;
       state = dartEntry.getState(descriptor);
     }
@@ -3991,8 +4121,17 @@
    * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry cacheDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+    //
+    // Check to see whether we already have the information being requested.
+    //
     CacheState state = (identical(descriptor, DartEntry.ELEMENT)) ? dartEntry.getState(descriptor) : dartEntry.getState2(descriptor, librarySource);
     while (state != CacheState.ERROR && state != CacheState.VALID) {
+      //
+      // If not, compute the information. Unless the modification date of the source continues to
+      // change, this loop will eventually terminate.
+      //
+      // TODO(brianwilkerson) As an optimization, if we already have the element model for the
+      // library we can use ResolveDartUnitTask to produce the resolved AST structure much faster.
       dartEntry = new ResolveDartLibraryTask(this, unitSource, librarySource).perform(_resultRecorder) as DartEntry;
       state = (identical(descriptor, DartEntry.ELEMENT)) ? dartEntry.getState(descriptor) : dartEntry.getState2(descriptor, librarySource);
     }
@@ -4012,8 +4151,15 @@
    * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry cacheDartVerificationData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+    //
+    // Check to see whether we already have the information being requested.
+    //
     CacheState state = dartEntry.getState2(descriptor, librarySource);
     while (state != CacheState.ERROR && state != CacheState.VALID) {
+      //
+      // If not, compute the information. Unless the modification date of the source continues to
+      // change, this loop will eventually terminate.
+      //
       dartEntry = new GenerateDartErrorsTask(this, unitSource, getLibraryElement(librarySource)).perform(_resultRecorder) as DartEntry;
       state = dartEntry.getState2(descriptor, librarySource);
     }
@@ -4033,8 +4179,15 @@
    *           resolved
    */
   HtmlEntry cacheHtmlParseData(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
+    //
+    // Check to see whether we already have the information being requested.
+    //
     CacheState state = htmlEntry.getState(descriptor);
     while (state != CacheState.ERROR && state != CacheState.VALID) {
+      //
+      // If not, compute the information. Unless the modification date of the source continues to
+      // change, this loop will eventually terminate.
+      //
       htmlEntry = new ParseHtmlTask(this, source).perform(_resultRecorder) as HtmlEntry;
       state = htmlEntry.getState(descriptor);
     }
@@ -4054,8 +4207,15 @@
    *           resolved
    */
   HtmlEntry cacheHtmlResolutionData(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
+    //
+    // Check to see whether we already have the information being requested.
+    //
     CacheState state = htmlEntry.getState(descriptor);
     while (state != CacheState.ERROR && state != CacheState.VALID) {
+      //
+      // If not, compute the information. Unless the modification date of the source continues to
+      // change, this loop will eventually terminate.
+      //
       htmlEntry = new ResolveHtmlTask(this, source).perform(_resultRecorder) as HtmlEntry;
       state = htmlEntry.getState(descriptor);
     }
@@ -4185,7 +4345,7 @@
   Object getDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
     dartEntry = cacheDartParseData(source, dartEntry, descriptor);
     if (identical(descriptor, DartEntry.PARSED_UNIT)) {
-      return dartEntry.anyParsedCompilationUnit as Object;
+      return dartEntry.anyParsedCompilationUnit;
     }
     return dartEntry.getValue(descriptor);
   }
@@ -4337,17 +4497,26 @@
   AnalysisTask get nextTaskAnalysisTask {
     {
       bool hintsEnabled = _options.hint;
+      //
+      // Look for incremental analysis
+      //
       if (_incrementalAnalysisCache != null && _incrementalAnalysisCache.hasWork()) {
         AnalysisTask task = new IncrementalAnalysisTask(this, _incrementalAnalysisCache);
         _incrementalAnalysisCache = null;
         return task;
       }
+      //
+      // Look for a priority source that needs to be analyzed.
+      //
       for (Source source in _priorityOrder) {
         AnalysisTask task = getNextTaskAnalysisTask2(source, _cache.get(source), true, hintsEnabled);
         if (task != null) {
           return task;
         }
       }
+      //
+      // Look for a non-priority source that needs to be analyzed.
+      //
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
         AnalysisTask task = getNextTaskAnalysisTask2(entry.getKey(), entry.getValue(), false, hintsEnabled);
         if (task != null) {
@@ -4373,7 +4542,7 @@
    */
   AnalysisTask getNextTaskAnalysisTask2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled) {
     if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       if (!source.exists()) {
         DartEntryImpl dartCopy = dartEntry.writableCopy;
         dartCopy.recordParseError();
@@ -4402,16 +4571,24 @@
         if (libraryEntry is DartEntry) {
           CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
           if (identical(elementState, CacheState.INVALID) || (isPriority && identical(elementState, CacheState.FLUSHED))) {
-            DartEntryImpl libraryCopy = (libraryEntry as DartEntry).writableCopy;
+            DartEntryImpl libraryCopy = libraryEntry.writableCopy;
             libraryCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
             _cache.put(librarySource, libraryCopy);
             return new ResolveDartLibraryTask(this, source, librarySource);
           }
           CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource);
           if (identical(resolvedUnitState, CacheState.INVALID) || (isPriority && identical(resolvedUnitState, CacheState.FLUSHED))) {
+            //
+            // The commented out lines below are an optimization that doesn't quite work yet. The
+            // problem is that if the source was not resolved because it wasn't part of any library,
+            // then there won't be any elements in the element model that we can use to resolve it.
+            //
+            //LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+            //if (libraryElement != null) {
             DartEntryImpl dartCopy = dartEntry.writableCopy;
             dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.IN_PROCESS);
             _cache.put(source, dartCopy);
+            //return new ResolveDartUnitTask(this, source, libraryElement);
             return new ResolveDartLibraryTask(this, source, librarySource);
           }
           CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VERIFICATION_ERRORS, librarySource);
@@ -4439,7 +4616,7 @@
         }
       }
     } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+      HtmlEntry htmlEntry = sourceEntry;
       if (!source.exists()) {
         HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
         htmlCopy.recordParseError();
@@ -4577,7 +4754,7 @@
    */
   void getSourcesNeedingProcessing2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, Set<Source> sources) {
     if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
       if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && identical(parseErrorsState, CacheState.FLUSHED))) {
         sources.add(source);
@@ -4627,7 +4804,7 @@
         }
       }
     } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+      HtmlEntry htmlEntry = sourceEntry;
       CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
       if (identical(parsedUnitState, CacheState.INVALID) || (isPriority && identical(parsedUnitState, CacheState.FLUSHED))) {
         sources.add(source);
@@ -4650,11 +4827,11 @@
     for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
       SourceEntry sourceEntry = mapEntry.getValue();
       if (sourceEntry is HtmlEntry) {
-        HtmlEntryImpl htmlCopy = (sourceEntry as HtmlEntry).writableCopy;
+        HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
         htmlCopy.invalidateAllResolutionInformation();
         mapEntry.setValue(htmlCopy);
       } else if (sourceEntry is DartEntry) {
-        DartEntryImpl dartCopy = (sourceEntry as DartEntry).writableCopy;
+        DartEntryImpl dartCopy = sourceEntry.writableCopy;
         dartCopy.invalidateAllResolutionInformation();
         mapEntry.setValue(dartCopy);
       }
@@ -4670,6 +4847,9 @@
    * @param librarySource the source of the library being invalidated
    */
   void invalidateLibraryResolution(Source librarySource) {
+    // TODO(brianwilkerson) This could be optimized. There's no need to flush all of these caches if
+    // the public namespace hasn't changed, which will be a fairly common case. The question is
+    // whether we can afford the time to compute the namespace to look for differences.
     DartEntry libraryEntry = getReadableDartEntry(librarySource);
     if (libraryEntry != null) {
       List<Source> includedParts = libraryEntry.getValue(DartEntry.INCLUDED_PARTS);
@@ -4680,7 +4860,7 @@
       for (Source partSource in includedParts) {
         SourceEntry partEntry = _cache.get(partSource);
         if (partEntry is DartEntry) {
-          DartEntryImpl partCopy = (partEntry as DartEntry).writableCopy;
+          DartEntryImpl partCopy = partEntry.writableCopy;
           partCopy.invalidateAllResolutionInformation();
           _cache.put(partSource, partCopy);
         }
@@ -4754,6 +4934,8 @@
     {
       SourceEntry sourceEntry = _cache.get(source);
       if (sourceEntry is! DartEntry) {
+        // This shouldn't be possible because we should never have performed the task if the source
+        // didn't represent a Dart file, but check to be safe.
         throw new AnalysisException.con1("Internal error: attempting to verify non-Dart file as a Dart file: ${source.fullName}");
       }
       dartEntry = sourceEntry as DartEntry;
@@ -4762,6 +4944,7 @@
       int resultTime = task.modificationTime;
       if (sourceTime == resultTime) {
         if (dartEntry.modificationTime != sourceTime) {
+          // The source has changed without the context being notified. Simulate notification.
           sourceChanged(source);
           dartEntry = getReadableDartEntry(source);
           if (dartEntry == null) {
@@ -4782,8 +4965,17 @@
       } else {
         DartEntryImpl dartCopy = dartEntry.writableCopy;
         if (thrownException == null || resultTime >= 0) {
+          //
+          // The analysis was performed on out-of-date sources. Mark the cache so that the source
+          // will be re-verified using the up-to-date sources.
+          //
           dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.INVALID);
         } else {
+          //
+          // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+          // cache so that we won't attempt to re-verify the source until there's a good chance
+          // that we'll be able to do so without error.
+          //
           dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.ERROR);
         }
         dartCopy.exception = thrownException;
@@ -4812,8 +5004,12 @@
     Map<Source, TimestampedData<List<AnalysisError>>> hintMap = task.hintMap;
     if (hintMap == null) {
       {
+        // We don't have any information about which sources to mark as invalid other than the library
+        // source.
         SourceEntry sourceEntry = _cache.get(librarySource);
         if (sourceEntry is! DartEntry) {
+          // This shouldn't be possible because we should never have performed the task if the source
+          // didn't represent a Dart file, but check to be safe.
           throw new AnalysisException.con1("Internal error: attempting to generate hints for non-Dart file as a Dart file: ${librarySource.fullName}");
         }
         if (thrownException == null) {
@@ -4832,6 +5028,8 @@
       {
         SourceEntry sourceEntry = _cache.get(unitSource);
         if (sourceEntry is! DartEntry) {
+          // This shouldn't be possible because we should never have performed the task if the source
+          // didn't represent a Dart file, but check to be safe.
           throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${unitSource.fullName}");
         }
         DartEntry dartEntry = sourceEntry as DartEntry;
@@ -4843,6 +5041,7 @@
         int resultTime = results.modificationTime;
         if (sourceTime == resultTime) {
           if (dartEntry.modificationTime != sourceTime) {
+            // The source has changed without the context being notified. Simulate notification.
             sourceChanged(unitSource);
             dartEntry = getReadableDartEntry(unitSource);
             if (dartEntry == null) {
@@ -4864,8 +5063,17 @@
           if (identical(dartEntry.getState2(DartEntry.HINTS, librarySource), CacheState.IN_PROCESS)) {
             DartEntryImpl dartCopy = dartEntry.writableCopy;
             if (thrownException == null || resultTime >= 0) {
+              //
+              // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+              // will be re-analyzed using the up-to-date sources.
+              //
               dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.INVALID);
             } else {
+              //
+              // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+              // cache so that we won't attempt to re-analyze the sources until there's a good chance
+              // that we'll be able to do so without error.
+              //
               dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
             }
             dartCopy.exception = thrownException;
@@ -4915,6 +5123,8 @@
     {
       SourceEntry sourceEntry = _cache.get(source);
       if (sourceEntry is! DartEntry) {
+        // This shouldn't be possible because we should never have performed the task if the source
+        // didn't represent a Dart file, but check to be safe.
         throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}");
       }
       dartEntry = sourceEntry as DartEntry;
@@ -4923,6 +5133,7 @@
       int resultTime = task.modificationTime;
       if (sourceTime == resultTime) {
         if (dartEntry.modificationTime != sourceTime) {
+          // The source has changed without the context being notified. Simulate notification.
           sourceChanged(source);
           dartEntry = getReadableDartEntry(source);
           if (dartEntry == null) {
@@ -4945,6 +5156,8 @@
           dartCopy.setValue(DartEntry.INCLUDED_PARTS, task.includedSources);
           ChangeNoticeImpl notice = getNotice(source);
           notice.setErrors(dartEntry.allErrors, lineInfo);
+          // Verify that the incrementally parsed and resolved unit in the incremental cache
+          // is structurally equivalent to the fully parsed unit
           _incrementalAnalysisCache = IncrementalAnalysisCache.verifyStructure(_incrementalAnalysisCache, source, task.compilationUnit);
         } else {
           dartCopy.recordParseError();
@@ -4955,8 +5168,17 @@
       } else {
         DartEntryImpl dartCopy = dartEntry.writableCopy;
         if (thrownException == null || resultTime >= 0) {
+          //
+          // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+          // will be re-analyzed using the up-to-date sources.
+          //
           dartCopy.recordParseNotInProcess();
         } else {
+          //
+          // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+          // cache so that we won't attempt to re-analyze the sources until there's a good chance
+          // that we'll be able to do so without error.
+          //
           dartCopy.recordParseError();
         }
         dartCopy.exception = thrownException;
@@ -4985,6 +5207,8 @@
     {
       SourceEntry sourceEntry = _cache.get(source);
       if (sourceEntry is! HtmlEntry) {
+        // This shouldn't be possible because we should never have performed the task if the source
+        // didn't represent an HTML file, but check to be safe.
         throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}");
       }
       htmlEntry = sourceEntry as HtmlEntry;
@@ -4993,6 +5217,7 @@
       int resultTime = task.modificationTime;
       if (sourceTime == resultTime) {
         if (htmlEntry.modificationTime != sourceTime) {
+          // The source has changed without the context being notified. Simulate notification.
           sourceChanged(source);
           htmlEntry = getReadableHtmlEntry(source);
           if (htmlEntry == null) {
@@ -5018,6 +5243,10 @@
       } else {
         HtmlEntryImpl htmlCopy = (sourceEntry as HtmlEntry).writableCopy;
         if (thrownException == null || resultTime >= 0) {
+          //
+          // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+          // will be re-analyzed using the up-to-date sources.
+          //
           if (identical(htmlCopy.getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
             htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
           }
@@ -5028,6 +5257,11 @@
             htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID);
           }
         } else {
+          //
+          // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+          // cache so that we won't attempt to re-analyze the sources until there's a good chance
+          // that we'll be able to do so without error.
+          //
           htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
           htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
           htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
@@ -5059,6 +5293,8 @@
     {
       SourceEntry sourceEntry = _cache.get(unitSource);
       if (sourceEntry is! DartEntry) {
+        // This shouldn't be possible because we should never have performed the task if the source
+        // didn't represent a Dart file, but check to be safe.
         throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${unitSource.fullName}");
       }
       dartEntry = sourceEntry as DartEntry;
@@ -5067,6 +5303,7 @@
       int resultTime = task.modificationTime;
       if (sourceTime == resultTime) {
         if (dartEntry.modificationTime != sourceTime) {
+          // The source has changed without the context being notified. Simulate notification.
           sourceChanged(unitSource);
           dartEntry = getReadableDartEntry(unitSource);
           if (dartEntry == null) {
@@ -5085,10 +5322,19 @@
       } else {
         DartEntryImpl dartCopy = dartEntry.writableCopy;
         if (thrownException == null || resultTime >= 0) {
+          //
+          // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+          // will be re-analyzed using the up-to-date sources.
+          //
           if (identical(dartCopy.getState(DartEntry.RESOLVED_UNIT), CacheState.IN_PROCESS)) {
             dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.INVALID);
           }
         } else {
+          //
+          // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+          // cache so that we won't attempt to re-analyze the sources until there's a good chance
+          // that we'll be able to do so without error.
+          //
           dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.ERROR);
         }
         dartCopy.exception = thrownException;
@@ -5117,6 +5363,8 @@
     {
       SourceEntry sourceEntry = _cache.get(source);
       if (sourceEntry is! HtmlEntry) {
+        // This shouldn't be possible because we should never have performed the task if the source
+        // didn't represent an HTML file, but check to be safe.
         throw new AnalysisException.con1("Internal error: attempting to reolve non-HTML file as an HTML file: ${source.fullName}");
       }
       htmlEntry = sourceEntry as HtmlEntry;
@@ -5125,6 +5373,7 @@
       int resultTime = task.modificationTime;
       if (sourceTime == resultTime) {
         if (htmlEntry.modificationTime != sourceTime) {
+          // The source has changed without the context being notified. Simulate notification.
           sourceChanged(source);
           htmlEntry = getReadableHtmlEntry(source);
           if (htmlEntry == null) {
@@ -5136,6 +5385,7 @@
           htmlCopy.setValue(HtmlEntry.ELEMENT, task.element);
           htmlCopy.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
           ChangeNoticeImpl notice = getNotice(source);
+          notice.htmlUnit = task.resolvedUnit;
           notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
         } else {
           htmlCopy.recordResolutionError();
@@ -5146,6 +5396,10 @@
       } else {
         HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
         if (thrownException == null || resultTime >= 0) {
+          //
+          // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+          // will be re-analyzed using the up-to-date sources.
+          //
           if (identical(htmlCopy.getState(HtmlEntry.ELEMENT), CacheState.IN_PROCESS)) {
             htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
           }
@@ -5153,6 +5407,11 @@
             htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
           }
         } else {
+          //
+          // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+          // cache so that we won't attempt to re-analyze the sources until there's a good chance
+          // that we'll be able to do so without error.
+          //
           htmlCopy.recordResolutionError();
         }
         htmlCopy.exception = thrownException;
@@ -5195,10 +5454,12 @@
   void sourceChanged(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
     if (sourceEntry == null || sourceEntry.modificationTime == source.modificationStamp) {
+      // Either we have removed this source, in which case we don't care that it is changed, or we
+      // have already invalidated the cache and don't need to invalidate it again.
       return;
     }
     if (sourceEntry is HtmlEntry) {
-      HtmlEntryImpl htmlCopy = (sourceEntry as HtmlEntry).writableCopy;
+      HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
       htmlCopy.modificationTime = source.modificationStamp;
       htmlCopy.invalidateAllInformation();
       _cache.put(source, htmlCopy);
@@ -5212,9 +5473,10 @@
         }
       }
       for (Source library in librariesToInvalidate) {
+        //    for (Source library : containingLibraries) {
         invalidateLibraryResolution(library);
       }
-      DartEntryImpl dartCopy = (sourceEntry as DartEntry).writableCopy;
+      DartEntryImpl dartCopy = sourceEntry.writableCopy;
       dartCopy.modificationTime = source.modificationStamp;
       dartCopy.invalidateAllInformation();
       _cache.put(source, dartCopy);
@@ -5282,7 +5544,7 @@
       }
     }
     if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry as DartEntry;
+      DartEntry dartEntry = sourceEntry;
       if (astIsNeeded(dartEntry)) {
         return RetentionPriority.MEDIUM;
       }
@@ -5396,6 +5658,12 @@
   CompilationUnit compilationUnit;
 
   /**
+   * The fully resolved HTML that changed as a result of the analysis, or `null` if the HTML
+   * was not changed.
+   */
+  HtmlUnit htmlUnit;
+
+  /**
    * The errors that changed as a result of the analysis, or `null` if errors were not
    * changed.
    */
@@ -5418,20 +5686,8 @@
    */
   ChangeNoticeImpl(this.source);
 
-  /**
-   * Return the errors that changed as a result of the analysis, or `null` if errors were not
-   * changed.
-   *
-   * @return the errors that changed as a result of the analysis
-   */
   List<AnalysisError> get errors => _errors;
 
-  /**
-   * Return the line information associated with the source, or `null` if errors were not
-   * changed.
-   *
-   * @return the line information associated with the source
-   */
   LineInfo get lineInfo => _lineInfo;
 
   /**
@@ -5676,6 +5932,10 @@
     if (elementMap.isEmpty) {
       return;
     }
+    // TODO(jwren) we are making the assumption here that the elementMap will have sources from only
+    // one library, while this is true with our use of the Analysis Engine, it is not required by
+    // the API, revisit to fix cases where the elementMap can have sources both in the sdk and other
+    // libraries
     Source source = new JavaIterator(elementMap.keys.toSet()).next();
     if (source.isInSystemLibrary) {
       _sdkAnalysisContext.recordLibraryElements(elementMap);
@@ -5791,10 +6051,11 @@
    *         be performed
    */
   static IncrementalAnalysisCache update(IncrementalAnalysisCache cache, Source source, String oldContents, String newContents, int offset, int oldLength, int newLength, SourceEntry sourceEntry) {
+    // Determine the cache resolved unit
     Source librarySource = null;
     CompilationUnit unit = null;
     if (sourceEntry is DartEntryImpl) {
-      DartEntryImpl dartEntry = sourceEntry as DartEntryImpl;
+      DartEntryImpl dartEntry = sourceEntry;
       List<Source> librarySources = dartEntry.librariesContaining;
       if (librarySources.length == 1) {
         librarySource = librarySources[0];
@@ -5803,6 +6064,8 @@
         }
       }
     }
+    // Create a new cache if there is not an existing cache or the source is different
+    // or a new resolved compilation unit is available
     if (cache == null || cache.source != source || unit != null) {
       if (unit == null) {
         return null;
@@ -5815,6 +6078,7 @@
       }
       return new IncrementalAnalysisCache(librarySource, source, unit, oldContents, newContents, offset, oldLength, newLength);
     }
+    // Update the existing cache if the change is contiguous
     if (cache._oldLength == 0 && cache._newLength == 0) {
       cache._offset = offset;
       cache._oldLength = oldLength;
@@ -6277,6 +6541,16 @@
     }
   }
 
+  HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
+    InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getResolvedHtmlUnit");
+    try {
+      instrumentation.metric3("contextId", _contextId);
+      return _basis.getResolvedHtmlUnit(htmlSource);
+    } finally {
+      instrumentation.log2(2);
+    }
+  }
+
   SourceFactory get sourceFactory {
     InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getSourceFactory");
     try {
@@ -6598,6 +6872,11 @@
  */
 class PerformanceStatistics {
   /**
+   * The [TimeCounter] for time spent in Angular analysis.
+   */
+  static TimeCounter angular = new TimeCounter();
+
+  /**
    * The [TimeCounter] for time spent in scanning.
    */
   static TimeCounter scan = new TimeCounter();
@@ -7086,8 +7365,15 @@
       RecordingErrorListener errorListener = new RecordingErrorListener();
       ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
       TypeProvider typeProvider = context.typeProvider;
+      //
+      // Use the ConstantVerifier to verify the use of constants. This needs to happen before using
+      // the ErrorVerifier because some error codes need the computed constant values.
+      //
       ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, typeProvider);
       unit.accept(constantVerifier);
+      //
+      // Use the ErrorVerifier to compute the rest of the errors.
+      //
       ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, libraryElement, typeProvider, new InheritanceManager(libraryElement));
       unit.accept(errorVerifier);
       _errors = errorListener.getErrors2(source);
@@ -7146,6 +7432,9 @@
     int partCount = parts.length;
     List<CompilationUnit> compilationUnits = new List<CompilationUnit>(partCount + 1);
     Map<Source, TimestampedData<CompilationUnit>> timestampMap = new Map<Source, TimestampedData<CompilationUnit>>();
+    //
+    // Get all of the (fully resolved) compilation units that will be analyzed.
+    //
     Source unitSource = libraryElement.definingCompilationUnit.source;
     TimestampedData<CompilationUnit> resolvedUnit = getCompilationUnit(unitSource);
     timestampMap[unitSource] = resolvedUnit;
@@ -7164,8 +7453,14 @@
       }
       compilationUnits[i + 1] = unit;
     }
+    //
+    // Analyze all of the units.
+    //
     HintGenerator hintGenerator = new HintGenerator(compilationUnits, context, errorListener);
     hintGenerator.generateForLibrary();
+    //
+    // Store the results.
+    //
     _hintMap = new Map<Source, TimestampedData<List<AnalysisError>>>();
     for (MapEntry<Source, TimestampedData<CompilationUnit>> entry in getMapEntrySet(timestampMap)) {
       Source source = entry.getKey();
@@ -7231,9 +7526,11 @@
     if (cache == null) {
       return;
     }
+    // Only handle small changes
     if (cache.oldLength > 0 || cache.newLength > 30) {
       return;
     }
+    // Produce an updated token stream
     CharacterReader reader = new CharSequenceReader(new CharSequence(cache.newContents));
     BooleanErrorListener errorListener = new BooleanErrorListener();
     IncrementalScanner scanner = new IncrementalScanner(cache.source, reader, errorListener);
@@ -7241,8 +7538,10 @@
     if (errorListener.errorReported) {
       return;
     }
+    // Produce an updated AST
     IncrementalParser parser = new IncrementalParser(cache.source, scanner.tokenMap, AnalysisErrorListener.NULL_LISTENER);
     _updatedUnit = parser.reparse(cache.resolvedUnit, scanner.leftToken, scanner.rightToken, cache.offset, cache.offset + cache.oldLength);
+    // Update the resolution
     TypeProvider typeProvider = this.typeProvider;
     if (_updatedUnit != null && typeProvider != null) {
       CompilationUnitElement element = _updatedUnit.element;
@@ -7416,18 +7715,22 @@
   void internalPerform() {
     RecordingErrorListener errorListener = new RecordingErrorListener();
     List<Token> token = [null];
-    TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
+    //
+    // Scan the contents of the file.
+    //
+    Source_ContentReceiver receiver = new Source_ContentReceiver_ParseDartTask_internalPerform(this, errorListener, token);
     try {
-      Source_ContentReceiver receiver = new Source_ContentReceiver_11(this, errorListener, token);
-      try {
-        source.getContents(receiver);
-      } on JavaException catch (exception) {
-        _modificationTime = source.modificationStamp;
-        throw new AnalysisException.con3(exception);
-      }
-    } finally {
-      timeCounterScan.stop();
+      source.getContents(receiver);
+    } on JavaException catch (exception) {
+      _modificationTime = source.modificationStamp;
+      throw new AnalysisException.con3(exception);
     }
+    if (token[0] == null) {
+      throw new AnalysisException.con1("Could not get contents for '${source.fullName}'");
+    }
+    //
+    // Then parse the token stream.
+    //
     TimeCounter_TimeCounterHandle timeCounterParse = PerformanceStatistics.parse.start();
     try {
       Parser parser = new Parser(source, errorListener);
@@ -7436,19 +7739,19 @@
       _errors = errorListener.getErrors2(source);
       for (Directive directive in _unit.directives) {
         if (directive is ExportDirective) {
-          Source exportSource = resolveSource(source, directive as ExportDirective);
+          Source exportSource = resolveSource(source, directive);
           if (exportSource != null) {
             _exportedSources.add(exportSource);
           }
         } else if (directive is ImportDirective) {
-          Source importSource = resolveSource(source, directive as ImportDirective);
+          Source importSource = resolveSource(source, directive);
           if (importSource != null) {
             _importedSources.add(importSource);
           }
         } else if (directive is LibraryDirective) {
           _hasLibraryDirective2 = true;
         } else if (directive is PartDirective) {
-          Source partSource = resolveSource(source, directive as PartDirective);
+          Source partSource = resolveSource(source, directive);
           if (partSource != null) {
             _includedSources.add(partSource);
           }
@@ -7503,14 +7806,14 @@
   }
 }
 
-class Source_ContentReceiver_11 implements Source_ContentReceiver {
+class Source_ContentReceiver_ParseDartTask_internalPerform implements Source_ContentReceiver {
   final ParseDartTask ParseDartTask_this;
 
   RecordingErrorListener errorListener;
 
   List<Token> token;
 
-  Source_ContentReceiver_11(this.ParseDartTask_this, this.errorListener, this.token);
+  Source_ContentReceiver_ParseDartTask_internalPerform(this.ParseDartTask_this, this.errorListener, this.token);
 
   void accept(CharBuffer contents, int modificationTime) {
     doScan(contents, modificationTime);
@@ -7522,10 +7825,15 @@
 
   void doScan(CharSequence contents, int modificationTime) {
     ParseDartTask_this._modificationTime = modificationTime;
-    Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceReader(contents), errorListener);
-    scanner.preserveComments = ParseDartTask_this.context.analysisOptions.preserveComments;
-    token[0] = scanner.tokenize();
-    ParseDartTask_this._lineInfo = new LineInfo(scanner.lineStarts);
+    TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
+    try {
+      Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceReader(contents), errorListener);
+      scanner.preserveComments = ParseDartTask_this.context.analysisOptions.preserveComments;
+      token[0] = scanner.tokenize();
+      ParseDartTask_this._lineInfo = new LineInfo(scanner.lineStarts);
+    } finally {
+      timeCounterScan.stop();
+    }
   }
 }
 
@@ -7663,7 +7971,7 @@
    */
   List<Source> get librarySources {
     List<Source> libraries = new List<Source>();
-    _unit.accept(new RecursiveXmlVisitor_12(this, libraries));
+    _unit.accept(new RecursiveXmlVisitor_ParseHtmlTask_getLibrarySources(this, libraries));
     if (libraries.isEmpty) {
       return Source.EMPTY_ARRAY;
     }
@@ -7671,17 +7979,17 @@
   }
 }
 
-class RecursiveXmlVisitor_12 extends RecursiveXmlVisitor<Object> {
+class RecursiveXmlVisitor_ParseHtmlTask_getLibrarySources extends RecursiveXmlVisitor<Object> {
   final ParseHtmlTask ParseHtmlTask_this;
 
   List<Source> libraries;
 
-  RecursiveXmlVisitor_12(this.ParseHtmlTask_this, this.libraries) : super();
+  RecursiveXmlVisitor_ParseHtmlTask_getLibrarySources(this.ParseHtmlTask_this, this.libraries) : super();
 
   Object visitHtmlScriptTagNode(HtmlScriptTagNode node) {
     XmlAttributeNode scriptAttribute = null;
     for (XmlAttributeNode attribute in node.attributes) {
-      if (javaStringEqualsIgnoreCase(attribute.name.lexeme, ParseHtmlTask._ATTRIBUTE_SRC)) {
+      if (javaStringEqualsIgnoreCase(attribute.name, ParseHtmlTask._ATTRIBUTE_SRC)) {
         scriptAttribute = attribute;
       }
     }
@@ -7826,18 +8134,31 @@
     if (unit == null) {
       throw new AnalysisException.con1("Internal error: computeResolvableCompilationUnit returned a value without a parsed Dart unit");
     }
+    //
+    // Resolve names in declarations.
+    //
     new DeclarationResolver().resolve(unit, find(_libraryElement, source));
+    //
+    // Resolve the type names.
+    //
     RecordingErrorListener errorListener = new RecordingErrorListener();
     TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor.con2(_libraryElement, source, typeProvider, errorListener);
     unit.accept(typeResolverVisitor);
+    //
+    // Resolve the rest of the structure
+    //
     InheritanceManager inheritanceManager = new InheritanceManager(_libraryElement);
     ResolverVisitor resolverVisitor = new ResolverVisitor.con2(_libraryElement, source, typeProvider, inheritanceManager, errorListener);
     unit.accept(resolverVisitor);
+    // TODO (jwren) Move this logic/ loop into the ResolverVisitor and then make the reportError protected again.
     for (ProxyConditionalAnalysisError conditionalCode in resolverVisitor.proxyConditionalAnalysisErrors) {
       if (conditionalCode.shouldIncludeErrorCode()) {
         resolverVisitor.reportError(conditionalCode.analysisError);
       }
     }
+    //
+    // Perform additional error checking.
+    //
     TimeCounter_TimeCounterHandle counterHandleErrors = PerformanceStatistics.errors.start();
     try {
       ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
@@ -7848,6 +8169,9 @@
     } finally {
       counterHandleErrors.stop();
     }
+    //
+    // Capture the results.
+    //
     _resolvedUnit = unit;
   }
 
@@ -7889,6 +8213,11 @@
   int _modificationTime = -1;
 
   /**
+   * The [HtmlUnit] that was resolved by this task.
+   */
+  HtmlUnit _resolvedUnit;
+
+  /**
    * The element produced by resolving the source.
    */
   HtmlElement _element = null;
@@ -7920,6 +8249,13 @@
 
   List<AnalysisError> get resolutionErrors => _resolutionErrors;
 
+  /**
+   * Return the [HtmlUnit] that was resolved by this task.
+   *
+   * @return the [HtmlUnit] that was resolved by this task
+   */
+  HtmlUnit get resolvedUnit => _resolvedUnit;
+
   String get taskDescription {
     if (source == null) {
       return "resolve as html null source";
@@ -7934,9 +8270,16 @@
       throw new AnalysisException.con1("Internal error: computeResolvableHtmlUnit returned a value without a parsed HTML unit");
     }
     _modificationTime = resolvableHtmlUnit.modificationTime;
+    // build standard HTML element
     HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
     _element = builder.buildHtmlElement2(source, _modificationTime, unit);
+    // resolve toolkit-specific features
+    LineInfo lineInfo = context.getLineInfo(source);
+//    new AngularHtmlUnitResolver(context, builder.errorListener, source, lineInfo).resolve(unit);
+    // record all resolution errors
     _resolutionErrors = builder.errorListener.getErrors2(source);
+    // remember resolved unit
+    _resolvedUnit = unit;
   }
 }
 
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 0b80972..e9cce74 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -134,6 +138,86 @@
 }
 
 /**
+ * The enumeration `AngularCode` defines Angular specific problems.
+ */
+class AngularCode extends Enum<AngularCode> implements ErrorCode {
+  static final AngularCode CANNOT_PARSE_SELECTOR = new AngularCode.con1('CANNOT_PARSE_SELECTOR', 0, "The selector '%s' cannot be parsed");
+
+  static final AngularCode EXPECTED_IDENTIFIER = new AngularCode.con1('EXPECTED_IDENTIFIER', 1, "Expected an identifier");
+
+  static final AngularCode EXPECTED_IN = new AngularCode.con1('EXPECTED_IN', 2, "Expected 'in' keyword");
+
+  static final AngularCode INVALID_PROPERTY_KIND = new AngularCode.con1('INVALID_PROPERTY_KIND', 3, "Unknown property binding kind '%s', use one of the '@', '=>', '=>!' or '<=>'");
+
+  static final AngularCode INVALID_PROPERTY_FIELD = new AngularCode.con1('INVALID_PROPERTY_FIELD', 4, "Unknown property field '%s'");
+
+  static final AngularCode INVALID_PROPERTY_MAP = new AngularCode.con1('INVALID_PROPERTY_MAP', 5, "Argument 'map' must be a constant map literal");
+
+  static final AngularCode INVALID_PROPERTY_NAME = new AngularCode.con1('INVALID_PROPERTY_NAME', 6, "Property name must be a string literal");
+
+  static final AngularCode INVALID_PROPERTY_SPEC = new AngularCode.con1('INVALID_PROPERTY_SPEC', 7, "Property binding specification must be a string literal");
+
+  static final AngularCode MISSING_CSS_URL = new AngularCode.con1('MISSING_CSS_URL', 8, "Argument 'cssUrl' must be provided");
+
+  static final AngularCode MISSING_NAME = new AngularCode.con1('MISSING_NAME', 9, "Argument 'name' must be provided");
+
+  static final AngularCode MISSING_PUBLISH_AS = new AngularCode.con1('MISSING_PUBLISH_AS', 10, "Argument 'publishAs' must be provided");
+
+  static final AngularCode MISSING_TEMPLATE_URL = new AngularCode.con1('MISSING_TEMPLATE_URL', 11, "Argument 'templateUrl' must be provided");
+
+  static final AngularCode MISSING_SELECTOR = new AngularCode.con1('MISSING_SELECTOR', 12, "Argument 'selector' must be provided");
+
+  static final List<AngularCode> values = [
+      CANNOT_PARSE_SELECTOR,
+      EXPECTED_IDENTIFIER,
+      EXPECTED_IN,
+      INVALID_PROPERTY_KIND,
+      INVALID_PROPERTY_FIELD,
+      INVALID_PROPERTY_MAP,
+      INVALID_PROPERTY_NAME,
+      INVALID_PROPERTY_SPEC,
+      MISSING_CSS_URL,
+      MISSING_NAME,
+      MISSING_PUBLISH_AS,
+      MISSING_TEMPLATE_URL,
+      MISSING_SELECTOR];
+
+  /**
+   * The template used to create the message to be displayed for this error.
+   */
+  final String message;
+
+  /**
+   * The template used to create the correction to be displayed for this error, or `null` if
+   * there is no correction information for this error.
+   */
+  String correction2;
+
+  /**
+   * Initialize a newly created error code to have the given message.
+   *
+   * @param message the message template used to create the message to be displayed for the error
+   */
+  AngularCode.con1(String name, int ordinal, this.message) : super(name, ordinal);
+
+  /**
+   * Initialize a newly created error code to have the given message and correction.
+   *
+   * @param message the template used to create the message to be displayed for the error
+   * @param correction the template used to create the correction to be displayed for the error
+   */
+  AngularCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
+    this.correction2 = correction;
+  }
+
+  String get correction => correction2;
+
+  ErrorSeverity get errorSeverity => ErrorType.TOOLKIT.severity;
+
+  ErrorType get type => ErrorType.TOOLKIT;
+}
+
+/**
  * Instances of the class `ErrorReporter` wrap an error listener with utility methods used to
  * create the errors being reported.
  *
@@ -197,8 +281,8 @@
    * @param node the node specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError2(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
-    reportError4(errorCode, node.offset, node.length, arguments);
+  void reportError3(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
+    reportError5(errorCode, node.offset, node.length, arguments);
   }
 
   /**
@@ -208,8 +292,8 @@
    * @param element the element which name should be used as the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError3(ErrorCode errorCode, Element element, List<Object> arguments) {
-    reportError4(errorCode, element.nameOffset, element.displayName.length, arguments);
+  void reportError4(ErrorCode errorCode, Element element, List<Object> arguments) {
+    reportError5(errorCode, element.nameOffset, element.displayName.length, arguments);
   }
 
   /**
@@ -220,7 +304,7 @@
    * @param length the length of the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError4(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
+  void reportError5(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(_source, offset, length, errorCode, arguments));
   }
 
@@ -231,8 +315,8 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError5(ErrorCode errorCode, Token token, List<Object> arguments) {
-    reportError4(errorCode, token.offset, token.length, arguments);
+  void reportError6(ErrorCode errorCode, Token token, List<Object> arguments) {
+    reportError5(errorCode, token.offset, token.length, arguments);
   }
 
   /**
@@ -356,10 +440,12 @@
     if (identical(obj, this)) {
       return true;
     }
+    // prepare other AnalysisError
     if (obj is! AnalysisError) {
       return false;
     }
     AnalysisError other = obj as AnalysisError;
+    // Quick checks.
     if (errorCode != other.errorCode) {
       return false;
     }
@@ -369,12 +455,14 @@
     if (isStaticOnly != other.isStaticOnly) {
       return false;
     }
+    // Deep checks.
     if (_message != other._message) {
       return false;
     }
     if (source != other.source) {
       return false;
     }
+    // OK
     return true;
   }
 
@@ -434,6 +522,7 @@
     builder.append("..");
     builder.append(_offset + _length - 1);
     builder.append("): ");
+    //builder.append("(" + lineNumber + ":" + columnNumber + "): ");
     builder.append(_message);
     return builder.toString();
   }
@@ -556,6 +645,15 @@
   static final HintCode IS_NOT_INT = new HintCode.con1('IS_NOT_INT', 9, "When compiled to JS, this test might return false when the left hand side is a double");
 
   /**
+   * Generate a hint for methods or functions that have a return type, but do not have a non-void
+   * return statement on all branches. At the end of methods or functions with no return, Dart
+   * implicitly returns `null`, avoiding these implicit returns is considered a best practice.
+   *
+   * @param returnType the name of the declared return type
+   */
+  static final HintCode MISSING_RETURN = new HintCode.con2('MISSING_RETURN', 10, "This function declares a return type of '%s', but does not end with a return statement.", "Either add a return statement or change the return type to 'void'.");
+
+  /**
    * It is not in best practice to declare a private method that happens to override the method in a
    * superclass- depending on where the superclass is (either in the same library, or out of the
    * same library), behavior can be different.
@@ -564,24 +662,24 @@
    * @param memberName some private member name
    * @param className the class name where the member is overriding the functionality
    */
-  static final HintCode OVERRIDDING_PRIVATE_MEMBER = new HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 10, "The %s '%s' does not override the definition from '%s' because it is private and in a different library");
+  static final HintCode OVERRIDDING_PRIVATE_MEMBER = new HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 11, "The %s '%s' does not override the definition from '%s' because it is private and in a different library");
 
   /**
    * Hint for classes that override equals, but not hashCode.
    *
    * @param className the name of the current class
    */
-  static final HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = new HintCode.con1('OVERRIDE_EQUALS_BUT_NOT_HASH_CODE', 11, "The class '%s' overrides 'operator==', but not 'get hashCode'");
+  static final HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = new HintCode.con1('OVERRIDE_EQUALS_BUT_NOT_HASH_CODE', 12, "The class '%s' overrides 'operator==', but not 'get hashCode'");
 
   /**
    * Type checks of the type `x is! Null` should be done with `x != null`.
    */
-  static final HintCode TYPE_CHECK_IS_NOT_NULL = new HintCode.con1('TYPE_CHECK_IS_NOT_NULL', 12, "Tests for non-null should be done with '!= null'");
+  static final HintCode TYPE_CHECK_IS_NOT_NULL = new HintCode.con1('TYPE_CHECK_IS_NOT_NULL', 13, "Tests for non-null should be done with '!= null'");
 
   /**
    * Type checks of the type `x is Null` should be done with `x == null`.
    */
-  static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 13, "Tests for null should be done with '== null'");
+  static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 14, "Tests for null should be done with '== null'");
 
   /**
    * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_GETTER] or
@@ -593,7 +691,7 @@
    * @see StaticTypeWarningCode#UNDEFINED_GETTER
    * @see StaticWarningCode#UNDEFINED_GETTER
    */
-  static final HintCode UNDEFINED_GETTER = new HintCode.con1('UNDEFINED_GETTER', 14, StaticTypeWarningCode.UNDEFINED_GETTER.message);
+  static final HintCode UNDEFINED_GETTER = new HintCode.con1('UNDEFINED_GETTER', 15, StaticTypeWarningCode.UNDEFINED_GETTER.message);
 
   /**
    * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_METHOD] would
@@ -603,7 +701,7 @@
    * @param typeName the resolved type name that the method lookup is happening on
    * @see StaticTypeWarningCode#UNDEFINED_METHOD
    */
-  static final HintCode UNDEFINED_METHOD = new HintCode.con1('UNDEFINED_METHOD', 15, StaticTypeWarningCode.UNDEFINED_METHOD.message);
+  static final HintCode UNDEFINED_METHOD = new HintCode.con1('UNDEFINED_METHOD', 16, StaticTypeWarningCode.UNDEFINED_METHOD.message);
 
   /**
    * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_OPERATOR]
@@ -613,7 +711,7 @@
    * @param enclosingType the name of the enclosing type where the operator is being looked for
    * @see StaticTypeWarningCode#UNDEFINED_OPERATOR
    */
-  static final HintCode UNDEFINED_OPERATOR = new HintCode.con1('UNDEFINED_OPERATOR', 16, StaticTypeWarningCode.UNDEFINED_OPERATOR.message);
+  static final HintCode UNDEFINED_OPERATOR = new HintCode.con1('UNDEFINED_OPERATOR', 17, StaticTypeWarningCode.UNDEFINED_OPERATOR.message);
 
   /**
    * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_SETTER] or
@@ -625,27 +723,27 @@
    * @see StaticTypeWarningCode#UNDEFINED_SETTER
    * @see StaticWarningCode#UNDEFINED_SETTER
    */
-  static final HintCode UNDEFINED_SETTER = new HintCode.con1('UNDEFINED_SETTER', 17, StaticTypeWarningCode.UNDEFINED_SETTER.message);
+  static final HintCode UNDEFINED_SETTER = new HintCode.con1('UNDEFINED_SETTER', 18, StaticTypeWarningCode.UNDEFINED_SETTER.message);
 
   /**
    * Unnecessary cast.
    */
-  static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 18, "Unnecessary cast");
+  static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 19, "Unnecessary cast");
 
   /**
    * Unnecessary type checks, the result is always true.
    */
-  static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 19, "Unnecessary type check, the result is always false");
+  static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 20, "Unnecessary type check, the result is always false");
 
   /**
    * Unnecessary type checks, the result is always false.
    */
-  static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 20, "Unnecessary type check, the result is always true");
+  static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 21, "Unnecessary type check, the result is always true");
 
   /**
    * Unused imports are imports which are never not used.
    */
-  static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 21, "Unused import");
+  static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 22, "Unused import");
 
   static final List<HintCode> values = [
       DEAD_CODE,
@@ -658,6 +756,7 @@
       IS_INT,
       IS_NOT_DOUBLE,
       IS_NOT_INT,
+      MISSING_RETURN,
       OVERRIDDING_PRIVATE_MEMBER,
       OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
       TYPE_CHECK_IS_NOT_NULL,
@@ -680,7 +779,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction3;
+  String correction4;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -696,10 +795,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   HintCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction3 = correction;
+    this.correction4 = correction;
   }
 
-  String get correction => correction3;
+  String get correction => correction4;
 
   ErrorSeverity get errorSeverity => ErrorType.HINT.severity;
 
@@ -795,6 +894,11 @@
    */
   static final ErrorType SYNTACTIC_ERROR = new ErrorType('SYNTACTIC_ERROR', 6, ErrorSeverity.ERROR);
 
+  /**
+   * Toolkit specific semantic problems.
+   */
+  static final ErrorType TOOLKIT = new ErrorType('TOOLKIT', 7, ErrorSeverity.INFO);
+
   static final List<ErrorType> values = [
       TODO,
       HINT,
@@ -802,7 +906,8 @@
       PUB_SUGGESTION,
       STATIC_WARNING,
       STATIC_TYPE_WARNING,
-      SYNTACTIC_ERROR];
+      SYNTACTIC_ERROR,
+      TOOLKIT];
 
   /**
    * The severity of this type of error.
@@ -2144,7 +2249,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction2;
+  String correction3;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -2160,10 +2265,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   CompileTimeErrorCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction2 = correction;
+    this.correction3 = correction;
   }
 
-  String get correction => correction2;
+  String get correction => correction3;
 
   ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
 
@@ -2214,7 +2319,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction5;
+  String correction6;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -2230,10 +2335,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   PubSuggestionCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction5 = correction;
+    this.correction6 = correction;
   }
 
-  String get correction => correction5;
+  String get correction => correction6;
 
   ErrorSeverity get errorSeverity => ErrorType.PUB_SUGGESTION.severity;
 
@@ -3104,7 +3209,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction7;
+  String correction8;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -3120,10 +3225,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   StaticWarningCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction7 = correction;
+    this.correction8 = correction;
   }
 
-  String get correction => correction7;
+  String get correction => correction8;
 
   ErrorSeverity get errorSeverity => ErrorType.STATIC_WARNING.severity;
 
@@ -3140,7 +3245,7 @@
   /**
    * An error listener that ignores errors that are reported to it.
    */
-  static final AnalysisErrorListener NULL_LISTENER = new AnalysisErrorListener_6();
+  static final AnalysisErrorListener NULL_LISTENER = new AnalysisErrorListener_NULL_LISTENER();
 
   /**
    * This method is invoked when an error has been found by the analysis engine.
@@ -3150,7 +3255,7 @@
   void onError(AnalysisError error);
 }
 
-class AnalysisErrorListener_6 implements AnalysisErrorListener {
+class AnalysisErrorListener_NULL_LISTENER implements AnalysisErrorListener {
   void onError(AnalysisError event) {
   }
 }
@@ -3191,7 +3296,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction4;
+  String correction5;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -3207,10 +3312,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   HtmlWarningCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction4 = correction;
+    this.correction5 = correction;
   }
 
-  String get correction => correction4;
+  String get correction => correction5;
 
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
 
@@ -3518,7 +3623,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction6;
+  String correction7;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -3534,10 +3639,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   StaticTypeWarningCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction6 = correction;
+    this.correction7 = correction;
   }
 
-  String get correction => correction6;
+  String get correction => correction7;
 
   ErrorSeverity get errorSeverity => ErrorType.STATIC_TYPE_WARNING.severity;
 
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
index d373bbc..3d1f303 100644
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ b/pkg/analyzer/lib/src/generated/html.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -10,8 +14,8 @@
 import 'error.dart' show AnalysisErrorListener;
 import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token;
 import 'parser.dart' show Parser;
-import 'ast.dart' show ASTVisitor, CompilationUnit, Expression;
-import 'element.dart' show HtmlElementImpl, HtmlScriptElement;
+import 'ast.dart';
+import 'element.dart';
 import 'engine.dart' show AnalysisEngine;
 
 /**
@@ -195,32 +199,6 @@
 }
 
 /**
- * Instances of the class `TagWithEmbeddedExpressions` represent a tag whose text content
- * contains one or more embedded expressions.
- */
-class TagWithEmbeddedExpressions extends XmlTagNode {
-  /**
-   * The expressions that are embedded in the tag's content.
-   */
-  final List<EmbeddedExpression> expressions;
-
-  /**
-   * Initialize a newly created tag whose text content contains one or more embedded expressions.
-   *
-   * @param nodeStart the token marking the beginning of the tag
-   * @param tag the name of the tag
-   * @param attributes the attributes in the tag
-   * @param attributeEnd the token terminating the region where attributes can be
-   * @param tagNodes the children of the tag
-   * @param contentEnd the token that starts the closing tag
-   * @param closingTag the name of the tag that occurs in the closing tag
-   * @param nodeEnd the last token in the tag
-   * @param expressions the expressions that are embedded in the value
-   */
-  TagWithEmbeddedExpressions(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd, this.expressions) : super(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
-}
-
-/**
  * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively
  * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
  * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and
@@ -255,6 +233,193 @@
 }
 
 /**
+ * Utilities locating [Expression]s and [Element]s in [HtmlUnit].
+ */
+class HtmlUnitUtils {
+  /**
+   * Returns the [XmlAttributeNode] that is part of the given [HtmlUnit] and encloses
+   * the given offset.
+   */
+  static XmlAttributeNode getAttributeNode(HtmlUnit htmlUnit, int offset) {
+    if (htmlUnit == null) {
+      return null;
+    }
+    List<XmlAttributeNode> result = [null];
+    try {
+      htmlUnit.accept(new RecursiveXmlVisitor_HtmlUnitUtils_getAttributeNode(offset, result));
+    } on HtmlUnitUtils_FoundAttributeNodeError catch (e) {
+      return result[0];
+    }
+    return null;
+  }
+
+  /**
+   * Returns the best [Element] of the given [Expression].
+   */
+  static Element getElement(Expression expression) {
+    if (expression == null) {
+      return null;
+    }
+    return ElementLocator.locate(expression);
+  }
+
+  /**
+   * Returns the [Element] of the [Expression] in the given [HtmlUnit], enclosing
+   * the given offset.
+   */
+  static Element getElement2(HtmlUnit htmlUnit, int offset) {
+    Expression expression = getExpression(htmlUnit, offset);
+    return getElement(expression);
+  }
+
+  /**
+   * Returns the [Element] to open when requested at the given [Expression].
+   */
+  static Element getElementToOpen(HtmlUnit htmlUnit, Expression expression) {
+    Element element = getElement(expression);
+    // special cases for Angular
+    if (isAngular(htmlUnit)) {
+      // replace artificial controller variable Element with controller ClassElement
+      if (element is VariableElement) {
+        VariableElement variable = element as VariableElement;
+        Type2 type = variable.type;
+        if (variable.nameOffset == 0 && type is InterfaceType) {
+          element = type.element;
+        }
+      }
+    }
+    // done
+    return element;
+  }
+
+  /**
+   * Returns the [Expression] that is part of the given [HtmlUnit] and encloses the
+   * given offset.
+   */
+  static Expression getExpression(HtmlUnit htmlUnit, int offset) {
+    if (htmlUnit == null) {
+      return null;
+    }
+    List<Expression> result = [null];
+    try {
+      htmlUnit.accept(new RecursiveXmlVisitor_HtmlUnitUtils_getExpression(offset, result));
+    } on HtmlUnitUtils_FoundExpressionError catch (e) {
+      return result[0];
+    }
+    return null;
+  }
+
+  /**
+   * Returns the [XmlTagNode] that is part of the given [HtmlUnit] and encloses the
+   * given offset.
+   */
+  static XmlTagNode getTagNode(HtmlUnit htmlUnit, int offset) {
+    if (htmlUnit == null) {
+      return null;
+    }
+    List<XmlTagNode> result = [null];
+    try {
+      htmlUnit.accept(new RecursiveXmlVisitor_HtmlUnitUtils_getTagNode(offset, result));
+    } on HtmlUnitUtils_FoundTagNodeError catch (e) {
+      return result[0];
+    }
+    return null;
+  }
+
+  /**
+   * Returns `true` if the given [HtmlUnit] has Angular annotation.
+   */
+  static bool isAngular(HtmlUnit htmlUnit) => false; // AngularHtmlUnitResolver.hasAngularAnnotation(htmlUnit);
+
+  /**
+   * Returns the [Expression] that is part of the given root [ASTNode] and encloses the
+   * given offset.
+   */
+  static Expression getExpressionAt(ASTNode root, int offset) {
+    if (root.offset <= offset && offset < root.end) {
+      ASTNode dartNode = new NodeLocator.con1(offset).searchWithin(root);
+      if (dartNode is Expression) {
+        return dartNode;
+      }
+    }
+    return null;
+  }
+}
+
+class HtmlUnitUtils_FoundAttributeNodeError extends Error {
+}
+
+class HtmlUnitUtils_FoundExpressionError extends Error {
+}
+
+class HtmlUnitUtils_FoundTagNodeError extends Error {
+}
+
+class RecursiveXmlVisitor_HtmlUnitUtils_getAttributeNode extends RecursiveXmlVisitor<Object> {
+  int offset = 0;
+
+  List<XmlAttributeNode> result;
+
+  RecursiveXmlVisitor_HtmlUnitUtils_getAttributeNode(this.offset, this.result) : super();
+
+  Object visitXmlAttributeNode(XmlAttributeNode node) {
+    Token nameToken = node.nameToken;
+    if (nameToken.offset <= offset && offset < nameToken.end) {
+      result[0] = node;
+      throw new HtmlUnitUtils_FoundAttributeNodeError();
+    }
+    return super.visitXmlAttributeNode(node);
+  }
+}
+
+class RecursiveXmlVisitor_HtmlUnitUtils_getExpression extends RecursiveXmlVisitor<Object> {
+  int offset = 0;
+
+  List<Expression> result;
+
+  RecursiveXmlVisitor_HtmlUnitUtils_getExpression(this.offset, this.result) : super();
+
+  Object visitXmlAttributeNode(XmlAttributeNode node) {
+    findExpression(offset, result, node.expressions);
+    return super.visitXmlAttributeNode(node);
+  }
+
+  Object visitXmlTagNode(XmlTagNode node) {
+    findExpression(offset, result, node.expressions);
+    return super.visitXmlTagNode(node);
+  }
+
+  void findExpression(int offset, List<Expression> result, List<EmbeddedExpression> expressions) {
+    for (EmbeddedExpression embeddedExpression in expressions) {
+      Expression expression = embeddedExpression.expression;
+      Expression at = HtmlUnitUtils.getExpressionAt(expression, offset);
+      if (at != null) {
+        result[0] = at;
+        throw new HtmlUnitUtils_FoundExpressionError();
+      }
+    }
+  }
+}
+
+class RecursiveXmlVisitor_HtmlUnitUtils_getTagNode extends RecursiveXmlVisitor<Object> {
+  int offset = 0;
+
+  List<XmlTagNode> result;
+
+  RecursiveXmlVisitor_HtmlUnitUtils_getTagNode(this.offset, this.result) : super();
+
+  Object visitXmlTagNode(XmlTagNode node) {
+    super.visitXmlTagNode(node);
+    Token tagToken = node.tagToken;
+    if (tagToken.offset <= offset && offset < tagToken.end) {
+      result[0] = node;
+      throw new HtmlUnitUtils_FoundTagNodeError();
+    }
+    return null;
+  }
+}
+
+/**
  * Instances of the class `HtmlScriptTagNode` represent a script tag within an HTML file that
  * references a Dart script.
  */
@@ -316,6 +481,11 @@
   XmlNode _parent;
 
   /**
+   * The element associated with this node or `null` if the receiver is not resolved.
+   */
+  Element _element;
+
+  /**
    * Use the given visitor to visit this node.
    *
    * @param visitor the visitor that will visit this node
@@ -331,6 +501,13 @@
   Token get beginToken;
 
   /**
+   * Return the element associated with this node.
+   *
+   * @return the element or `null` if the receiver is not resolved
+   */
+  Element get element => _element;
+
+  /**
    * Return the offset of the character immediately following the last character of this node's
    * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
    * unit this will be equal to the length of the unit's source.
@@ -385,6 +562,15 @@
    */
   XmlNode get parent => _parent;
 
+  /**
+   * Set the element associated with this node.
+   *
+   * @param element the element
+   */
+  void set element(Element element) {
+    this._element = element;
+  }
+
   String toString() {
     PrintStringWriter writer = new PrintStringWriter();
     accept(new ToSourceVisitor(writer));
@@ -411,6 +597,7 @@
         XmlNode node = iter.next();
         node.parent = this;
       }
+      // This will create ArrayList for exactly given number of elements.
       return new List.from(children);
     }
     return children;
@@ -435,9 +622,9 @@
    */
   void appendIdentifier(JavaStringBuilder builder, XmlNode node) {
     if (node is XmlTagNode) {
-      builder.append((node as XmlTagNode).tag.lexeme);
+      builder.append(node.tag);
     } else if (node is XmlAttributeNode) {
-      builder.append((node as XmlAttributeNode).name.lexeme);
+      builder.append(node.name);
     } else {
       builder.append("htmlUnit");
     }
@@ -485,27 +672,6 @@
 }
 
 /**
- * Instances of the class `AttributeWithEmbeddedExpressions` represent an attribute whose
- * value contains one or more embedded expressions.
- */
-class AttributeWithEmbeddedExpressions extends XmlAttributeNode {
-  /**
-   * The expressions that are embedded in the attribute's value.
-   */
-  final List<EmbeddedExpression> expressions;
-
-  /**
-   * Initialize a newly created attribute whose value contains one or more embedded expressions.
-   *
-   * @param name the name of the attribute
-   * @param equals the equals sign separating the name from the value
-   * @param value the value of the attribute
-   * @param expressions the expressions that are embedded in the value
-   */
-  AttributeWithEmbeddedExpressions(Token name, Token equals, Token value, this.expressions) : super(name, equals, value);
-}
-
-/**
  * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing
  * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
  * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
@@ -636,6 +802,7 @@
 
   void appendEofToken() {
     Token eofToken = new Token.con1(TokenType.EOF, offset);
+    // The EOF token points to itself so that there is always infinite look-ahead.
     eofToken.setNext(eofToken);
     _tail = _tail.setNext(eofToken);
   }
@@ -679,6 +846,7 @@
         if (c == 0x21) {
           c = advance();
           if (c == 0x2D && peek() == 0x2D) {
+            // handle a comment
             c = advance();
             int dashCount = 1;
             while (c >= 0) {
@@ -693,9 +861,11 @@
               c = recordStartOfLineAndAdvance(c);
             }
             emit3(TokenType.COMMENT, start, -1);
+            // Capture <!--> and <!---> as tokens but report an error
             if (_tail.length < 7) {
             }
           } else {
+            // handle a declaration
             while (c >= 0) {
               if (c == 0x3E) {
                 c = advance();
@@ -708,6 +878,7 @@
             }
           }
         } else if (c == 0x3F) {
+          // handle a directive
           while (c >= 0) {
             if (c == 0x3F) {
               c = advance();
@@ -729,9 +900,11 @@
         } else {
           inBrackets = true;
           emit2(TokenType.LT, start);
+          // ignore whitespace in braces
           while (Character.isWhitespace(c)) {
             c = recordStartOfLineAndAdvance(c);
           }
+          // get tag
           if (Character.isLetterOrDigit(c)) {
             int tagStart = offset;
             c = advance();
@@ -739,6 +912,7 @@
               c = advance();
             }
             emit3(TokenType.TAG, tagStart, -1);
+            // check tag against passThrough elements
             String tag = _tail.lexeme;
             for (String str in _passThroughElements) {
               if (str == tag) {
@@ -752,6 +926,7 @@
         emit2(TokenType.GT, start);
         inBrackets = false;
         c = advance();
+        // if passThrough != null, read until we match it
         if (endPassThrough != null) {
           bool endFound = false;
           int len = endPassThrough.length;
@@ -798,6 +973,7 @@
         }
         emit3(TokenType.TEXT, start, -1);
       } else if (c == 0x22 || c == 0x27) {
+        // read a string
         int endQuote = c;
         c = advance();
         while (c >= 0) {
@@ -809,9 +985,11 @@
         }
         emit3(TokenType.STRING, start, -1);
       } else if (c == 0x3D) {
+        // a non-char token
         emit2(TokenType.EQ, start);
         c = advance();
       } else if (Character.isWhitespace(c)) {
+        // ignore whitespace in braces
         do {
           c = recordStartOfLineAndAdvance(c);
         } while (Character.isWhitespace(c));
@@ -822,6 +1000,7 @@
         }
         emit3(TokenType.TAG, start, -1);
       } else {
+        // a non-char token
         emit3(TokenType.TEXT, start, 0);
         c = advance();
       }
@@ -997,8 +1176,8 @@
   }
 
   Object visitXmlAttributeNode(XmlAttributeNode node) {
-    String name = node.name.lexeme;
-    Token value = node.value;
+    String name = node.name;
+    Token value = node.valueToken;
     if (name.length == 0) {
       _writer.print("__");
     } else {
@@ -1015,7 +1194,7 @@
 
   Object visitXmlTagNode(XmlTagNode node) {
     _writer.print("<");
-    String tagName = node.tag.lexeme;
+    String tagName = node.tag;
     _writer.print(tagName);
     for (XmlAttributeNode attribute in node.attributes) {
       _writer.print(" ");
@@ -1114,11 +1293,13 @@
  * @coverage dart.engine.html
  */
 class XmlAttributeNode extends XmlNode {
-  final Token name;
+  Token _name;
 
   final Token equals;
 
-  final Token value;
+  Token _value;
+
+  List<EmbeddedExpression> expressions = EmbeddedExpression.EMPTY_ARRAY;
 
   /**
    * Construct a new instance representing an XML attribute.
@@ -1128,20 +1309,31 @@
    * @param equals the equals sign or `null` if none
    * @param value the value token (not `null`)
    */
-  XmlAttributeNode(this.name, this.equals, this.value);
+  XmlAttributeNode(Token name, this.equals, Token value) {
+    this._name = name;
+    this._value = value;
+  }
 
   accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
 
-  Token get beginToken => name;
+  Token get beginToken => _name;
 
-  Token get endToken => value;
+  Token get endToken => _value;
 
   /**
-   * Return the expressions that are embedded in the attribute's value.
+   * Answer the attribute name. This may be a zero length string if the attribute is badly formed.
    *
-   * @return the expressions that are embedded in the attribute's value
+   * @return the name (not `null`)
    */
-  List<EmbeddedExpression> get expressions => EmbeddedExpression.EMPTY_ARRAY;
+  String get name => _name.lexeme;
+
+  /**
+   * Answer the attribute name token. This may be a zero length token if the attribute is badly
+   * formed.
+   *
+   * @return the name token (not `null`)
+   */
+  Token get nameToken => _name;
 
   /**
    * Answer the lexeme for the value token without the leading and trailing quotes.
@@ -1149,10 +1341,11 @@
    * @return the text or `null` if the value is not specified
    */
   String get text {
-    if (value == null) {
+    if (_value == null) {
       return null;
     }
-    String text = value.lexeme;
+    //TODO (danrubel): replace HTML character encodings with the actual characters
+    String text = _value.lexeme;
     int len = text.length;
     if (len > 0) {
       if (text.codeUnitAt(0) == 0x22) {
@@ -1172,6 +1365,14 @@
     return text;
   }
 
+  /**
+   * Answer the attribute value token. A properly formed value will start and end with matching
+   * quote characters, but the value returned may not be properly formed.
+   *
+   * @return the value token or `null` if this represents a badly formed attribute
+   */
+  Token get valueToken => _value;
+
   void visitChildren(XmlVisitor visitor) {
   }
 }
@@ -1381,6 +1582,7 @@
         if (_currentToken.type == TokenType.LT) {
           tagNodes.add(parseTagNode());
         } else if (_currentToken.type == TokenType.DECLARATION || _currentToken.type == TokenType.DIRECTIVE || _currentToken.type == TokenType.COMMENT) {
+          // ignored tokens
           _currentToken = _currentToken.next;
         } else if (_currentToken.type == TokenType.EOF) {
           return tagNodes;
@@ -1420,8 +1622,10 @@
    * @return the attribute (not `null`)
    */
   XmlAttributeNode parseAttribute() {
+    // Assume the current token is a tag
     Token name = _currentToken;
     _currentToken = _currentToken.next;
+    // Equals sign
     Token equals;
     if (identical(_currentToken.type, TokenType.EQ)) {
       equals = _currentToken;
@@ -1430,6 +1634,7 @@
       reportUnexpectedToken();
       equals = insertSyntheticToken(TokenType.EQ);
     }
+    // String value
     Token value;
     if (identical(_currentToken.type, TokenType.STRING)) {
       value = _currentToken;
@@ -1487,6 +1692,7 @@
         } else if (_currentToken.type == TokenType.LT_SLASH || _currentToken.type == TokenType.EOF) {
           return nodes;
         } else if (_currentToken.type == TokenType.COMMENT) {
+          // ignored token
           _currentToken = _currentToken.next;
         } else {
           reportUnexpectedToken();
@@ -1504,8 +1710,10 @@
    * @return the tag node or `null` if none found
    */
   XmlTagNode parseTagNode() {
+    // Assume that the current node is a tag node start TokenType#LT
     Token nodeStart = _currentToken;
     _currentToken = _currentToken.next;
+    // Get the tag or create a synthetic tag and report an error
     Token tag;
     if (identical(_currentToken.type, TokenType.TAG)) {
       tag = _currentToken;
@@ -1514,7 +1722,9 @@
       reportUnexpectedToken();
       tag = insertSyntheticToken(TokenType.TAG);
     }
+    // Parse the attributes
     List<XmlAttributeNode> attributes = parseAttributes();
+    // Token ending attribute list
     Token attributeEnd;
     if (identical(_currentToken.type, TokenType.GT) || identical(_currentToken.type, TokenType.SLASH_GT)) {
       attributeEnd = _currentToken;
@@ -1523,18 +1733,24 @@
       reportUnexpectedToken();
       attributeEnd = insertSyntheticToken(TokenType.SLASH_GT);
     }
+    // If the node has no children, then return the node
     if (identical(attributeEnd.type, TokenType.SLASH_GT) || isSelfClosing(tag)) {
       return createTagNode(nodeStart, tag, attributes, attributeEnd, XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
     }
+    // Parse the child tag nodes
     List<XmlTagNode> tagNodes = parseChildTagNodes();
+    // Token ending child tag nodes
     Token contentEnd;
     if (identical(_currentToken.type, TokenType.LT_SLASH)) {
       contentEnd = _currentToken;
       _currentToken = _currentToken.next;
     } else {
+      // TODO (danrubel): handle self closing HTML elements by inserting synthetic tokens
+      // but not reporting an error
       reportUnexpectedToken();
       contentEnd = insertSyntheticToken(TokenType.LT_SLASH);
     }
+    // Closing tag
     Token closingTag;
     if (identical(_currentToken.type, TokenType.TAG)) {
       closingTag = _currentToken;
@@ -1543,6 +1759,7 @@
       reportUnexpectedToken();
       closingTag = insertSyntheticToken(TokenType.TAG);
     }
+    // Token ending node
     Token nodeEnd;
     if (identical(_currentToken.type, TokenType.GT)) {
       nodeEnd = _currentToken;
@@ -1586,7 +1803,7 @@
   /**
    * The [TokenType#TAG] token after the starting '&lt;' (not `null`).
    */
-  final Token tag;
+  Token _tag;
 
   /**
    * The attributes contained by the receiver (not `null`, contains no `null`s).
@@ -1630,6 +1847,11 @@
   final Token nodeEnd;
 
   /**
+   * The expressions that are embedded in the tag's content.
+   */
+  List<EmbeddedExpression> expressions = EmbeddedExpression.EMPTY_ARRAY;
+
+  /**
    * Construct a new instance representing an XML or HTML element
    *
    * @param nodeStart the starting [TokenType#LT] token (not `null`)
@@ -1655,7 +1877,8 @@
    * @param nodeEnd the ending [TokenType#GT] or [TokenType#SLASH_GT] token (not
    *          `null`)
    */
-  XmlTagNode(this.nodeStart, this.tag, List<XmlAttributeNode> attributes, this.attributeEnd, List<XmlTagNode> tagNodes, this.contentEnd, this.closingTag, this.nodeEnd) {
+  XmlTagNode(this.nodeStart, Token tag, List<XmlAttributeNode> attributes, this.attributeEnd, List<XmlTagNode> tagNodes, this.contentEnd, this.closingTag, this.nodeEnd) {
+    this._tag = tag;
     this._attributes = becomeParentOfEmpty(attributes, NO_ATTRIBUTES);
     this._tagNodes = becomeParentOfEmpty(tagNodes, NO_TAG_NODES);
   }
@@ -1670,7 +1893,7 @@
    */
   XmlAttributeNode getAttribute(String name) {
     for (XmlAttributeNode attribute in _attributes) {
-      if (attribute.name.lexeme == name) {
+      if (attribute.name == name) {
         return attribute;
       }
     }
@@ -1712,6 +1935,7 @@
     if (identical(token, contentEnd)) {
       return "";
     }
+    //TODO (danrubel): handle CDATA and replace HTML character encodings with the actual characters
     String content = token.lexeme;
     token = token.next;
     if (identical(token, contentEnd)) {
@@ -1744,15 +1968,15 @@
     if (!_attributes.isEmpty) {
       return _attributes[_attributes.length - 1].endToken;
     }
-    return tag;
+    return _tag;
   }
 
   /**
-   * Return the expressions that are embedded in the tag's content.
+   * Answer the tag name after the starting '&lt;'.
    *
-   * @return the expressions that are embedded in the tag's content
+   * @return the tag name (not `null`)
    */
-  List<EmbeddedExpression> get expressions => EmbeddedExpression.EMPTY_ARRAY;
+  String get tag => _tag.lexeme;
 
   /**
    * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
@@ -1762,6 +1986,13 @@
    */
   List<XmlTagNode> get tagNodes => _tagNodes;
 
+  /**
+   * Answer the [TokenType#TAG] token after the starting '&lt;'.
+   *
+   * @return the token (not `null`)
+   */
+  Token get tagToken => _tag;
+
   void visitChildren(XmlVisitor visitor) {
     for (XmlAttributeNode node in _attributes) {
       node.accept(visitor);
@@ -1803,10 +2034,6 @@
 
   static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
 
-  static String _OPENING_DELIMITER = "{{";
-
-  static String _CLOSING_DELIMITER = "}}";
-
   static String _SCRIPT = "script";
 
   static String _TYPE = "type";
@@ -1817,6 +2044,35 @@
   static Set<String> SELF_CLOSING = new Set<String>();
 
   /**
+   * Given the contents of an embedded expression that occurs at the given offset, parse it as a
+   * Dart expression. The contents should not include the expression's delimiters.
+   *
+   * @param source the source that contains that given token
+   * @param token the token to start parsing from
+   * @return the Dart expression that was parsed
+   */
+  static Expression parseEmbeddedExpression(Source source, sc.Token token, AnalysisErrorListener errorListener) {
+    Parser parser = new Parser(source, errorListener);
+    return parser.parseExpression(token);
+  }
+
+  /**
+   * Given the contents of an embedded expression that occurs at the given offset, scans it as a
+   * Dart code.
+   *
+   * @param source the source of that contains the given contents
+   * @param contents the contents to scan
+   * @param contentOffset the offset of the contents in the larger file
+   * @return the first Dart token
+   */
+  static sc.Token scanDartSource(Source source, LineInfo lineInfo, String contents, int contentOffset, AnalysisErrorListener errorListener) {
+    LineInfo_Location location = lineInfo.getLocation(contentOffset);
+    sc.Scanner scanner = new sc.Scanner(source, new sc.SubSequenceReader(new CharSequence(contents), contentOffset), errorListener);
+    scanner.setSourceStart(location.lineNumber, location.columnNumber);
+    return scanner.tokenize();
+  }
+
+  /**
    * Construct a parser for the specified source.
    *
    * @param source the source being parsed
@@ -1826,28 +2082,6 @@
     this._errorListener = errorListener;
   }
 
-  Token getEndToken(Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd) {
-    if (nodeEnd != null) {
-      return nodeEnd;
-    }
-    if (closingTag != null) {
-      return closingTag;
-    }
-    if (contentEnd != null) {
-      return contentEnd;
-    }
-    if (!tagNodes.isEmpty) {
-      return tagNodes[tagNodes.length - 1].endToken;
-    }
-    if (attributeEnd != null) {
-      return attributeEnd;
-    }
-    if (!attributes.isEmpty) {
-      return attributes[attributes.length - 1].endToken;
-    }
-    return tag;
-  }
-
   /**
    * Parse the tokens specified by the given scan result.
    *
@@ -1875,14 +2109,7 @@
     return parse(scanner.result);
   }
 
-  XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) {
-    List<EmbeddedExpression> expressions = new List<EmbeddedExpression>();
-    addEmbeddedExpressions(expressions, value);
-    if (expressions.isEmpty) {
-      return new XmlAttributeNode(name, equals, value);
-    }
-    return new AttributeWithEmbeddedExpressions(name, equals, value, new List.from(expressions));
-  }
+  XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) => new XmlAttributeNode(name, equals, value);
 
   XmlTagNode createTagNode(Token nodeStart, Token tag, List<XmlAttributeNode> attributes, Token attributeEnd, List<XmlTagNode> tagNodes, Token contentEnd, Token closingTag, Token nodeEnd) {
     if (isScriptNode(tag, attributes, tagNodes)) {
@@ -1899,46 +2126,12 @@
       tagNode.script = unit;
       return tagNode;
     }
-    Token token = nodeStart;
-    Token endToken = getEndToken(tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
-    List<EmbeddedExpression> expressions = new List<EmbeddedExpression>();
-    while (token != endToken) {
-      if (identical(token.type, TokenType.TEXT)) {
-        addEmbeddedExpressions(expressions, token);
-      }
-      token = token.next;
-    }
-    if (expressions.isEmpty) {
-      return super.createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
-    }
-    return new TagWithEmbeddedExpressions(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd, new List.from(expressions));
+    return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
   }
 
   bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
 
   /**
-   * Parse the value of the given token for embedded expressions, and add any embedded expressions
-   * that are found to the given list of expressions.
-   *
-   * @param expressions the list to which embedded expressions are to be added
-   * @param token the token whose value is to be parsed
-   */
-  void addEmbeddedExpressions(List<EmbeddedExpression> expressions, Token token) {
-    String lexeme = token.lexeme;
-    int startIndex = lexeme.indexOf(_OPENING_DELIMITER);
-    while (startIndex >= 0) {
-      int endIndex = JavaString.indexOf(lexeme, _CLOSING_DELIMITER, startIndex + 2);
-      if (endIndex < 0) {
-        return;
-      } else if (startIndex + 2 < endIndex) {
-        int offset = token.offset;
-        expressions.add(new EmbeddedExpression(startIndex, parseEmbeddedExpression(lexeme.substring(startIndex + 2, endIndex), offset + startIndex), endIndex));
-      }
-      startIndex = JavaString.indexOf(lexeme, _OPENING_DELIMITER, endIndex + 2);
-    }
-  }
-
-  /**
    * Determine if the specified node is a Dart script.
    *
    * @param node the node to be tested (not `null`)
@@ -1949,8 +2142,8 @@
       return false;
     }
     for (XmlAttributeNode attribute in attributes) {
-      if (attribute.name.lexeme == _TYPE) {
-        Token valueToken = attribute.value;
+      if (attribute.name == _TYPE) {
+        Token valueToken = attribute.valueToken;
         if (valueToken != null) {
           String value = valueToken.lexeme;
           if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATION_DART_IN_SINGLE_QUOTES) {
@@ -1961,23 +2154,6 @@
     }
     return false;
   }
-
-  /**
-   * Given the contents of an embedded expression that occurs at the given offset, parse it as a
-   * Dart expression. The contents should not include the expression's delimiters.
-   *
-   * @param contents the contents of the expression
-   * @param contentOffset the offset of the expression in the larger file
-   * @return the Dart expression that was parsed
-   */
-  Expression parseEmbeddedExpression(String contents, int contentOffset) {
-    LineInfo_Location location = _lineInfo.getLocation(contentOffset);
-    sc.Scanner scanner = new sc.Scanner(source, new sc.SubSequenceReader(new CharSequence(contents), contentOffset), _errorListener);
-    scanner.setSourceStart(location.lineNumber, location.columnNumber);
-    sc.Token firstToken = scanner.tokenize();
-    Parser parser = new Parser(source, _errorListener);
-    return parser.parseExpression(firstToken);
-  }
 }
 
 /**
@@ -2003,9 +2179,10 @@
   List<XmlTagNode> _tagNodes;
 
   /**
-   * The element associated with this HTML unit or `null` if the receiver is not resolved.
+   * The element associated with Dart pieces in this HTML unit or `null` if the receiver is
+   * not resolved.
    */
-  HtmlElementImpl element;
+  CompilationUnitElement compilationUnitElement;
 
   /**
    * Construct a new instance representing the content of an HTML file.
@@ -2022,6 +2199,13 @@
   accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
 
   /**
+   * Return the element associated with this HTML unit.
+   *
+   * @return the element or `null` if the receiver is not resolved
+   */
+  HtmlElement get element => super.element as HtmlElement;
+
+  /**
    * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
    * to edit the AST structure.
    *
@@ -2029,6 +2213,13 @@
    */
   List<XmlTagNode> get tagNodes => _tagNodes;
 
+  void set element(Element element) {
+    if (element != null && element is! HtmlElement) {
+      throw new IllegalArgumentException("HtmlElement expected, but ${element.runtimeType} given");
+    }
+    super.element = element;
+  }
+
   void visitChildren(XmlVisitor visitor) {
     for (XmlTagNode node in _tagNodes) {
       node.accept(visitor);
diff --git a/pkg/analyzer/lib/src/generated/index.dart b/pkg/analyzer/lib/src/generated/index.dart
new file mode 100644
index 0000000..38c1167
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/index.dart
@@ -0,0 +1,2776 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 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.index;
+
+import 'dart:collection' show Queue;
+import 'java_core.dart';
+import 'source.dart';
+import 'scanner.dart' show Token;
+import 'ast.dart';
+import 'element.dart';
+import 'resolver.dart' show Namespace, NamespaceBuilder;
+import 'engine.dart' show AnalysisEngine, AnalysisContext, InstrumentedAnalysisContextImpl;
+import 'html.dart' as ht;
+
+/**
+ * Instances of the [RemoveSourceOperation] implement an operation that removes from the index
+ * any data based on the content of a specified source.
+ *
+ * @coverage dart.engine.index
+ */
+class RemoveSourceOperation implements IndexOperation {
+  /**
+   * The index store against which this operation is being run.
+   */
+  IndexStore _indexStore;
+
+  /**
+   * The context in which source being removed.
+   */
+  AnalysisContext _context;
+
+  /**
+   * The source being removed.
+   */
+  final Source source;
+
+  /**
+   * Initialize a newly created operation that will remove the specified resource.
+   *
+   * @param indexStore the index store against which this operation is being run
+   * @param context the [AnalysisContext] to remove source in
+   * @param source the [Source] to remove from index
+   */
+  RemoveSourceOperation(IndexStore indexStore, AnalysisContext context, this.source) {
+    this._indexStore = indexStore;
+    this._context = context;
+  }
+
+  bool get isQuery => false;
+
+  void performOperation() {
+    {
+      _indexStore.removeSource(_context, source);
+    }
+  }
+
+  bool removeWhenSourceRemoved(Source source) => false;
+
+  String toString() => "RemoveSource(${source.fullName})";
+}
+
+/**
+ * The interface [IndexOperation] defines the behavior of objects used to perform operations
+ * on an index.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class IndexOperation {
+  /**
+   * Return `true` if this operation returns information from the index.
+   *
+   * @return `true` if this operation returns information from the index
+   */
+  bool get isQuery;
+
+  /**
+   * Perform the operation implemented by this operation.
+   */
+  void performOperation();
+
+  /**
+   * Return `true` if this operation should be removed from the operation queue when the
+   * given resource has been removed.
+   *
+   * @param source the [Source] that has been removed
+   * @return `true` if this operation should be removed from the operation queue as a
+   *         result of removing the resource
+   */
+  bool removeWhenSourceRemoved(Source source);
+}
+
+/**
+ * [IndexStore] which keeps full index in memory.
+ *
+ * @coverage dart.engine.index
+ */
+class MemoryIndexStoreImpl implements MemoryIndexStore {
+  static Object _WEAK_SET_VALUE = new Object();
+
+  /**
+   * When logging is on, [AnalysisEngine] actually creates
+   * [InstrumentedAnalysisContextImpl], which wraps [AnalysisContextImpl] used to create
+   * actual [Element]s. So, in index we have to unwrap [InstrumentedAnalysisContextImpl]
+   * when perform any operation.
+   */
+  static AnalysisContext unwrapContext(AnalysisContext context) {
+    if (context is InstrumentedAnalysisContextImpl) {
+      context = (context as InstrumentedAnalysisContextImpl).basis;
+    }
+    return context;
+  }
+
+  /**
+   * @return the [Source] of the enclosing [LibraryElement], may be `null`.
+   */
+  static Source getLibrarySourceOrNull(Element element) {
+    LibraryElement library = element.library;
+    return library != null ? library.source : null;
+  }
+
+  /**
+   * We add [AnalysisContext] to this weak set to ensure that we don't continue to add
+   * relationships after some context was removed using [removeContext].
+   */
+  Expando _removedContexts = new Expando();
+
+  /**
+   * This map is used to canonicalize equal keys.
+   */
+  Map<MemoryIndexStoreImpl_ElementRelationKey, MemoryIndexStoreImpl_ElementRelationKey> _canonicalKeys = {};
+
+  /**
+   * The mapping of [ElementRelationKey] to the [Location]s, one-to-many.
+   */
+  Map<MemoryIndexStoreImpl_ElementRelationKey, Set<Location>> _keyToLocations = {};
+
+  /**
+   * The mapping of [Source] to the [ElementRelationKey]s. It is used in
+   * [removeSource] to identify keys to remove from
+   * [keyToLocations].
+   */
+  Map<AnalysisContext, Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>>> _contextToSourceToKeys = {};
+
+  /**
+   * The mapping of [Source] to the [Location]s existing in it. It is used in
+   * [clearSource0] to identify locations to remove from
+   * [keyToLocations].
+   */
+  Map<AnalysisContext, Map<MemoryIndexStoreImpl_Source2, List<Location>>> _contextToSourceToLocations = {};
+
+  /**
+   * The mapping of library [Source] to the [Source]s of part units.
+   */
+  Map<AnalysisContext, Map<Source, Set<Source>>> _contextToLibraryToUnits = {};
+
+  /**
+   * The mapping of unit [Source] to the [Source]s of libraries it is used in.
+   */
+  Map<AnalysisContext, Map<Source, Set<Source>>> _contextToUnitToLibraries = {};
+
+  int _sourceCount = 0;
+
+  int _keyCount = 0;
+
+  int _locationCount = 0;
+
+  bool aboutToIndex(AnalysisContext context, CompilationUnitElement unitElement) {
+    context = unwrapContext(context);
+    // may be already removed in other thread
+    if (isRemovedContext(context)) {
+      return false;
+    }
+    // validate unit
+    if (unitElement == null) {
+      return false;
+    }
+    LibraryElement libraryElement = unitElement.library;
+    if (libraryElement == null) {
+      return false;
+    }
+    CompilationUnitElement definingUnitElement = libraryElement.definingCompilationUnit;
+    if (definingUnitElement == null) {
+      return false;
+    }
+    // prepare sources
+    Source library = definingUnitElement.source;
+    Source unit = unitElement.source;
+    // special handling for the defining library unit
+    if (unit == library) {
+      // prepare new parts
+      Set<Source> newParts = new Set();
+      for (CompilationUnitElement part in libraryElement.parts) {
+        newParts.add(part.source);
+      }
+      // prepare old parts
+      Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
+      if (libraryToUnits == null) {
+        libraryToUnits = {};
+        _contextToLibraryToUnits[context] = libraryToUnits;
+      }
+      Set<Source> oldParts = libraryToUnits[library];
+      // check if some parts are not in the library now
+      if (oldParts != null) {
+        Set<Source> noParts = oldParts.difference(newParts);
+        for (Source noPart in noParts) {
+          removeLocations(context, library, noPart);
+        }
+      }
+      // remember new parts
+      libraryToUnits[library] = newParts;
+    }
+    // remember libraries in which unit is used
+    Map<Source, Set<Source>> unitToLibraries = _contextToUnitToLibraries[context];
+    if (unitToLibraries == null) {
+      unitToLibraries = {};
+      _contextToUnitToLibraries[context] = unitToLibraries;
+    }
+    Set<Source> libraries = unitToLibraries[unit];
+    if (libraries == null) {
+      libraries = new Set();
+      unitToLibraries[unit] = libraries;
+    }
+    libraries.add(library);
+    // remove locations
+    removeLocations(context, library, unit);
+    // remove keys
+    {
+      Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>> sourceToKeys = _contextToSourceToKeys[context];
+      if (sourceToKeys != null) {
+        MemoryIndexStoreImpl_Source2 source2 = new MemoryIndexStoreImpl_Source2(library, unit);
+        sourceToKeys.remove(source2);
+      }
+    }
+    // OK, we can index
+    return true;
+  }
+
+  bool aboutToIndex2(AnalysisContext context, Source source) {
+    context = unwrapContext(context);
+    // may be already removed in other thread
+    if (isRemovedContext(context)) {
+      return false;
+    }
+    // remove locations
+    removeLocations(context, source, source);
+    // remove keys
+    {
+      Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>> sourceToKeys = _contextToSourceToKeys[context];
+      if (sourceToKeys != null) {
+        MemoryIndexStoreImpl_Source2 source2 = new MemoryIndexStoreImpl_Source2(source, source);
+        sourceToKeys.remove(source2);
+      }
+    }
+    // OK, we can index
+    return true;
+  }
+
+  List<Location> getRelationships(Element element, Relationship relationship) {
+    MemoryIndexStoreImpl_ElementRelationKey key = new MemoryIndexStoreImpl_ElementRelationKey(element, relationship);
+    Set<Location> locations = _keyToLocations[key];
+    if (locations != null) {
+      return new List.from(locations);
+    }
+    return Location.EMPTY_ARRAY;
+  }
+
+  String get statistics => "${_locationCount} relationships in ${_keyCount} keys in ${_sourceCount} sources";
+
+  int internalGetKeyCount() => _keyToLocations.length;
+
+  int internalGetLocationCount() {
+    int count = 0;
+    for (Set<Location> locations in _keyToLocations.values) {
+      count += locations.length;
+    }
+    return count;
+  }
+
+  int internalGetLocationCount2(AnalysisContext context) {
+    context = unwrapContext(context);
+    int count = 0;
+    for (Set<Location> locations in _keyToLocations.values) {
+      for (Location location in locations) {
+        if (identical(location.element.context, context)) {
+          count++;
+        }
+      }
+    }
+    return count;
+  }
+
+  int internalGetSourceKeyCount(AnalysisContext context) {
+    int count = 0;
+    Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>> sourceToKeys = _contextToSourceToKeys[context];
+    if (sourceToKeys != null) {
+      for (Set<MemoryIndexStoreImpl_ElementRelationKey> keys in sourceToKeys.values) {
+        count += keys.length;
+      }
+    }
+    return count;
+  }
+
+  void recordRelationship(Element element, Relationship relationship, Location location) {
+    if (element == null || location == null) {
+      return;
+    }
+    location = location.clone();
+    // at the index level we don't care about Member(s)
+    if (element is Member) {
+      element = (element as Member).baseElement;
+    }
+    // prepare information
+    AnalysisContext elementContext = element.context;
+    AnalysisContext locationContext = location.element.context;
+    Source elementSource = element.source;
+    Source locationSource = location.element.source;
+    Source elementLibrarySource = getLibrarySourceOrNull(element);
+    Source locationLibrarySource = getLibrarySourceOrNull(location.element);
+    // sanity check
+    if (locationContext == null) {
+      return;
+    }
+    if (locationSource == null) {
+      return;
+    }
+    if (elementContext == null && element is! NameElementImpl && element is! UniverseElementImpl) {
+      return;
+    }
+    if (elementSource == null && element is! NameElementImpl && element is! UniverseElementImpl) {
+      return;
+    }
+    // may be already removed in other thread
+    if (isRemovedContext(elementContext)) {
+      return;
+    }
+    if (isRemovedContext(locationContext)) {
+      return;
+    }
+    // record: key -> location(s)
+    MemoryIndexStoreImpl_ElementRelationKey key = getCanonicalKey(element, relationship);
+    {
+      Set<Location> locations = _keyToLocations.remove(key);
+      if (locations == null) {
+        locations = createLocationIdentitySet();
+      } else {
+        _keyCount--;
+      }
+      _keyToLocations[key] = locations;
+      _keyCount++;
+      locations.add(location);
+      _locationCount++;
+    }
+    // record: location -> key
+    location.internalKey = key;
+    // prepare source pairs
+    MemoryIndexStoreImpl_Source2 elementSource2 = new MemoryIndexStoreImpl_Source2(elementLibrarySource, elementSource);
+    MemoryIndexStoreImpl_Source2 locationSource2 = new MemoryIndexStoreImpl_Source2(locationLibrarySource, locationSource);
+    // record: element source -> keys
+    {
+      Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>> sourceToKeys = _contextToSourceToKeys[elementContext];
+      if (sourceToKeys == null) {
+        sourceToKeys = {};
+        _contextToSourceToKeys[elementContext] = sourceToKeys;
+      }
+      Set<MemoryIndexStoreImpl_ElementRelationKey> keys = sourceToKeys[elementSource2];
+      if (keys == null) {
+        keys = new Set();
+        sourceToKeys[elementSource2] = keys;
+        _sourceCount++;
+      }
+      keys.remove(key);
+      keys.add(key);
+    }
+    // record: location source -> locations
+    {
+      Map<MemoryIndexStoreImpl_Source2, List<Location>> sourceToLocations = _contextToSourceToLocations[locationContext];
+      if (sourceToLocations == null) {
+        sourceToLocations = {};
+        _contextToSourceToLocations[locationContext] = sourceToLocations;
+      }
+      List<Location> locations = sourceToLocations[locationSource2];
+      if (locations == null) {
+        locations = [];
+        sourceToLocations[locationSource2] = locations;
+      }
+      locations.add(location);
+    }
+  }
+
+  void removeContext(AnalysisContext context) {
+    context = unwrapContext(context);
+    if (context == null) {
+      return;
+    }
+    // mark as removed
+    markRemovedContext(context);
+    removeSources(context, null);
+    // remove context
+    _contextToSourceToKeys.remove(context);
+    _contextToSourceToLocations.remove(context);
+    _contextToLibraryToUnits.remove(context);
+    _contextToUnitToLibraries.remove(context);
+  }
+
+  void removeSource(AnalysisContext context, Source unit) {
+    context = unwrapContext(context);
+    if (context == null) {
+      return;
+    }
+    // remove locations defined in source
+    Map<Source, Set<Source>> unitToLibraries = _contextToUnitToLibraries[context];
+    if (unitToLibraries != null) {
+      Set<Source> libraries = unitToLibraries.remove(unit);
+      if (libraries != null) {
+        for (Source library in libraries) {
+          MemoryIndexStoreImpl_Source2 source2 = new MemoryIndexStoreImpl_Source2(library, unit);
+          // remove locations defined in source
+          removeLocations(context, library, unit);
+          // remove keys for elements defined in source
+          Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>> sourceToKeys = _contextToSourceToKeys[context];
+          if (sourceToKeys != null) {
+            Set<MemoryIndexStoreImpl_ElementRelationKey> keys = sourceToKeys.remove(source2);
+            if (keys != null) {
+              for (MemoryIndexStoreImpl_ElementRelationKey key in keys) {
+                _canonicalKeys.remove(key);
+                Set<Location> locations = _keyToLocations.remove(key);
+                if (locations != null) {
+                  _keyCount--;
+                  _locationCount -= locations.length;
+                }
+              }
+              _sourceCount--;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  void removeSources(AnalysisContext context, SourceContainer container) {
+    context = unwrapContext(context);
+    if (context == null) {
+      return;
+    }
+    // remove sources #1
+    Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelationKey>> sourceToKeys = _contextToSourceToKeys[context];
+    if (sourceToKeys != null) {
+      List<MemoryIndexStoreImpl_Source2> sources = [];
+      for (MemoryIndexStoreImpl_Source2 source2 in sources) {
+        Source source = source2._unitSource;
+        if (container == null || container.contains(source)) {
+          removeSource(context, source);
+        }
+      }
+    }
+    // remove sources #2
+    Map<MemoryIndexStoreImpl_Source2, List<Location>> sourceToLocations = _contextToSourceToLocations[context];
+    if (sourceToLocations != null) {
+      List<MemoryIndexStoreImpl_Source2> sources = [];
+      for (MemoryIndexStoreImpl_Source2 source2 in sources) {
+        Source source = source2._unitSource;
+        if (container == null || container.contains(source)) {
+          removeSource(context, source);
+        }
+      }
+    }
+  }
+
+  /**
+   * Creates new [Set] that uses object identity instead of equals.
+   */
+  Set<Location> createLocationIdentitySet() => new Set<Location>.identity();
+
+  /**
+   * @return the canonical [ElementRelationKey] for given [Element] and
+   *         [Relationship], i.e. unique instance for this combination.
+   */
+  MemoryIndexStoreImpl_ElementRelationKey getCanonicalKey(Element element, Relationship relationship) {
+    MemoryIndexStoreImpl_ElementRelationKey key = new MemoryIndexStoreImpl_ElementRelationKey(element, relationship);
+    MemoryIndexStoreImpl_ElementRelationKey canonicalKey = _canonicalKeys[key];
+    if (canonicalKey == null) {
+      canonicalKey = key;
+      _canonicalKeys[key] = canonicalKey;
+    }
+    return canonicalKey;
+  }
+
+  /**
+   * Checks if given [AnalysisContext] is marked as removed.
+   */
+  bool isRemovedContext(AnalysisContext context) => _removedContexts[context] != null;
+
+  /**
+   * Marks given [AnalysisContext] as removed.
+   */
+  void markRemovedContext(AnalysisContext context) {
+    _removedContexts[context] = true;
+  }
+
+  /**
+   * Removes locations recorded in the given library/unit pair.
+   */
+  void removeLocations(AnalysisContext context, Source library, Source unit) {
+    MemoryIndexStoreImpl_Source2 source2 = new MemoryIndexStoreImpl_Source2(library, unit);
+    Map<MemoryIndexStoreImpl_Source2, List<Location>> sourceToLocations = _contextToSourceToLocations[context];
+    if (sourceToLocations != null) {
+      List<Location> sourceLocations = sourceToLocations.remove(source2);
+      if (sourceLocations != null) {
+        for (Location location in sourceLocations) {
+          MemoryIndexStoreImpl_ElementRelationKey key = location.internalKey as MemoryIndexStoreImpl_ElementRelationKey;
+          Set<Location> relLocations = _keyToLocations[key];
+          if (relLocations != null) {
+            relLocations.remove(location);
+            _locationCount--;
+            // no locations with this key
+            if (relLocations.isEmpty) {
+              _canonicalKeys.remove(key);
+              _keyToLocations.remove(key);
+              _keyCount--;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+class MemoryIndexStoreImpl_ElementRelationKey {
+  Element _element;
+
+  Relationship _relationship;
+
+  MemoryIndexStoreImpl_ElementRelationKey(Element element, Relationship relationship) {
+    this._element = element;
+    this._relationship = relationship;
+  }
+
+  bool operator ==(Object obj) {
+    MemoryIndexStoreImpl_ElementRelationKey other = obj as MemoryIndexStoreImpl_ElementRelationKey;
+    Element otherElement = other._element;
+    return identical(other._relationship, _relationship) && otherElement.nameOffset == _element.nameOffset && identical(otherElement.kind, _element.kind) && otherElement.displayName == _element.displayName && otherElement.source == _element.source;
+  }
+
+  int get hashCode => JavaArrays.makeHashCode([
+      _element.source,
+      _element.nameOffset,
+      _element.kind,
+      _element.displayName,
+      _relationship]);
+
+  String toString() => "${_element} ${_relationship}";
+}
+
+class MemoryIndexStoreImpl_Source2 {
+  Source _librarySource;
+
+  Source _unitSource;
+
+  MemoryIndexStoreImpl_Source2(Source librarySource, Source unitSource) {
+    this._librarySource = librarySource;
+    this._unitSource = unitSource;
+  }
+
+  bool operator ==(Object obj) {
+    if (identical(obj, this)) {
+      return true;
+    }
+    if (obj is! MemoryIndexStoreImpl_Source2) {
+      return false;
+    }
+    MemoryIndexStoreImpl_Source2 other = obj as MemoryIndexStoreImpl_Source2;
+    return other._librarySource == _librarySource && other._unitSource == _unitSource;
+  }
+
+  int get hashCode => JavaArrays.makeHashCode([_librarySource, _unitSource]);
+
+  String toString() => "${_librarySource} ${_unitSource}";
+}
+
+/**
+ * Instances of the [IndexUnitOperation] implement an operation that adds data to the index
+ * based on the resolved [CompilationUnit].
+ *
+ * @coverage dart.engine.index
+ */
+class IndexUnitOperation implements IndexOperation {
+  /**
+   * The index store against which this operation is being run.
+   */
+  IndexStore _indexStore;
+
+  /**
+   * The context in which compilation unit was resolved.
+   */
+  AnalysisContext _context;
+
+  /**
+   * The compilation unit being indexed.
+   */
+  final CompilationUnit unit;
+
+  /**
+   * The element of the compilation unit being indexed.
+   */
+  CompilationUnitElement _unitElement;
+
+  /**
+   * The source being indexed.
+   */
+  Source _source;
+
+  /**
+   * Initialize a newly created operation that will index the specified unit.
+   *
+   * @param indexStore the index store against which this operation is being run
+   * @param context the context in which compilation unit was resolved
+   * @param unit the fully resolved AST structure
+   */
+  IndexUnitOperation(IndexStore indexStore, AnalysisContext context, this.unit) {
+    this._indexStore = indexStore;
+    this._context = context;
+    this._unitElement = unit.element;
+    this._source = _unitElement.source;
+  }
+
+  /**
+   * @return the [Source] to be indexed.
+   */
+  Source get source => _source;
+
+  bool get isQuery => false;
+
+  void performOperation() {
+    {
+      try {
+        bool mayIndex = _indexStore.aboutToIndex(_context, _unitElement);
+        if (!mayIndex) {
+          return;
+        }
+        unit.accept(new IndexContributor(_indexStore));
+        unit.accept(new AngularDartIndexContributor(_indexStore));
+      } catch (exception) {
+        AnalysisEngine.instance.logger.logError2("Could not index ${unit.element.location}", exception);
+      }
+    }
+  }
+
+  bool removeWhenSourceRemoved(Source source) => this._source == source;
+
+  String toString() => "IndexUnitOperation(${_source.fullName})";
+}
+
+/**
+ * Recursively visits [HtmlUnit] and every embedded [Expression].
+ */
+abstract class ExpressionVisitor extends ht.RecursiveXmlVisitor<Object> {
+  /**
+   * Visits the given [Expression]s embedded into tag or attribute.
+   *
+   * @param expression the [Expression] to visit, not `null`
+   */
+  void visitExpression(Expression expression);
+
+  Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
+    visitExpressions(node.expressions);
+    return super.visitXmlAttributeNode(node);
+  }
+
+  Object visitXmlTagNode(ht.XmlTagNode node) {
+    visitExpressions(node.expressions);
+    return super.visitXmlTagNode(node);
+  }
+
+  /**
+   * Visits [Expression]s of the given [EmbeddedExpression]s.
+   */
+  void visitExpressions(List<ht.EmbeddedExpression> expressions) {
+    for (ht.EmbeddedExpression embeddedExpression in expressions) {
+      Expression expression = embeddedExpression.expression;
+      visitExpression(expression);
+    }
+  }
+}
+
+/**
+ * Relationship between an element and a location. Relationships are identified by a globally unique
+ * identifier.
+ *
+ * @coverage dart.engine.index
+ */
+class Relationship {
+  /**
+   * The unique identifier for this relationship.
+   */
+  String _uniqueId;
+
+  /**
+   * A table mapping relationship identifiers to relationships.
+   */
+  static Map<String, Relationship> _RelationshipMap = {};
+
+  /**
+   * Return the relationship with the given unique identifier.
+   *
+   * @param uniqueId the unique identifier for the relationship
+   * @return the relationship with the given unique identifier
+   */
+  static Relationship getRelationship(String uniqueId) {
+    {
+      Relationship relationship = _RelationshipMap[uniqueId];
+      if (relationship == null) {
+        relationship = new Relationship(uniqueId);
+        _RelationshipMap[uniqueId] = relationship;
+      }
+      return relationship;
+    }
+  }
+
+  /**
+   * @return all registered [Relationship]s.
+   */
+  static Iterable<Relationship> values() => _RelationshipMap.values;
+
+  /**
+   * Initialize a newly created relationship to have the given unique identifier.
+   *
+   * @param uniqueId the unique identifier for this relationship
+   */
+  Relationship(String uniqueId) {
+    this._uniqueId = uniqueId;
+  }
+
+  /**
+   * Return the unique identifier for this relationship.
+   *
+   * @return the unique identifier for this relationship
+   */
+  String get identifier => _uniqueId;
+
+  String toString() => _uniqueId;
+}
+
+/**
+ * Implementation of [Index].
+ *
+ * @coverage dart.engine.index
+ */
+class IndexImpl implements Index {
+  IndexStore _store;
+
+  OperationQueue _queue;
+
+  OperationProcessor _processor;
+
+  IndexImpl(IndexStore store, OperationQueue queue, OperationProcessor processor) {
+    this._store = store;
+    this._queue = queue;
+    this._processor = processor;
+  }
+
+  void getRelationships(Element element, Relationship relationship, RelationshipCallback callback) {
+    _queue.enqueue(new GetRelationshipsOperation(_store, element, relationship, callback));
+  }
+
+  String get statistics => _store.statistics;
+
+  void indexHtmlUnit(AnalysisContext context, ht.HtmlUnit unit) {
+    if (unit == null) {
+      return;
+    }
+    if (unit.element == null) {
+      return;
+    }
+    if (unit.compilationUnitElement == null) {
+      return;
+    }
+    _queue.enqueue(new IndexHtmlUnitOperation(_store, context, unit));
+  }
+
+  void indexUnit(AnalysisContext context, CompilationUnit unit) {
+    if (unit == null) {
+      return;
+    }
+    if (unit.element == null) {
+      return;
+    }
+    _queue.enqueue(new IndexUnitOperation(_store, context, unit));
+  }
+
+  void removeContext(AnalysisContext context) {
+    _queue.enqueue(new RemoveContextOperation(_store, context));
+  }
+
+  void removeSource(AnalysisContext context, Source source) {
+    _queue.enqueue(new RemoveSourceOperation(_store, context, source));
+  }
+
+  void removeSources(AnalysisContext context, SourceContainer container) {
+    _queue.enqueue(new RemoveSourcesOperation(_store, context, container));
+  }
+
+  void run() {
+    _processor.run();
+  }
+
+  void stop() {
+    _processor.stop(false);
+  }
+}
+
+/**
+ * Instances of the [RemoveSourcesOperation] implement an operation that removes from the
+ * index any data based on the content of source belonging to a [SourceContainer].
+ *
+ * @coverage dart.engine.index
+ */
+class RemoveSourcesOperation implements IndexOperation {
+  /**
+   * The index store against which this operation is being run.
+   */
+  IndexStore _indexStore;
+
+  /**
+   * The context to remove container.
+   */
+  AnalysisContext _context;
+
+  /**
+   * The source container to remove.
+   */
+  final SourceContainer container;
+
+  /**
+   * Initialize a newly created operation that will remove the specified resource.
+   *
+   * @param indexStore the index store against which this operation is being run
+   * @param context the [AnalysisContext] to remove container in
+   * @param container the [SourceContainer] to remove from index
+   */
+  RemoveSourcesOperation(IndexStore indexStore, AnalysisContext context, this.container) {
+    this._indexStore = indexStore;
+    this._context = context;
+  }
+
+  bool get isQuery => false;
+
+  void performOperation() {
+    {
+      _indexStore.removeSources(_context, container);
+    }
+  }
+
+  bool removeWhenSourceRemoved(Source source) => false;
+
+  String toString() => "RemoveSources(${container})";
+}
+
+/**
+ * The interface `UniverseElement` defines element to use when we want to request "defines"
+ * relations without specifying exact library.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class UniverseElement implements Element {
+  static final UniverseElement INSTANCE = UniverseElementImpl.INSTANCE;
+}
+
+/**
+ * Instances of the [OperationProcessor] process the operations on a single
+ * [OperationQueue]. Each processor can be run one time on a single thread.
+ *
+ * @coverage dart.engine.index
+ */
+class OperationProcessor {
+  /**
+   * The queue containing the operations to be processed.
+   */
+  OperationQueue _queue;
+
+  /**
+   * The current state of the processor.
+   */
+  ProcessorState _state = ProcessorState.READY;
+
+  /**
+   * The number of milliseconds for which the thread on which the processor is running will wait for
+   * an operation to become available if there are no operations ready to be processed.
+   */
+  static int _WAIT_DURATION = 100;
+
+  /**
+   * Initialize a newly created operation processor to process the operations on the given queue.
+   *
+   * @param queue the queue containing the operations to be processed
+   */
+  OperationProcessor(OperationQueue queue) {
+    this._queue = queue;
+  }
+
+  /**
+   * Start processing operations. If the processor is already running on a different thread, then
+   * this method will return immediately with no effect. Otherwise, this method will not return
+   * until after the processor has been stopped from a different thread or until the thread running
+   * the processor has been interrupted.
+   */
+  void run() {
+    {
+      // This processor is, or was, already running on a different thread.
+      if (_state != ProcessorState.READY) {
+        throw new IllegalStateException("Operation processors can only be run one time");
+      }
+      // OK, run.
+      _state = ProcessorState.RUNNING;
+    }
+    try {
+      while (isRunning) {
+        // wait for operation
+        IndexOperation operation = null;
+        {
+          operation = _queue.dequeue(_WAIT_DURATION);
+        }
+        // perform operation
+        if (operation != null) {
+          try {
+            operation.performOperation();
+          } catch (exception) {
+            AnalysisEngine.instance.logger.logError2("Exception in indexing operation: ${operation}", exception);
+          }
+        }
+      }
+    } finally {
+      {
+        _state = ProcessorState.STOPPED;
+      }
+    }
+  }
+
+  /**
+   * Stop processing operations after the current operation has completed. If the argument is
+   * `true` then this method will wait until the last operation has completed; otherwise this
+   * method might return before the last operation has completed.
+   *
+   * @param wait `true` if this method will wait until the last operation has completed before
+   *          returning
+   * @return the library files for the libraries that need to be analyzed when a new session is
+   *         started.
+   */
+  List<Source> stop(bool wait) {
+    {
+      if (identical(_state, ProcessorState.READY)) {
+        _state = ProcessorState.STOPPED;
+        return unanalyzedSources;
+      } else if (identical(_state, ProcessorState.STOPPED)) {
+        return unanalyzedSources;
+      } else if (identical(_state, ProcessorState.RUNNING)) {
+        _state = ProcessorState.STOP_REQESTED;
+      }
+    }
+    while (wait) {
+      {
+        if (identical(_state, ProcessorState.STOPPED)) {
+          return unanalyzedSources;
+        }
+      }
+      waitOneMs();
+    }
+    return unanalyzedSources;
+  }
+
+  /**
+   * Waits until processors will switch from "ready" to "running" state.
+   *
+   * @return `true` if processor is now actually in "running" state, e.g. not in "stopped"
+   *         state.
+   */
+  bool waitForRunning() {
+    while (identical(_state, ProcessorState.READY)) {
+      threadYield();
+    }
+    return identical(_state, ProcessorState.RUNNING);
+  }
+
+  /**
+   * @return the [Source]s that are not indexed yet.
+   */
+  List<Source> get unanalyzedSources {
+    Set<Source> sources = new Set();
+    for (IndexOperation operation in _queue.operations) {
+      if (operation is IndexUnitOperation) {
+        Source source = operation.source;
+        sources.add(source);
+      }
+    }
+    return new List.from(sources);
+  }
+
+  /**
+   * Return `true` if the current state is [ProcessorState#RUNNING].
+   *
+   * @return `true` if this processor is running
+   */
+  bool get isRunning {
+    {
+      return identical(_state, ProcessorState.RUNNING);
+    }
+  }
+
+  void threadYield() {
+  }
+
+  void waitOneMs() {
+  }
+}
+
+/**
+ * The enumeration <code>ProcessorState</code> represents the possible states of an operation
+ * processor.
+ */
+class ProcessorState extends Enum<ProcessorState> {
+  /**
+   * The processor is ready to be run (has not been run before).
+   */
+  static final ProcessorState READY = new ProcessorState('READY', 0);
+
+  /**
+   * The processor is currently performing operations.
+   */
+  static final ProcessorState RUNNING = new ProcessorState('RUNNING', 1);
+
+  /**
+   * The processor is currently performing operations but has been asked to stop.
+   */
+  static final ProcessorState STOP_REQESTED = new ProcessorState('STOP_REQESTED', 2);
+
+  /**
+   * The processor has stopped performing operations and cannot be used again.
+   */
+  static final ProcessorState STOPPED = new ProcessorState('STOPPED', 3);
+
+  static final List<ProcessorState> values = [READY, RUNNING, STOP_REQESTED, STOPPED];
+
+  ProcessorState(String name, int ordinal) : super(name, ordinal);
+}
+
+/**
+ * Constants used when populating and accessing the index.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class IndexConstants {
+  /**
+   * An element used to represent the universe.
+   */
+  static final Element UNIVERSE = UniverseElement.INSTANCE;
+
+  /**
+   * The relationship used to indicate that a container (the left-operand) contains the definition
+   * of a class at a specific location (the right operand).
+   */
+  static final Relationship DEFINES_CLASS = Relationship.getRelationship("defines-class");
+
+  /**
+   * The relationship used to indicate that a container (the left-operand) contains the definition
+   * of a function at a specific location (the right operand).
+   */
+  static final Relationship DEFINES_FUNCTION = Relationship.getRelationship("defines-function");
+
+  /**
+   * The relationship used to indicate that a container (the left-operand) contains the definition
+   * of a class type alias at a specific location (the right operand).
+   */
+  static final Relationship DEFINES_CLASS_ALIAS = Relationship.getRelationship("defines-class-alias");
+
+  /**
+   * The relationship used to indicate that a container (the left-operand) contains the definition
+   * of a function type at a specific location (the right operand).
+   */
+  static final Relationship DEFINES_FUNCTION_TYPE = Relationship.getRelationship("defines-function-type");
+
+  /**
+   * The relationship used to indicate that a container (the left-operand) contains the definition
+   * of a method at a specific location (the right operand).
+   */
+  static final Relationship DEFINES_VARIABLE = Relationship.getRelationship("defines-variable");
+
+  /**
+   * The relationship used to indicate that a name (the left-operand) is defined at a specific
+   * location (the right operand).
+   */
+  static final Relationship IS_DEFINED_BY = Relationship.getRelationship("is-defined-by");
+
+  /**
+   * The relationship used to indicate that a type (the left-operand) is extended by a type at a
+   * specific location (the right operand).
+   */
+  static final Relationship IS_EXTENDED_BY = Relationship.getRelationship("is-extended-by");
+
+  /**
+   * The relationship used to indicate that a type (the left-operand) is implemented by a type at a
+   * specific location (the right operand).
+   */
+  static final Relationship IS_IMPLEMENTED_BY = Relationship.getRelationship("is-implemented-by");
+
+  /**
+   * The relationship used to indicate that a type (the left-operand) is mixed into a type at a
+   * specific location (the right operand).
+   */
+  static final Relationship IS_MIXED_IN_BY = Relationship.getRelationship("is-mixed-in-by");
+
+  /**
+   * The relationship used to indicate that a parameter or variable (the left-operand) is read at a
+   * specific location (the right operand).
+   */
+  static final Relationship IS_READ_BY = Relationship.getRelationship("is-read-by");
+
+  /**
+   * The relationship used to indicate that a parameter or variable (the left-operand) is both read
+   * and modified at a specific location (the right operand).
+   */
+  static final Relationship IS_READ_WRITTEN_BY = Relationship.getRelationship("is-read-written-by");
+
+  /**
+   * The relationship used to indicate that a parameter or variable (the left-operand) is modified
+   * (assigned to) at a specific location (the right operand).
+   */
+  static final Relationship IS_WRITTEN_BY = Relationship.getRelationship("is-written-by");
+
+  /**
+   * The relationship used to indicate that an element (the left-operand) is referenced at a
+   * specific location (the right operand). This is used for everything except read/write operations
+   * for fields, parameters, and variables. Those use either [IS_REFERENCED_BY_QUALIFIED],
+   * [IS_REFERENCED_BY_UNQUALIFIED], [IS_READ_BY], [IS_WRITTEN_BY] or
+   * [IS_READ_WRITTEN_BY], as appropriate.
+   */
+  static final Relationship IS_REFERENCED_BY = Relationship.getRelationship("is-referenced-by");
+
+  /**
+   * The relationship used to indicate that an [NameElementImpl] (the left-operand) is
+   * referenced at a specific location (the right operand). This is used for qualified resolved
+   * references to methods and fields.
+   */
+  static final Relationship IS_REFERENCED_BY_QUALIFIED_RESOLVED = Relationship.getRelationship("is-referenced-by_qualified-resolved");
+
+  /**
+   * The relationship used to indicate that an [NameElementImpl] (the left-operand) is
+   * referenced at a specific location (the right operand). This is used for qualified unresolved
+   * references to methods and fields.
+   */
+  static final Relationship IS_REFERENCED_BY_QUALIFIED_UNRESOLVED = Relationship.getRelationship("is-referenced-by_qualified-unresolved");
+
+  /**
+   * The relationship used to indicate that an element (the left-operand) is referenced at a
+   * specific location (the right operand). This is used for field accessors and methods.
+   */
+  static final Relationship IS_REFERENCED_BY_QUALIFIED = Relationship.getRelationship("is-referenced-by-qualified");
+
+  /**
+   * The relationship used to indicate that an element (the left-operand) is referenced at a
+   * specific location (the right operand). This is used for field accessors and methods.
+   */
+  static final Relationship IS_REFERENCED_BY_UNQUALIFIED = Relationship.getRelationship("is-referenced-by-unqualified");
+
+  /**
+   * The relationship used to indicate that an element (the left-operand) is invoked at a specific
+   * location (the right operand). This is used for functions.
+   */
+  static final Relationship IS_INVOKED_BY = Relationship.getRelationship("is-invoked-by");
+
+  /**
+   * The relationship used to indicate that an element (the left-operand) is invoked at a specific
+   * location (the right operand). This is used for methods.
+   */
+  static final Relationship IS_INVOKED_BY_QUALIFIED = Relationship.getRelationship("is-invoked-by-qualified");
+
+  /**
+   * The relationship used to indicate that an element (the left-operand) is invoked at a specific
+   * location (the right operand). This is used for methods.
+   */
+  static final Relationship IS_INVOKED_BY_UNQUALIFIED = Relationship.getRelationship("is-invoked-by-unqualified");
+}
+
+/**
+ * Visits resolved [HtmlUnit] and adds relationships into [IndexStore].
+ *
+ * @coverage dart.engine.index
+ */
+class AngularHtmlIndexContributor extends ExpressionVisitor {
+  /**
+   * The [IndexStore] to record relations into.
+   */
+  IndexStore _store;
+
+  /**
+   * The index contributor used to index Dart [Expression]s.
+   */
+  IndexContributor _indexContributor;
+
+  HtmlElement _htmlUnitElement;
+
+  /**
+   * Initialize a newly created Angular HTML index contributor.
+   *
+   * @param store the [IndexStore] to record relations into.
+   */
+  AngularHtmlIndexContributor(IndexStore store) {
+    this._store = store;
+    _indexContributor = new IndexContributor(store);
+  }
+
+  void visitExpression(Expression expression) {
+    expression.accept(_indexContributor);
+  }
+
+  Object visitHtmlUnit(ht.HtmlUnit node) {
+    _htmlUnitElement = node.element;
+    CompilationUnitElement dartUnitElement = node.compilationUnitElement;
+    _indexContributor.enterScope(dartUnitElement);
+    return super.visitHtmlUnit(node);
+  }
+
+  Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
+    Element element = node.element;
+    if (element != null) {
+      ht.Token nameToken = node.nameToken;
+      Location location = createLocation(nameToken);
+      _store.recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    }
+    return super.visitXmlAttributeNode(node);
+  }
+
+  Object visitXmlTagNode(ht.XmlTagNode node) {
+    Element element = node.element;
+    if (element != null) {
+      ht.Token tagToken = node.tagToken;
+      Location location = createLocation(tagToken);
+      _store.recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    }
+    return super.visitXmlTagNode(node);
+  }
+
+  Location createLocation(ht.Token token) => new Location(_htmlUnitElement, token.offset, token.length);
+}
+
+/**
+ * The interface [Index] defines the behavior of objects that maintain an index storing
+ * [Relationship] between [Element]. All of the operations
+ * defined on the index are asynchronous, and results, when there are any, are provided through a
+ * callback.
+ *
+ * Despite being asynchronous, the results of the operations are guaranteed to be consistent with
+ * the expectation that operations are performed in the order in which they are requested.
+ * Modification operations are executed before any read operation. There is no guarantee about the
+ * order in which the callbacks for read operations will be invoked.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class Index {
+  /**
+   * Asynchronously invoke the given callback with an array containing all of the locations of the
+   * elements that have the given relationship with the given element. For example, if the element
+   * represents a method and the relationship is the is-referenced-by relationship, then the
+   * locations that will be passed into the callback will be all of the places where the method is
+   * invoked.
+   *
+   * @param element the element that has the relationship with the locations to be returned
+   * @param relationship the relationship between the given element and the locations to be returned
+   * @param callback the callback that will be invoked when the locations are found
+   */
+  void getRelationships(Element element, Relationship relationship, RelationshipCallback callback);
+
+  /**
+   * Answer index statistics.
+   */
+  String get statistics;
+
+  /**
+   * Asynchronously process the given [HtmlUnit] in order to record the relationships.
+   *
+   * @param context the [AnalysisContext] in which [HtmlUnit] was resolved
+   * @param unit the [HtmlUnit] being indexed
+   */
+  void indexHtmlUnit(AnalysisContext context, ht.HtmlUnit unit);
+
+  /**
+   * Asynchronously process the given [CompilationUnit] in order to record the relationships.
+   *
+   * @param context the [AnalysisContext] in which [CompilationUnit] was resolved
+   * @param unit the [CompilationUnit] being indexed
+   */
+  void indexUnit(AnalysisContext context, CompilationUnit unit);
+
+  /**
+   * Asynchronously remove from the index all of the information associated with the given context.
+   *
+   * This method should be invoked when a context is disposed.
+   *
+   * @param context the [AnalysisContext] to remove
+   */
+  void removeContext(AnalysisContext context);
+
+  /**
+   * Asynchronously remove from the index all of the information associated with elements or
+   * locations in the given source. This includes relationships between an element in the given
+   * source and any other locations, relationships between any other elements and a location within
+   * the given source.
+   *
+   * This method should be invoked when a source is no longer part of the code base.
+   *
+   * @param context the [AnalysisContext] in which [Source] being removed
+   * @param source the [Source] being removed
+   */
+  void removeSource(AnalysisContext context, Source source);
+
+  /**
+   * Asynchronously remove from the index all of the information associated with elements or
+   * locations in the given sources. This includes relationships between an element in the given
+   * sources and any other locations, relationships between any other elements and a location within
+   * the given sources.
+   *
+   * This method should be invoked when multiple sources are no longer part of the code base.
+   *
+   * @param the [AnalysisContext] in which [Source]s being removed
+   * @param container the [SourceContainer] holding the sources being removed
+   */
+  void removeSources(AnalysisContext context, SourceContainer container);
+
+  /**
+   * Should be called in separate [Thread] to process request in this [Index]. Does not
+   * return until the [stop] method is called.
+   */
+  void run();
+
+  /**
+   * Should be called to stop process running [run], so stop processing requests.
+   */
+  void stop();
+}
+
+/**
+ * Container of information computed by the index - relationships between elements.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class IndexStore {
+  /**
+   * Notifies the index store that we are going to index the unit with the given element.
+   *
+   * If the unit is a part of a library, then all its locations are removed. If it is a defining
+   * compilation unit of a library, then index store also checks if some previously indexed parts of
+   * the library are not parts of the library anymore, and clears their information.
+   *
+   * @param the [AnalysisContext] in which unit being indexed
+   * @param unitElement the element of the unit being indexed
+   * @return `true` the given [AnalysisContext] is active, or `false` if it was
+   *         removed before, so no any unit may be indexed with it
+   */
+  bool aboutToIndex(AnalysisContext context, CompilationUnitElement unitElement);
+
+  /**
+   * Notifies the index store that we are going to index the given [Source].
+   *
+   * This method should be used only for a [Source] that cannot be a part of multiple
+   * libraries. Otherwise [aboutToIndex] should be
+   * used.
+   *
+   * @param the [AnalysisContext] in which unit being indexed
+   * @param source the [Source] being indexed
+   * @return `true` the given [AnalysisContext] is active, or `false` if it was
+   *         removed before, so no any unit may be indexed with it
+   */
+  bool aboutToIndex2(AnalysisContext context, Source source);
+
+  /**
+   * Return the locations of the elements that have the given relationship with the given element.
+   * For example, if the element represents a method and the relationship is the is-referenced-by
+   * relationship, then the returned locations will be all of the places where the method is
+   * invoked.
+   *
+   * @param element the the element that has the relationship with the locations to be returned
+   * @param relationship the [Relationship] between the given element and the locations to be
+   *          returned
+   * @return the locations that have the given relationship with the given element
+   */
+  List<Location> getRelationships(Element element, Relationship relationship);
+
+  /**
+   * Answer index statistics.
+   */
+  String get statistics;
+
+  /**
+   * Record that the given element and location have the given relationship. For example, if the
+   * relationship is the is-referenced-by relationship, then the element would be the element being
+   * referenced and the location would be the point at which it is referenced. Each element can have
+   * the same relationship with multiple locations. In other words, if the following code were
+   * executed
+   *
+   * <pre>
+   *   recordRelationship(element, isReferencedBy, location1);
+   *   recordRelationship(element, isReferencedBy, location2);
+   * </pre>
+   *
+   * then both relationships would be maintained in the index and the result of executing
+   *
+   * <pre>
+   *   getRelationship(element, isReferencedBy);
+   * </pre>
+   *
+   * would be an array containing both <code>location1</code> and <code>location2</code>.
+   *
+   * @param element the element that is related to the location
+   * @param relationship the [Relationship] between the element and the location
+   * @param location the [Location] where relationship happens
+   */
+  void recordRelationship(Element element, Relationship relationship, Location location);
+
+  /**
+   * Remove from the index all of the information associated with [AnalysisContext].
+   *
+   * This method should be invoked when a context is disposed.
+   *
+   * @param the [AnalysisContext] being removed
+   */
+  void removeContext(AnalysisContext context);
+
+  /**
+   * Remove from the index all of the information associated with elements or locations in the given
+   * source. This includes relationships between an element in the given source and any other
+   * locations, relationships between any other elements and a location within the given source.
+   *
+   * This method should be invoked when a source is no longer part of the code base.
+   *
+   * @param the [AnalysisContext] in which [Source] being removed
+   * @param source the source being removed
+   */
+  void removeSource(AnalysisContext context, Source source);
+
+  /**
+   * Remove from the index all of the information associated with elements or locations in the given
+   * sources. This includes relationships between an element in the given sources and any other
+   * locations, relationships between any other elements and a location within the given sources.
+   *
+   * This method should be invoked when multiple sources are no longer part of the code base.
+   *
+   * @param the [AnalysisContext] in which [Source]s being removed
+   * @param container the [SourceContainer] holding the sources being removed
+   */
+  void removeSources(AnalysisContext context, SourceContainer container);
+}
+
+/**
+ * Implementation of [UniverseElement].
+ *
+ * @coverage dart.engine.index
+ */
+class UniverseElementImpl extends ElementImpl implements UniverseElement {
+  static UniverseElementImpl INSTANCE = new UniverseElementImpl();
+
+  UniverseElementImpl() : super.con2("--universe--", -1);
+
+  accept(ElementVisitor visitor) => null;
+
+  ElementKind get kind => ElementKind.UNIVERSE;
+}
+
+/**
+ * Visits resolved AST and adds relationships into [IndexStore].
+ *
+ * @coverage dart.engine.index
+ */
+class IndexContributor extends GeneralizingASTVisitor<Object> {
+  /**
+   * @return the [Location] representing location of the [Element].
+   */
+  static Location createLocation(Element element) {
+    if (element != null) {
+      int offset = element.nameOffset;
+      int length = element.displayName.length;
+      return new Location(element, offset, length);
+    }
+    return null;
+  }
+
+  /**
+   * @return the [ImportElement] that is referenced by this node with [PrefixElement],
+   *         may be `null`.
+   */
+  static ImportElement getImportElement(SimpleIdentifier prefixNode) {
+    IndexContributor_ImportElementInfo info = getImportElementInfo(prefixNode);
+    return info != null ? info._element : null;
+  }
+
+  /**
+   * @return the [ImportElementInfo] with [ImportElement] that is referenced by this
+   *         node with [PrefixElement], may be `null`.
+   */
+  static IndexContributor_ImportElementInfo getImportElementInfo(SimpleIdentifier prefixNode) {
+    IndexContributor_ImportElementInfo info = new IndexContributor_ImportElementInfo();
+    // prepare environment
+    ASTNode parent = prefixNode.parent;
+    CompilationUnit unit = prefixNode.getAncestor(CompilationUnit);
+    LibraryElement libraryElement = unit.element.library;
+    // prepare used element
+    Element usedElement = null;
+    if (parent is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent;
+      usedElement = prefixed.staticElement;
+      info._periodEnd = prefixed.period.end;
+    }
+    if (parent is MethodInvocation) {
+      MethodInvocation invocation = parent;
+      usedElement = invocation.methodName.staticElement;
+      info._periodEnd = invocation.period.end;
+    }
+    // we need used Element
+    if (usedElement == null) {
+      return null;
+    }
+    // find ImportElement
+    String prefix = prefixNode.name;
+    Map<ImportElement, Set<Element>> importElementsMap = {};
+    info._element = getImportElement2(libraryElement, prefix, usedElement, importElementsMap);
+    if (info._element == null) {
+      return null;
+    }
+    return info;
+  }
+
+  /**
+   * @return the [ImportElement] that declares given [PrefixElement] and imports library
+   *         with given "usedElement".
+   */
+  static ImportElement getImportElement2(LibraryElement libraryElement, String prefix, Element usedElement, Map<ImportElement, Set<Element>> importElementsMap) {
+    // validate Element
+    if (usedElement == null) {
+      return null;
+    }
+    if (usedElement.enclosingElement is! CompilationUnitElement) {
+      return null;
+    }
+    LibraryElement usedLibrary = usedElement.library;
+    // find ImportElement that imports used library with used prefix
+    List<ImportElement> candidates = null;
+    for (ImportElement importElement in libraryElement.imports) {
+      // required library
+      if (importElement.importedLibrary != usedLibrary) {
+        continue;
+      }
+      // required prefix
+      PrefixElement prefixElement = importElement.prefix;
+      if (prefix == null) {
+        if (prefixElement != null) {
+          continue;
+        }
+      } else {
+        if (prefixElement == null) {
+          continue;
+        }
+        if (prefix != prefixElement.name) {
+          continue;
+        }
+      }
+      // no combinators => only possible candidate
+      if (importElement.combinators.length == 0) {
+        return importElement;
+      }
+      // OK, we have candidate
+      if (candidates == null) {
+        candidates = [];
+      }
+      candidates.add(importElement);
+    }
+    // no candidates, probably element is defined in this library
+    if (candidates == null) {
+      return null;
+    }
+    // one candidate
+    if (candidates.length == 1) {
+      return candidates[0];
+    }
+    // ensure that each ImportElement has set of elements
+    for (ImportElement importElement in candidates) {
+      if (importElementsMap.containsKey(importElement)) {
+        continue;
+      }
+      Namespace namespace = new NamespaceBuilder().createImportNamespace(importElement);
+      Set<Element> elements = new Set();
+      importElementsMap[importElement] = elements;
+    }
+    // use import namespace to choose correct one
+    for (MapEntry<ImportElement, Set<Element>> entry in getMapEntrySet(importElementsMap)) {
+      if (entry.getValue().contains(usedElement)) {
+        return entry.getKey();
+      }
+    }
+    // not found
+    return null;
+  }
+
+  /**
+   * If the given expression has resolved type, returns the new location with this type.
+   *
+   * @param location the base location
+   * @param expression the expression assigned at the given location
+   */
+  static Location getLocationWithExpressionType(Location location, Expression expression) {
+    if (expression != null) {
+      return new LocationWithData<Type2>.con1(location, expression.bestType);
+    }
+    return location;
+  }
+
+  /**
+   * If the given node is the part of the [ConstructorFieldInitializer], returns location with
+   * type of the initializer expression.
+   */
+  static Location getLocationWithInitializerType(SimpleIdentifier node, Location location) {
+    if (node.parent is ConstructorFieldInitializer) {
+      ConstructorFieldInitializer initializer = node.parent as ConstructorFieldInitializer;
+      if (identical(initializer.fieldName, node)) {
+        location = getLocationWithExpressionType(location, initializer.expression);
+      }
+    }
+    return location;
+  }
+
+  /**
+   * If the given identifier has a synthetic [PropertyAccessorElement], i.e. accessor for
+   * normal field, and it is LHS of assignment, then include [Type] of the assigned value into
+   * the [Location].
+   *
+   * @param identifier the identifier to record location
+   * @param element the element of the identifier
+   * @param location the raw location
+   * @return the [Location] with the type of the assigned value
+   */
+  static Location getLocationWithTypeAssignedToField(SimpleIdentifier identifier, Element element, Location location) {
+    // we need accessor
+    if (element is! PropertyAccessorElement) {
+      return location;
+    }
+    PropertyAccessorElement accessor = element as PropertyAccessorElement;
+    // should be setter
+    if (!accessor.isSetter) {
+      return location;
+    }
+    // accessor should be synthetic, i.e. field normal
+    if (!accessor.isSynthetic) {
+      return location;
+    }
+    // should be LHS of assignment
+    ASTNode parent;
+    {
+      ASTNode node = identifier;
+      parent = node.parent;
+      // new T().field = x;
+      if (parent is PropertyAccess) {
+        PropertyAccess propertyAccess = parent as PropertyAccess;
+        if (identical(propertyAccess.propertyName, node)) {
+          node = propertyAccess;
+          parent = propertyAccess.parent;
+        }
+      }
+      // obj.field = x;
+      if (parent is PrefixedIdentifier) {
+        PrefixedIdentifier prefixedIdentifier = parent as PrefixedIdentifier;
+        if (identical(prefixedIdentifier.identifier, node)) {
+          node = prefixedIdentifier;
+          parent = prefixedIdentifier.parent;
+        }
+      }
+    }
+    // OK, remember the type
+    if (parent is AssignmentExpression) {
+      AssignmentExpression assignment = parent as AssignmentExpression;
+      Expression rhs = assignment.rightHandSide;
+      location = getLocationWithExpressionType(location, rhs);
+    }
+    // done
+    return location;
+  }
+
+  /**
+   * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node".
+   */
+  static bool isIdentifierInPrefixedIdentifier(SimpleIdentifier node) {
+    ASTNode parent = node.parent;
+    return parent is PrefixedIdentifier && identical(parent.identifier, node);
+  }
+
+  /**
+   * @return `true` if given [SimpleIdentifier] is "name" part of prefixed identifier or
+   *         method invocation.
+   */
+  static bool isQualified(SimpleIdentifier node) {
+    ASTNode parent = node.parent;
+    if (parent is PrefixedIdentifier) {
+      return identical(parent.identifier, node);
+    }
+    if (parent is PropertyAccess) {
+      return identical(parent.propertyName, node);
+    }
+    if (parent is MethodInvocation) {
+      MethodInvocation invocation = parent;
+      return invocation.realTarget != null && identical(invocation.methodName, node);
+    }
+    return false;
+  }
+
+  IndexStore _store;
+
+  LibraryElement _libraryElement;
+
+  Map<ImportElement, Set<Element>> _importElementsMap = {};
+
+  /**
+   * A stack whose top element (the element with the largest index) is an element representing the
+   * inner-most enclosing scope.
+   */
+  Queue<Element> _elementStack = new Queue();
+
+  IndexContributor(IndexStore store) {
+    this._store = store;
+  }
+
+  /**
+   * Enter a new scope represented by the given [Element].
+   */
+  void enterScope(Element element) {
+    _elementStack.addFirst(element);
+  }
+
+  /**
+   * @return the inner-most enclosing [Element], may be `null`.
+   */
+  Element peekElement() {
+    for (Element element in _elementStack) {
+      if (element != null) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    recordOperatorReference(node.operator, node.bestElement);
+    return super.visitAssignmentExpression(node);
+  }
+
+  Object visitBinaryExpression(BinaryExpression node) {
+    recordOperatorReference(node.operator, node.bestElement);
+    return super.visitBinaryExpression(node);
+  }
+
+  Object visitClassDeclaration(ClassDeclaration node) {
+    ClassElement element = node.element;
+    enterScope(element);
+    try {
+      recordElementDefinition(element, IndexConstants.DEFINES_CLASS);
+      {
+        ExtendsClause extendsClause = node.extendsClause;
+        if (extendsClause != null) {
+          TypeName superclassNode = extendsClause.superclass;
+          recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
+        } else {
+          InterfaceType superType = element.supertype;
+          if (superType != null) {
+            ClassElement objectElement = superType.element;
+            recordRelationship(objectElement, IndexConstants.IS_EXTENDED_BY, createLocation3(node.name.offset, 0));
+          }
+        }
+      }
+      {
+        WithClause withClause = node.withClause;
+        if (withClause != null) {
+          for (TypeName mixinNode in withClause.mixinTypes) {
+            recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
+          }
+        }
+      }
+      {
+        ImplementsClause implementsClause = node.implementsClause;
+        if (implementsClause != null) {
+          for (TypeName interfaceNode in implementsClause.interfaces) {
+            recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
+          }
+        }
+      }
+      return super.visitClassDeclaration(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    ClassElement element = node.element;
+    enterScope(element);
+    try {
+      recordElementDefinition(element, IndexConstants.DEFINES_CLASS_ALIAS);
+      {
+        TypeName superclassNode = node.superclass;
+        if (superclassNode != null) {
+          recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
+        }
+      }
+      {
+        WithClause withClause = node.withClause;
+        if (withClause != null) {
+          for (TypeName mixinNode in withClause.mixinTypes) {
+            recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
+          }
+        }
+      }
+      {
+        ImplementsClause implementsClause = node.implementsClause;
+        if (implementsClause != null) {
+          for (TypeName interfaceNode in implementsClause.interfaces) {
+            recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
+          }
+        }
+      }
+      return super.visitClassTypeAlias(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitCompilationUnit(CompilationUnit node) {
+    CompilationUnitElement unitElement = node.element;
+    if (unitElement != null) {
+      _elementStack.add(unitElement);
+      _libraryElement = unitElement.enclosingElement;
+      if (_libraryElement != null) {
+        return super.visitCompilationUnit(node);
+      }
+    }
+    return null;
+  }
+
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    ConstructorElement element = node.element;
+    // define
+    {
+      Location location;
+      if (node.name != null) {
+        int start = node.period.offset;
+        int end = node.name.end;
+        location = createLocation3(start, end - start);
+      } else {
+        int start = node.returnType.end;
+        location = createLocation3(start, 0);
+      }
+      recordRelationship(element, IndexConstants.IS_DEFINED_BY, location);
+    }
+    // visit children
+    enterScope(element);
+    try {
+      return super.visitConstructorDeclaration(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitConstructorName(ConstructorName node) {
+    ConstructorElement element = node.staticElement;
+    Location location;
+    if (node.name != null) {
+      int start = node.period.offset;
+      int end = node.name.end;
+      location = createLocation3(start, end - start);
+    } else {
+      int start = node.type.end;
+      location = createLocation3(start, 0);
+    }
+    recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    return super.visitConstructorName(node);
+  }
+
+  Object visitExportDirective(ExportDirective node) {
+    ExportElement element = node.element as ExportElement;
+    if (element != null) {
+      LibraryElement expLibrary = element.exportedLibrary;
+      recordLibraryReference(node, expLibrary);
+    }
+    return super.visitExportDirective(node);
+  }
+
+  Object visitFormalParameter(FormalParameter node) {
+    ParameterElement element = node.element;
+    enterScope(element);
+    try {
+      return super.visitFormalParameter(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    Element element = node.element;
+    recordElementDefinition(element, IndexConstants.DEFINES_FUNCTION);
+    enterScope(element);
+    try {
+      return super.visitFunctionDeclaration(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    Element element = node.element;
+    recordElementDefinition(element, IndexConstants.DEFINES_FUNCTION_TYPE);
+    return super.visitFunctionTypeAlias(node);
+  }
+
+  Object visitImportDirective(ImportDirective node) {
+    ImportElement element = node.element;
+    if (element != null) {
+      LibraryElement impLibrary = element.importedLibrary;
+      recordLibraryReference(node, impLibrary);
+    }
+    return super.visitImportDirective(node);
+  }
+
+  Object visitIndexExpression(IndexExpression node) {
+    MethodElement element = node.bestElement;
+    if (element is MethodElement) {
+      Token operator = node.leftBracket;
+      Location location = createLocation4(operator);
+      recordRelationship(element, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
+    }
+    return super.visitIndexExpression(node);
+  }
+
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    ExecutableElement element = node.element;
+    enterScope(element);
+    try {
+      return super.visitMethodDeclaration(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitMethodInvocation(MethodInvocation node) {
+    SimpleIdentifier name = node.methodName;
+    Element element = name.bestElement;
+    if (element is MethodElement) {
+      Location location = createLocation2(name);
+      Relationship relationship;
+      if (node.target != null) {
+        relationship = IndexConstants.IS_INVOKED_BY_QUALIFIED;
+      } else {
+        relationship = IndexConstants.IS_INVOKED_BY_UNQUALIFIED;
+      }
+      recordRelationship(element, relationship, location);
+    }
+    if (element is FunctionElement) {
+      Location location = createLocation2(name);
+      recordRelationship(element, IndexConstants.IS_INVOKED_BY, location);
+    }
+    recordImportElementReferenceWithoutPrefix(name);
+    return super.visitMethodInvocation(node);
+  }
+
+  Object visitPartDirective(PartDirective node) {
+    Element element = node.element;
+    Location location = createLocation2(node.uri);
+    recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    return super.visitPartDirective(node);
+  }
+
+  Object visitPartOfDirective(PartOfDirective node) {
+    Location location = createLocation2(node.libraryName);
+    recordRelationship(node.element, IndexConstants.IS_REFERENCED_BY, location);
+    return null;
+  }
+
+  Object visitPostfixExpression(PostfixExpression node) {
+    recordOperatorReference(node.operator, node.bestElement);
+    return super.visitPostfixExpression(node);
+  }
+
+  Object visitPrefixExpression(PrefixExpression node) {
+    recordOperatorReference(node.operator, node.bestElement);
+    return super.visitPrefixExpression(node);
+  }
+
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    Element nameElement = new NameElementImpl(node.name);
+    Location location = createLocation2(node);
+    // name in declaration
+    if (node.inDeclarationContext()) {
+      recordRelationship(nameElement, IndexConstants.IS_DEFINED_BY, location);
+      return null;
+    }
+    // prepare information
+    Element element = node.bestElement;
+    // qualified name reference
+    recordQualifiedMemberReference(node, element, nameElement, location);
+    // stop if already handled
+    if (isAlreadyHandledName(node)) {
+      return null;
+    }
+    // record specific relations
+    if (element is ClassElement || element is FunctionElement || element is FunctionTypeAliasElement || element is LabelElement || element is TypeParameterElement) {
+      recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    } else if (element is FieldElement) {
+      location = getLocationWithInitializerType(node, location);
+      recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    } else if (element is FieldFormalParameterElement) {
+      FieldFormalParameterElement fieldParameter = element;
+      FieldElement field = fieldParameter.field;
+      recordRelationship(field, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
+    } else if (element is PrefixElement) {
+      recordImportElementReferenceWithPrefix(node);
+    } else if (element is PropertyAccessorElement || element is MethodElement) {
+      location = getLocationWithTypeAssignedToField(node, element, location);
+      if (isQualified(node)) {
+        recordRelationship(element, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
+      } else {
+        recordRelationship(element, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
+      }
+    } else if (element is ParameterElement || element is LocalVariableElement) {
+      bool inGetterContext = node.inGetterContext();
+      bool inSetterContext = node.inSetterContext();
+      if (inGetterContext && inSetterContext) {
+        recordRelationship(element, IndexConstants.IS_READ_WRITTEN_BY, location);
+      } else if (inGetterContext) {
+        recordRelationship(element, IndexConstants.IS_READ_BY, location);
+      } else if (inSetterContext) {
+        recordRelationship(element, IndexConstants.IS_WRITTEN_BY, location);
+      } else {
+        recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+      }
+    }
+    recordImportElementReferenceWithoutPrefix(node);
+    return super.visitSimpleIdentifier(node);
+  }
+
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    ConstructorElement element = node.staticElement;
+    Location location;
+    if (node.constructorName != null) {
+      int start = node.period.offset;
+      int end = node.constructorName.end;
+      location = createLocation3(start, end - start);
+    } else {
+      int start = node.keyword.end;
+      location = createLocation3(start, 0);
+    }
+    recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+    return super.visitSuperConstructorInvocation(node);
+  }
+
+  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    VariableDeclarationList variables = node.variables;
+    for (VariableDeclaration variableDeclaration in variables.variables) {
+      Element element = variableDeclaration.element;
+      recordElementDefinition(element, IndexConstants.DEFINES_VARIABLE);
+    }
+    return super.visitTopLevelVariableDeclaration(node);
+  }
+
+  Object visitTypeParameter(TypeParameter node) {
+    TypeParameterElement element = node.element;
+    enterScope(element);
+    try {
+      return super.visitTypeParameter(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    VariableElement element = node.element;
+    // record declaration
+    {
+      SimpleIdentifier name = node.name;
+      Location location = createLocation2(name);
+      location = getLocationWithExpressionType(location, node.initializer);
+      recordRelationship(element, IndexConstants.IS_DEFINED_BY, location);
+    }
+    // visit
+    enterScope(element);
+    try {
+      return super.visitVariableDeclaration(node);
+    } finally {
+      exitScope();
+    }
+  }
+
+  Object visitVariableDeclarationList(VariableDeclarationList node) {
+    NodeList<VariableDeclaration> variables = node.variables;
+    if (variables != null) {
+      // use first VariableDeclaration as Element for Location(s) in type
+      {
+        TypeName type = node.type;
+        if (type != null) {
+          for (VariableDeclaration variableDeclaration in variables) {
+            enterScope(variableDeclaration.element);
+            try {
+              type.accept(this);
+            } finally {
+              exitScope();
+            }
+            // only one iteration
+            break;
+          }
+        }
+      }
+      // visit variables
+      variables.accept(this);
+    }
+    return null;
+  }
+
+  /**
+   * @return the [Location] representing location of the [ASTNode].
+   */
+  Location createLocation2(ASTNode node) => createLocation3(node.offset, node.length);
+
+  /**
+   * @param offset the offset of the location within [Source]
+   * @param length the length of the location
+   * @return the [Location] representing the given offset and length within the inner-most
+   *         [Element].
+   */
+  Location createLocation3(int offset, int length) {
+    Element element = peekElement();
+    return new Location(element, offset, length);
+  }
+
+  /**
+   * @return the [Location] representing location of the [Token].
+   */
+  Location createLocation4(Token token) => createLocation3(token.offset, token.length);
+
+  /**
+   * Exit the current scope.
+   */
+  void exitScope() {
+    _elementStack.removeFirst();
+  }
+
+  /**
+   * @return `true` if given node already indexed as more interesting reference, so it should
+   *         not be indexed again.
+   */
+  bool isAlreadyHandledName(SimpleIdentifier node) {
+    ASTNode parent = node.parent;
+    if (parent is MethodInvocation) {
+      Element element = node.staticElement;
+      if (element is MethodElement || element is FunctionElement) {
+        return identical(parent.methodName, node);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Records the [Element] definition in the library and universe.
+   */
+  void recordElementDefinition(Element element, Relationship relationship) {
+    Location location = createLocation(element);
+    recordRelationship(_libraryElement, relationship, location);
+    recordRelationship(IndexConstants.UNIVERSE, relationship, location);
+  }
+
+  /**
+   * Records [ImportElement] reference if given [SimpleIdentifier] references some
+   * top-level element and not qualified with import prefix.
+   */
+  void recordImportElementReferenceWithoutPrefix(SimpleIdentifier node) {
+    if (isIdentifierInPrefixedIdentifier(node)) {
+      return;
+    }
+    Element element = node.staticElement;
+    ImportElement importElement = getImportElement2(_libraryElement, null, element, _importElementsMap);
+    if (importElement != null) {
+      Location location = createLocation3(node.offset, 0);
+      recordRelationship(importElement, IndexConstants.IS_REFERENCED_BY, location);
+    }
+  }
+
+  /**
+   * Records [ImportElement] that declares given prefix and imports library with element used
+   * with given prefix node.
+   */
+  void recordImportElementReferenceWithPrefix(SimpleIdentifier prefixNode) {
+    IndexContributor_ImportElementInfo info = getImportElementInfo(prefixNode);
+    if (info != null) {
+      int offset = prefixNode.offset;
+      int length = info._periodEnd - offset;
+      Location location = createLocation3(offset, length);
+      recordRelationship(info._element, IndexConstants.IS_REFERENCED_BY, location);
+    }
+  }
+
+  /**
+   * Records reference to defining [CompilationUnitElement] of the given
+   * [LibraryElement].
+   */
+  void recordLibraryReference(UriBasedDirective node, LibraryElement library) {
+    if (library != null) {
+      Location location = createLocation2(node.uri);
+      recordRelationship(library.definingCompilationUnit, IndexConstants.IS_REFERENCED_BY, location);
+    }
+  }
+
+  /**
+   * Record reference to the given operator [Element] and name.
+   */
+  void recordOperatorReference(Token operator, Element element) {
+    // prepare location
+    Location location = createLocation4(operator);
+    // record name reference
+    {
+      String name = operator.lexeme;
+      if (name == "++") {
+        name = "+";
+      }
+      if (name == "--") {
+        name = "-";
+      }
+      if (name.endsWith("=") && name != "==") {
+        name = name.substring(0, name.length - 1);
+      }
+      Element nameElement = new NameElementImpl(name);
+      Relationship relationship = element != null ? IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED : IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED;
+      recordRelationship(nameElement, relationship, location);
+    }
+    // record element reference
+    if (element != null) {
+      recordRelationship(element, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
+    }
+  }
+
+  /**
+   * Records reference if the given [SimpleIdentifier] looks like a qualified property access
+   * or method invocation.
+   */
+  void recordQualifiedMemberReference(SimpleIdentifier node, Element element, Element nameElement, Location location) {
+    if (isQualified(node)) {
+      Relationship relationship = element != null ? IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED : IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED;
+      recordRelationship(nameElement, relationship, location);
+    }
+  }
+
+  /**
+   * Record the given relationship between the given [Element] and [Location].
+   */
+  void recordRelationship(Element element, Relationship relationship, Location location) {
+    if (element != null && location != null) {
+      _store.recordRelationship(element, relationship, location);
+    }
+  }
+
+  /**
+   * Records extends/implements relationships between given [ClassElement] and [Type] of
+   * "superNode".
+   */
+  void recordSuperType(TypeName superNode, Relationship relationship) {
+    if (superNode != null) {
+      Identifier superName = superNode.name;
+      if (superName != null) {
+        Element superElement = superName.staticElement;
+        recordRelationship(superElement, relationship, createLocation2(superNode));
+      }
+    }
+  }
+}
+
+/**
+ * Information about [ImportElement] and place where it is referenced using
+ * [PrefixElement].
+ */
+class IndexContributor_ImportElementInfo {
+  ImportElement _element;
+
+  int _periodEnd = 0;
+}
+
+/**
+ * Factory for [Index] and [IndexStore].
+ *
+ * @coverage dart.engine.index
+ */
+class IndexFactory {
+  /**
+   * @return the new instance of [Index] which uses given [IndexStore].
+   */
+  static Index newIndex(IndexStore store) {
+    OperationQueue queue = new OperationQueue();
+    OperationProcessor processor = new OperationProcessor(queue);
+    return new IndexImpl(store, queue, processor);
+  }
+
+  /**
+   * @return the new instance of [MemoryIndexStore].
+   */
+  static MemoryIndexStore newMemoryIndexStore() => new MemoryIndexStoreImpl();
+}
+
+/**
+ * Instances of the [OperationQueue] represent a queue of operations against the index that
+ * are waiting to be performed.
+ *
+ * @coverage dart.engine.index
+ */
+class OperationQueue {
+  /**
+   * The non-query operations that are waiting to be performed.
+   */
+  Queue<IndexOperation> _nonQueryOperations = new Queue();
+
+  /**
+   * The query operations that are waiting to be performed.
+   */
+  Queue<IndexOperation> _queryOperations = new Queue();
+
+  /**
+   * `true` if query operations should be returned by [dequeue] or {code false}
+   * if not.
+   */
+  bool _processQueries = true;
+
+  /**
+   * If this queue is not empty, then remove the next operation from the head of this queue and
+   * return it. If this queue is empty (see [setProcessQueries], then the behavior
+   * of this method depends on the value of the argument. If the argument is less than or equal to
+   * zero (<code>0</code>), then `null` will be returned immediately. If the argument is
+   * greater than zero, then this method will wait until at least one operation has been added to
+   * this queue or until the given amount of time has passed. If, at the end of that time, this
+   * queue is empty, then `null` will be returned. If this queue is not empty, then the first
+   * operation will be removed and returned.
+   *
+   * Note that `null` can be returned, even if a positive timeout is given.
+   *
+   * Note too that this method's timeout is not treated the same way as the timeout value used for
+   * [Object#wait]. In particular, it is not possible to cause this method to wait for
+   * an indefinite period of time.
+   *
+   * @param timeout the maximum number of milliseconds to wait for an operation to be available
+   *          before giving up and returning `null`
+   * @return the operation that was removed from the queue
+   * @throws InterruptedException if the thread on which this method is running was interrupted
+   *           while it was waiting for an operation to be added to the queue
+   */
+  IndexOperation dequeue(int timeout) {
+    {
+      if (_nonQueryOperations.isEmpty && (!_processQueries || _queryOperations.isEmpty)) {
+        if (timeout <= 0) {
+          return null;
+        }
+        waitForOperationAvailable(timeout);
+      }
+      if (!_nonQueryOperations.isEmpty) {
+        return _nonQueryOperations.removeFirst();
+      }
+      if (_processQueries && !_queryOperations.isEmpty) {
+        return _queryOperations.removeFirst();
+      }
+      return null;
+    }
+  }
+
+  /**
+   * Add the given operation to the tail of this queue.
+   *
+   * @param operation the operation to be added to the queue
+   */
+  void enqueue(IndexOperation operation) {
+    {
+      if (operation is RemoveSourceOperation) {
+        Source source = operation.source;
+        removeForSource(source, _nonQueryOperations);
+        removeForSource(source, _queryOperations);
+      }
+      if (operation.isQuery) {
+        _queryOperations.add(operation);
+      } else {
+        _nonQueryOperations.add(operation);
+      }
+      notifyOperationAvailable();
+    }
+  }
+
+  /**
+   * Return a list containing all of the operations that are currently on the queue. Modifying this
+   * list will not affect the state of the queue.
+   *
+   * @return all of the operations that are currently on the queue
+   */
+  List<IndexOperation> get operations {
+    List<IndexOperation> operations = [];
+    {
+      operations.addAll(_nonQueryOperations);
+      operations.addAll(_queryOperations);
+    }
+    return operations;
+  }
+
+  /**
+   * Set whether the receiver's [dequeue] method should return query operations.
+   *
+   * @param processQueries `true` if the receiver's [dequeue] method should
+   *          return query operations or `false` if query operations should be queued but not
+   *          returned by the receiver's [dequeue] method until this method is called
+   *          with a value of `true`.
+   */
+  void set processQueries(bool processQueries) {
+    {
+      if (this._processQueries != processQueries) {
+        this._processQueries = processQueries;
+        if (processQueries && !_queryOperations.isEmpty) {
+          notifyOperationAvailable();
+        }
+      }
+    }
+  }
+
+  /**
+   * Return the number of operations on the queue.
+   *
+   * @return the number of operations on the queue
+   */
+  int size() {
+    {
+      return _nonQueryOperations.length + _queryOperations.length;
+    }
+  }
+
+  void notifyOperationAvailable() {
+  }
+
+  /**
+   * Removes operations that should be removed when given [Source] is removed.
+   */
+  void removeForSource(Source source, Queue<IndexOperation> operations) {
+    operations.removeWhere((_) => _.removeWhenSourceRemoved(source));
+  }
+
+  void waitForOperationAvailable(int timeout) {
+  }
+}
+
+/**
+ * Special [Element] which is used to index references to the name without specifying concrete
+ * kind of this name - field, method or something else.
+ *
+ * @coverage dart.engine.index
+ */
+class NameElementImpl extends ElementImpl {
+  NameElementImpl(String name) : super.con2("name:${name}", -1);
+
+  accept(ElementVisitor visitor) => null;
+
+  ElementKind get kind => ElementKind.NAME;
+}
+
+/**
+ * Visits resolved [CompilationUnit] and adds Angular specific relationships into
+ * [IndexStore].
+ *
+ * @coverage dart.engine.index
+ */
+class AngularDartIndexContributor extends GeneralizingASTVisitor<Object> {
+  IndexStore _store;
+
+  AngularDartIndexContributor(IndexStore store) {
+    this._store = store;
+  }
+
+  Object visitClassDeclaration(ClassDeclaration node) {
+    ClassElement classElement = node.element;
+    if (classElement != null) {
+      List<ToolkitObjectElement> toolkitObjects = classElement.toolkitObjects;
+      for (ToolkitObjectElement object in toolkitObjects) {
+        if (object is AngularComponentElement) {
+          indexComponent(object);
+        }
+        if (object is AngularDirectiveElement) {
+          AngularDirectiveElement directive = object;
+          indexDirective(directive);
+        }
+      }
+    }
+    // stop visiting
+    return null;
+  }
+
+  Object visitCompilationUnitMember(CompilationUnitMember node) => null;
+
+  void indexComponent(AngularComponentElement component) {
+    indexProperties(component.properties);
+  }
+
+  void indexDirective(AngularDirectiveElement directive) {
+    indexProperties(directive.properties);
+  }
+
+  void indexProperties(List<AngularPropertyElement> properties) {
+    for (AngularPropertyElement property in properties) {
+      FieldElement field = property.field;
+      if (field != null) {
+        int offset = property.fieldNameOffset;
+        int length = field.name.length;
+        Location location = new Location(property, offset, length);
+        // getter reference
+        if (property.propertyKind.callsGetter()) {
+          PropertyAccessorElement getter = field.getter;
+          if (getter != null) {
+            _store.recordRelationship(getter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
+          }
+        }
+        // setter reference
+        if (property.propertyKind.callsSetter()) {
+          PropertyAccessorElement setter = field.setter;
+          if (setter != null) {
+            _store.recordRelationship(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Instances of the [RemoveContextOperation] implement an operation that removes from the
+ * index any data based on the specified [AnalysisContext].
+ *
+ * @coverage dart.engine.index
+ */
+class RemoveContextOperation implements IndexOperation {
+  /**
+   * The index store against which this operation is being run.
+   */
+  IndexStore _indexStore;
+
+  /**
+   * The context being removed.
+   */
+  final AnalysisContext context;
+
+  /**
+   * Initialize a newly created operation that will remove the specified resource.
+   *
+   * @param indexStore the index store against which this operation is being run
+   * @param context the [AnalysisContext] to remove
+   */
+  RemoveContextOperation(IndexStore indexStore, this.context) {
+    this._indexStore = indexStore;
+  }
+
+  bool get isQuery => false;
+
+  void performOperation() {
+    {
+      _indexStore.removeContext(context);
+    }
+  }
+
+  bool removeWhenSourceRemoved(Source source) => false;
+
+  String toString() => "RemoveContext(${context})";
+}
+
+/**
+ * Instances of the [IndexHtmlUnitOperation] implement an operation that adds data to the
+ * index based on the resolved [HtmlUnit].
+ *
+ * @coverage dart.engine.index
+ */
+class IndexHtmlUnitOperation implements IndexOperation {
+  /**
+   * The index store against which this operation is being run.
+   */
+  IndexStore _indexStore;
+
+  /**
+   * The context in which [HtmlUnit] was resolved.
+   */
+  AnalysisContext _context;
+
+  /**
+   * The [HtmlUnit] being indexed.
+   */
+  final ht.HtmlUnit unit;
+
+  /**
+   * The element of the [HtmlUnit] being indexed.
+   */
+  HtmlElement _htmlElement;
+
+  /**
+   * The source being indexed.
+   */
+  Source _source;
+
+  /**
+   * Initialize a newly created operation that will index the specified [HtmlUnit].
+   *
+   * @param indexStore the index store against which this operation is being run
+   * @param context the context in which [HtmlUnit] was resolved
+   * @param unit the fully resolved [HtmlUnit]
+   */
+  IndexHtmlUnitOperation(IndexStore indexStore, AnalysisContext context, this.unit) {
+    this._indexStore = indexStore;
+    this._context = context;
+    this._htmlElement = unit.element;
+    this._source = _htmlElement.source;
+  }
+
+  /**
+   * @return the [Source] to be indexed.
+   */
+  Source get source => _source;
+
+  bool get isQuery => false;
+
+  void performOperation() {
+    {
+      try {
+        bool mayIndex = _indexStore.aboutToIndex2(_context, _source);
+        if (!mayIndex) {
+          return;
+        }
+        AngularHtmlIndexContributor contributor = new AngularHtmlIndexContributor(_indexStore);
+        unit.accept(contributor);
+      } catch (exception) {
+        AnalysisEngine.instance.logger.logError2("Could not index ${unit.element.location}", exception);
+      }
+    }
+  }
+
+  bool removeWhenSourceRemoved(Source source) => this._source == source;
+
+  String toString() => "IndexHtmlUnitOperation(${_source.fullName})";
+}
+
+/**
+ * Instances of the class <code>Location</code> represent a location related to an element. The
+ * location is expressed as an offset and length, but the offset is relative to the resource
+ * containing the element rather than the start of the element within that resource.
+ *
+ * @coverage dart.engine.index
+ */
+class Location {
+  /**
+   * An empty array of locations.
+   */
+  static List<Location> EMPTY_ARRAY = new List<Location>(0);
+
+  /**
+   * The element containing this location.
+   */
+  final Element element;
+
+  /**
+   * The offset of this location within the resource containing the element.
+   */
+  final int offset;
+
+  /**
+   * The length of this location.
+   */
+  final int length;
+
+  /**
+   * Internal field used to hold a key that is referenced at this location.
+   */
+  Object internalKey;
+
+  /**
+   * Initialize a newly create location to be relative to the given element at the given offset with
+   * the given length.
+   *
+   * @param element the [Element] containing this location
+   * @param offset the offset of this location within the resource containing the element
+   * @param length the length of this location
+   */
+  Location(this.element, this.offset, this.length) {
+    if (element == null) {
+      throw new IllegalArgumentException("element location cannot be null");
+    }
+  }
+
+  Location clone() => new Location(element, offset, length);
+
+  String toString() => "[${offset} - ${(offset + length)}) in ${element}";
+}
+
+/**
+ * [IndexStore] which keeps all information in memory, but can write it to stream and read
+ * later.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class MemoryIndexStore implements IndexStore {
+}
+
+/**
+ * Instances of the [GetRelationshipsOperation] implement an operation used to access the
+ * locations that have a specified relationship with a specified element.
+ *
+ * @coverage dart.engine.index
+ */
+class GetRelationshipsOperation implements IndexOperation {
+  IndexStore _indexStore;
+
+  final Element element;
+
+  final Relationship relationship;
+
+  final RelationshipCallback callback;
+
+  /**
+   * Initialize a newly created operation that will access the locations that have a specified
+   * relationship with a specified element.
+   */
+  GetRelationshipsOperation(IndexStore indexStore, this.element, this.relationship, this.callback) {
+    this._indexStore = indexStore;
+  }
+
+  bool get isQuery => true;
+
+  void performOperation() {
+    List<Location> locations;
+    {
+      locations = _indexStore.getRelationships(element, relationship);
+    }
+    callback.hasRelationships(element, relationship, locations);
+  }
+
+  bool removeWhenSourceRemoved(Source source) => false;
+
+  String toString() => "GetRelationships(${element}, ${relationship})";
+}
+
+/**
+ * [Location] with attached data.
+ */
+class LocationWithData<D> extends Location {
+  final D data;
+
+  LocationWithData.con1(Location location, this.data) : super(location.element, location.offset, location.length);
+
+  LocationWithData.con2(Element element, int offset, int length, this.data) : super(element, offset, length);
+
+  Location clone() => new LocationWithData<D>.con2(element, offset, length, data);
+}
+
+/**
+ * The interface <code>RelationshipCallback</code> defines the behavior of objects that are invoked
+ * with the results of a query about a given relationship.
+ *
+ * @coverage dart.engine.index
+ */
+abstract class RelationshipCallback {
+  /**
+   * This method is invoked when the locations that have a specified relationship with a specified
+   * element are available. For example, if the element is a field and the relationship is the
+   * is-referenced-by relationship, then this method will be invoked with each location at which the
+   * field is referenced.
+   *
+   * @param element the [Element] that has the relationship with the locations
+   * @param relationship the relationship between the given element and the locations
+   * @param locations the locations that were found
+   */
+  void hasRelationships(Element element, Relationship relationship, List<Location> locations);
+}
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/generated/instrumentation.dart b/pkg/analyzer/lib/src/generated/instrumentation.dart
index f75ac2a..0a89639 100644
--- a/pkg/analyzer/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer/lib/src/generated/instrumentation.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -40,13 +44,13 @@
   /**
    * A builder that will silently ignore all data and logging requests.
    */
-  static InstrumentationBuilder _NULL_INSTRUMENTATION_BUILDER = new InstrumentationBuilder_18();
+  static InstrumentationBuilder _NULL_INSTRUMENTATION_BUILDER = new InstrumentationBuilder_Instrumentation_NULL_INSTRUMENTATION_BUILDER();
 
   /**
    * 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_19();
+  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_Instrumentation_NULL_LOGGER();
 
   /**
    * The current instrumentation logger.
@@ -99,7 +103,7 @@
   }
 }
 
-class InstrumentationBuilder_18 implements InstrumentationBuilder {
+class InstrumentationBuilder_Instrumentation_NULL_INSTRUMENTATION_BUILDER implements InstrumentationBuilder {
   InstrumentationBuilder data(String name, bool value) => this;
 
   InstrumentationBuilder data2(String name, int value) => this;
@@ -127,7 +131,7 @@
   InstrumentationBuilder record(Exception exception) => this;
 }
 
-class InstrumentationLogger_19 implements InstrumentationLogger {
+class InstrumentationLogger_Instrumentation_NULL_LOGGER implements InstrumentationLogger {
   InstrumentationBuilder createBuilder(String name) => Instrumentation._NULL_INSTRUMENTATION_BUILDER;
 }
 
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index ea75f59..574cba4 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -14,70 +14,77 @@
   }
 }
 
+Stopwatch instanceOfTimer = new Stopwatch();
+
 /**
  * Limited implementation of "o is instanceOfType", see
  * http://code.google.com/p/dart/issues/detail?id=8184
  */
 bool isInstanceOf(o, Type t) {
-  if (o == null) {
+  instanceOfTimer.start();
+  try {
+    if (o == null) {
+      return false;
+    }
+    if (o.runtimeType == t) {
+      return true;
+    }
+    String oTypeName = o.runtimeType.toString();
+    String tTypeName = t.toString();
+    if (oTypeName == tTypeName) {
+      return true;
+    }
+    if (oTypeName.startsWith("List") && tTypeName == "List") {
+      return true;
+    }
+    if (tTypeName == "Map" && o is Map) {
+      return true;
+    }
+    // Dart Analysis Engine specific
+    if (oTypeName == "${tTypeName}Impl") {
+      return true;
+    }
+    if (tTypeName == "FormalParameter") {
+      return
+          oTypeName == "DefaultFormalParameter" ||
+          oTypeName == "FieldNormalParameter" ||
+          oTypeName == "FunctionTypedFormalParameter" ||
+          oTypeName == "SimpleFormalParameter";
+    }
+    if (tTypeName == "MethodElement") {
+      if (oTypeName == "MethodMember") {
+        return true;
+      }
+    }
+    if (tTypeName == "ExecutableElement") {
+      if (oTypeName == "MethodElementImpl" ||
+          oTypeName == "FunctionElementImpl" ||
+          oTypeName == "PropertyAccessorElementImpl") {
+        return true;
+      }
+    }
+    if (tTypeName == "ParameterElement") {
+      if (oTypeName == "FieldFormalParameterElementImpl" ||
+          oTypeName == "DefaultFieldFormalParameterElementImpl" ||
+          oTypeName == "DefaultParameterElementImpl") {
+        return true;
+      }
+    }
+    if (tTypeName == "VariableElement") {
+      if (oTypeName == "LocalVariableElementImpl" ||
+          oTypeName == "ConstLocalVariableElementImpl" ||
+          oTypeName == "FieldElementImpl" ||
+          oTypeName == "ConstFieldElementImpl" ||
+          oTypeName == "TopLevelVariableElementImpl" ||
+          oTypeName == "ConstTopLevelVariableElementImpl") {
+        return true;
+      }
+    }
+    // no
     return false;
+  } finally {
+    instanceOfTimer.stop();
   }
-  if (o.runtimeType == t) {
-    return true;
-  }
-  String oTypeName = o.runtimeType.toString();
-  String tTypeName = t.toString();
-  if (oTypeName == tTypeName) {
-    return true;
-  }
-  if (oTypeName.startsWith("List") && tTypeName == "List") {
-    return true;
-  }
-  if (tTypeName == "Map" && o is Map) {
-    return true;
-  }
-  // Dart Analysis Engine specific
-  if (oTypeName == "${tTypeName}Impl") {
-    return true;
-  }
-  if (tTypeName == "FormalParameter") {
-    return
-        oTypeName == "DefaultFormalParameter" ||
-        oTypeName == "FieldNormalParameter" ||
-        oTypeName == "FunctionTypedFormalParameter" ||
-        oTypeName == "SimpleFormalParameter";
-  }
-  if (tTypeName == "MethodElement") {
-    if (oTypeName == "MethodMember") {
-      return true;
-    }
-  }
-  if (tTypeName == "ExecutableElement") {
-    if (oTypeName == "MethodElementImpl" ||
-        oTypeName == "FunctionElementImpl" ||
-        oTypeName == "PropertyAccessorElementImpl") {
-      return true;
-    }
-  }
-  if (tTypeName == "ParameterElement") {
-    if (oTypeName == "FieldFormalParameterElementImpl" ||
-        oTypeName == "DefaultFieldFormalParameterElementImpl" ||
-        oTypeName == "DefaultParameterElementImpl") {
-      return true;
-    }
-  }
-  if (tTypeName == "VariableElement") {
-    if (oTypeName == "LocalVariableElementImpl" ||
-        oTypeName == "ConstLocalVariableElementImpl" ||
-        oTypeName == "FieldElementImpl" ||
-        oTypeName == "ConstFieldElementImpl" ||
-        oTypeName == "TopLevelVariableElementImpl" ||
-        oTypeName == "ConstTopLevelVariableElementImpl") {
-      return true;
-    }
-  }
-  // no
-  return false;
 }
 
 class JavaArrays {
@@ -115,11 +122,14 @@
   static const int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
   static const int MIN_LOW_SURROGATE  = 0xDC00;
   static const int MIN_HIGH_SURROGATE = 0xD800;
+  static bool isDigit(int c) {
+    return c >= 0x30 && c <= 0x39;
+  }
   static bool isLetter(int c) {
     return c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A;
   }
   static bool isLetterOrDigit(int c) {
-    return isLetter(c) || c >= 0x30 && c <= 0x39;
+    return isLetter(c) || isDigit(c);
   }
   static bool isWhitespace(int c) {
     return c == 0x09 || c == 0x20 || c == 0x0A || c == 0x0D;
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index 21a205b..a6ae444 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -1,9 +1,29 @@
 library java.engine;
 
+import 'java_core.dart';
+
 class StringUtilities {
   static const String EMPTY = '';
   static const List<String> EMPTY_ARRAY = const <String> [];
   static String intern(String s) => s;
+  static bool isTagName(String s) {
+    if (s == null || s.length == 0) {
+      return false;
+    }
+    int sz = s.length;
+    for (int i = 0; i < sz; i++) {
+      int c = s.codeUnitAt(i);
+      if (!Character.isLetter(c)) {
+        if (i == 0) {
+          return false;
+        }
+        if (!Character.isDigit(c) && c != 0x2D) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
   static String substringBefore(String str, String separator) {
     if (str == null || str.isEmpty) {
       return str;
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 7576839..bdd7fd8 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -23,19 +23,13 @@
       return '\n';
     }
     if (name == 'com.google.dart.sdk') {
-      String value = Platform.environment['DART_SDK'];
-      if (value != null) {
-        _properties[name] = value;
-        return value;
-      }
-    }
-    if (name == 'com.google.dart.sdk') {
       String exec = Platform.executable;
       if (exec.length != 0) {
         String sdkPath;
-        // may be "xcodebuild/ReleaseIA32/dart" with "dart-sdk" sibling
+        // may be "xcodebuild/ReleaseIA32/dart" with "sdk" sibling
         {
-          sdkPath = pathos.join(pathos.dirname(exec), "dart-sdk");
+          var outDir = pathos.dirname(pathos.dirname(exec));
+          sdkPath = pathos.join(pathos.dirname(outDir), "sdk");
           if (new Directory(sdkPath).existsSync()) {
             _properties[name] = sdkPath;
             return sdkPath;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 2d26f34..4e99c1b 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -213,17 +217,21 @@
 
   ASTNode visitAssertStatement(AssertStatement node) {
     if (identical(_oldNode, node.condition)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
 
   ASTNode visitAssignmentExpression(AssignmentExpression node) {
     if (identical(_oldNode, node.leftHandSide)) {
+      // TODO(brianwilkerson) If the assignment is part of a cascade section, then we don't have a
+      // single parse method that will work. Otherwise, we can parse a conditional expression, but
+      // need to ensure that the resulting expression is assignable.
+      // return parser.parseConditionalExpression();
       throw new InsufficientContextException();
     } else if (identical(_oldNode, node.rightHandSide)) {
       if (isCascadeAllowed(node)) {
-        return _parser.parseExpression2();
+        return _parser.parseExpression3();
       }
       return _parser.parseExpressionWithoutCascade();
     }
@@ -413,7 +421,7 @@
     if (identical(_oldNode, node.parameter)) {
       return _parser.parseNormalFormalParameter();
     } else if (identical(_oldNode, node.defaultValue)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -422,7 +430,7 @@
     if (identical(_oldNode, node.body)) {
       return _parser.parseStatement2();
     } else if (identical(_oldNode, node.condition)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -448,14 +456,14 @@
 
   ASTNode visitExpressionFunctionBody(ExpressionFunctionBody node) {
     if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
 
   ASTNode visitExpressionStatement(ExpressionStatement node) {
     if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -505,6 +513,7 @@
   }
 
   ASTNode visitFormalParameterList(FormalParameterList node) {
+    // We don't know which kind of parameter to parse.
     throw new InsufficientContextException();
   }
 
@@ -514,9 +523,9 @@
     } else if (identical(_oldNode, node.initialization)) {
       throw new InsufficientContextException();
     } else if (identical(_oldNode, node.condition)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (node.updaters.contains(_oldNode)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (identical(_oldNode, node.body)) {
       return _parser.parseStatement2();
     }
@@ -604,7 +613,7 @@
 
   ASTNode visitIfStatement(IfStatement node) {
     if (identical(_oldNode, node.condition)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (identical(_oldNode, node.thenStatement)) {
       return _parser.parseStatement2();
     } else if (identical(_oldNode, node.elseStatement)) {
@@ -639,7 +648,7 @@
     if (identical(_oldNode, node.target)) {
       throw new InsufficientContextException();
     } else if (identical(_oldNode, node.index)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -660,7 +669,7 @@
       if (node.leftBracket == null) {
         throw new InsufficientContextException();
       }
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -716,7 +725,7 @@
     if (identical(_oldNode, node.typeArguments)) {
       return _parser.parseTypeArgumentList();
     } else if (node.elements.contains(_oldNode)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -732,9 +741,9 @@
 
   ASTNode visitMapLiteralEntry(MapLiteralEntry node) {
     if (identical(_oldNode, node.key)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (identical(_oldNode, node.value)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -752,6 +761,7 @@
       }
       return _parser.parseSimpleIdentifier();
     } else if (identical(_oldNode, node.body)) {
+      //return parser.parseFunctionBody();
       throw new InsufficientContextException();
     }
     return notAChild(node);
@@ -772,7 +782,7 @@
     if (identical(_oldNode, node.name)) {
       return _parser.parseLabel();
     } else if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -795,7 +805,7 @@
 
   ASTNode visitParenthesizedExpression(ParenthesizedExpression node) {
     if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -867,7 +877,7 @@
 
   ASTNode visitReturnStatement(ReturnStatement node) {
     if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     }
     return notAChild(node);
   }
@@ -920,7 +930,7 @@
     if (node.labels.contains(_oldNode)) {
       return _parser.parseLabel();
     } else if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (node.statements.contains(_oldNode)) {
       return _parser.parseStatement2();
     }
@@ -938,7 +948,7 @@
 
   ASTNode visitSwitchStatement(SwitchStatement node) {
     if (identical(_oldNode, node.expression)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (node.members.contains(_oldNode)) {
       throw new InsufficientContextException();
     }
@@ -952,7 +962,7 @@
   ASTNode visitThrowExpression(ThrowExpression node) {
     if (identical(_oldNode, node.expression)) {
       if (isCascadeAllowed2(node)) {
-        return _parser.parseExpression2();
+        return _parser.parseExpression3();
       }
       return _parser.parseExpressionWithoutCascade();
     }
@@ -1050,7 +1060,7 @@
 
   ASTNode visitWhileStatement(WhileStatement node) {
     if (identical(_oldNode, node.condition)) {
-      return _parser.parseExpression2();
+      return _parser.parseExpression3();
     } else if (identical(_oldNode, node.body)) {
       return _parser.parseStatement2();
     }
@@ -1072,6 +1082,7 @@
    * @return `true` if the right-hand side can be a cascade expression
    */
   bool isCascadeAllowed(AssignmentExpression node) {
+    // TODO(brianwilkerson) Implement this method.
     throw new InsufficientContextException();
   }
 
@@ -1082,6 +1093,7 @@
    * @return `true` if the expression can be a cascade expression
    */
   bool isCascadeAllowed2(ThrowExpression node) {
+    // TODO(brianwilkerson) Implement this method.
     throw new InsufficientContextException();
   }
 
@@ -1183,20 +1195,33 @@
   ASTNode reparse(ASTNode originalStructure, Token leftToken, Token rightToken, int originalStart, int originalEnd) {
     ASTNode oldNode = null;
     ASTNode newNode = null;
+    //
+    // Find the first token that needs to be re-parsed.
+    //
     Token firstToken = leftToken.next;
     if (identical(firstToken, rightToken)) {
+      // If there are no new tokens, then we need to include at least one copied node in the range.
       firstToken = leftToken;
     }
+    //
+    // Find the smallest AST node that encompasses the range of re-scanned tokens.
+    //
     if (originalEnd < originalStart) {
       oldNode = new NodeLocator.con1(originalStart).searchWithin(originalStructure);
     } else {
       oldNode = new NodeLocator.con2(originalStart, originalEnd).searchWithin(originalStructure);
     }
+    //
+    // Find the token at which parsing is to begin.
+    //
     int originalOffset = oldNode.offset;
     Token parseToken = findTokenAt(firstToken, originalOffset);
     if (parseToken == null) {
       return null;
     }
+    //
+    // Parse the appropriate AST structure starting at the appropriate place.
+    //
     Parser parser = new Parser(_source, _errorListener);
     parser.currentToken = parseToken;
     while (newNode == null) {
@@ -1204,12 +1229,15 @@
       if (parent == null) {
         parseToken = findFirstToken(parseToken);
         parser.currentToken = parseToken;
-        return parser.parseCompilationUnit2() as ASTNode;
+        return parser.parseCompilationUnit2();
       }
       bool advanceToParent = false;
       try {
         IncrementalParseDispatcher dispatcher = new IncrementalParseDispatcher(parser, oldNode);
         newNode = parent.accept(dispatcher);
+        //
+        // Validate that the new node can replace the old node.
+        //
         Token mappedToken = _tokenMap.get(oldNode.endToken.next);
         if (mappedToken == null || mappedToken.offset != newNode.endToken.next.offset || newNode.offset != oldNode.offset) {
           advanceToParent = true;
@@ -1228,9 +1256,13 @@
       }
     }
     _updatedNode = newNode;
+    //
+    // Replace the old node with the new node in a copy of the original AST structure.
+    //
     if (identical(oldNode, originalStructure)) {
+      // We ended up re-parsing the whole structure, so there's no need for a copy.
       ResolutionCopier.copyResolutionData(oldNode, newNode);
-      return newNode as ASTNode;
+      return newNode;
     }
     ResolutionCopier.copyResolutionData(oldNode, newNode);
     IncrementalASTCloner cloner = new IncrementalASTCloner(oldNode, newNode, _tokenMap);
@@ -1382,7 +1414,7 @@
     InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.Parser.parseExpression");
     try {
       _currentToken = token;
-      return parseExpression2();
+      return parseExpression3();
     } finally {
       instrumentation.log();
     }
@@ -1472,10 +1504,14 @@
    * @return the argument that was parsed
    */
   Expression parseArgument() {
+    //
+    // Both namedArgument and expression can start with an identifier, but only namedArgument can
+    // have an identifier followed by a colon.
+    //
     if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
-      return new NamedExpression(parseLabel(), parseExpression2());
+      return new NamedExpression(parseLabel(), parseExpression3());
     } else {
-      return parseExpression2();
+      return parseExpression3();
     }
   }
 
@@ -1499,6 +1535,10 @@
     if (matches5(TokenType.CLOSE_PAREN)) {
       return new ArgumentList(leftParenthesis, arguments, andAdvance);
     }
+    //
+    // Even though unnamed arguments must all appear before any named arguments, we allow them to
+    // appear in any order so that we can recover faster.
+    //
     Expression argument = parseArgument();
     arguments.add(argument);
     bool foundNamedArgument = argument is NamedExpression;
@@ -1508,13 +1548,17 @@
       arguments.add(argument);
       if (foundNamedArgument) {
         if (!generatedError && argument is! NamedExpression) {
-          reportError10(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []);
+          // Report the error, once, but allow the arguments to be in any order in the AST.
+          reportError11(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []);
           generatedError = true;
         }
       } else if (argument is NamedExpression) {
         foundNamedArgument = true;
       }
     }
+    // TODO(brianwilkerson) Recovery: Look at the left parenthesis to see whether there is a
+    // matching right parenthesis. If there is, then we're more likely missing a comma and should
+    // go back to parsing arguments.
     Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
     return new ArgumentList(leftParenthesis, arguments, rightParenthesis);
   }
@@ -1564,7 +1608,8 @@
         statements.add(statement);
       }
       if (identical(_currentToken, statementStart)) {
-        reportError11(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        // Ensure that we are making progress and report an error if we're not.
+        reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       statementStart = _currentToken;
@@ -1607,17 +1652,26 @@
         validateModifiersForGetterOrSetterOrMethod(modifiers);
         return parseMethodDeclaration(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, returnType);
       } else {
+        //
+        // We have found an error of some kind. Try to recover.
+        //
         if (matchesIdentifier()) {
           if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
-            reportError9(ParserErrorCode.VOID_VARIABLE, returnType, []);
+            //
+            // We appear to have a variable declaration with a type of "void".
+            //
+            reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []);
             return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), returnType);
           }
         }
         if (isOperator(_currentToken)) {
+          //
+          // We appear to have found an operator declaration without the 'operator' keyword.
+          //
           validateModifiersForOperator(modifiers);
           return parseOperator(commentAndMetadata, modifiers.externalKeyword, returnType);
         }
-        reportError11(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
+        reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
         return null;
       }
     } else if (matches(Keyword.GET) && matchesIdentifier2(peek())) {
@@ -1631,10 +1685,13 @@
       return parseOperator(commentAndMetadata, modifiers.externalKeyword, null);
     } else if (!matchesIdentifier()) {
       if (isOperator(_currentToken)) {
+        //
+        // We appear to have found an operator declaration without the 'operator' keyword.
+        //
         validateModifiersForOperator(modifiers);
         return parseOperator(commentAndMetadata, modifiers.externalKeyword, null);
       }
-      reportError11(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []);
+      reportError12(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []);
       return null;
     } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)) && matches4(peek2(3), TokenType.OPEN_PAREN)) {
       return parseConstructor(commentAndMetadata, modifiers.externalKeyword, validateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleIdentifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList());
@@ -1649,7 +1706,7 @@
       return parseMethodDeclaration2(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, null, methodName, parameters);
     } else if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
       if (modifiers.constKeyword == null && modifiers.finalKeyword == null && modifiers.varKeyword == null) {
-        reportError10(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
+        reportError11(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
       }
       return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), null);
     }
@@ -1665,13 +1722,26 @@
       return parseOperator(commentAndMetadata, modifiers.externalKeyword, type);
     } else if (!matchesIdentifier()) {
       if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+        //
+        // We appear to have found an incomplete declaration at the end of the class. At this point
+        // it consists of a type name, so we'll treat it as a field declaration with a missing
+        // field name and semicolon.
+        //
         return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), type);
       }
       if (isOperator(_currentToken)) {
+        //
+        // We appear to have found an operator declaration without the 'operator' keyword.
+        //
         validateModifiersForOperator(modifiers);
         return parseOperator(commentAndMetadata, modifiers.externalKeyword, type);
       }
-      reportError11(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []);
+      //
+      // We appear to have found an incomplete declaration before another declaration.
+      // At this point it consists of a type name, so we'll treat it as a field declaration
+      // with a missing field name and semicolon.
+      //
+      reportError12(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []);
       try {
         lockErrorListener();
         return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), type);
@@ -1682,7 +1752,7 @@
       SimpleIdentifier methodName = parseSimpleIdentifier();
       FormalParameterList parameters = parseFormalParameterList();
       if (methodName.name == className) {
-        reportError9(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type, []);
+        reportError10(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type, []);
         return parseConstructor(commentAndMetadata, modifiers.externalKeyword, validateModifiersForConstructor(modifiers), modifiers.factoryKeyword, methodName, null, null, parameters);
       }
       validateModifiersForGetterOrSetterOrMethod(modifiers);
@@ -1720,6 +1790,10 @@
     if (matches5(TokenType.SCRIPT_TAG)) {
       scriptTag = new ScriptTag(andAdvance);
     }
+    //
+    // Even though all directives must appear before declarations and must occur in a given order,
+    // we allow directives and declarations to occur in any order so that we can recover better.
+    //
     bool libraryDirectiveFound = false;
     bool partOfDirectiveFound = false;
     bool partDirectiveFound = false;
@@ -1732,15 +1806,15 @@
       if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.LIBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT) && !matches4(peek(), TokenType.OPEN_PAREN)) {
         Directive directive = parseDirective(commentAndMetadata);
         if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
-          reportError10(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, []);
+          reportError11(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, []);
           directiveFoundAfterDeclaration = true;
         }
         if (directive is LibraryDirective) {
           if (libraryDirectiveFound) {
-            reportError10(ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES, []);
+            reportError11(ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES, []);
           } else {
             if (directives.length > 0) {
-              reportError10(ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, []);
+              reportError12(ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, directive.libraryToken, []);
             }
             libraryDirectiveFound = true;
           }
@@ -1748,29 +1822,29 @@
           partDirectiveFound = true;
         } else if (partDirectiveFound) {
           if (directive is ExportDirective) {
-            reportError11(ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, (directive as NamespaceDirective).keyword, []);
+            reportError12(ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, directive.keyword, []);
           } else if (directive is ImportDirective) {
-            reportError11(ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, (directive as NamespaceDirective).keyword, []);
+            reportError12(ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, directive.keyword, []);
           }
         }
         if (directive is PartOfDirective) {
           if (partOfDirectiveFound) {
-            reportError10(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, []);
+            reportError11(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, []);
           } else {
             int directiveCount = directives.length;
             for (int i = 0; i < directiveCount; i++) {
-              reportError11(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directives[i].keyword, []);
+              reportError12(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directives[i].keyword, []);
             }
             partOfDirectiveFound = true;
           }
         } else {
           if (partOfDirectiveFound) {
-            reportError11(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directive.keyword, []);
+            reportError12(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directive.keyword, []);
           }
         }
         directives.add(directive);
       } else if (matches5(TokenType.SEMICOLON)) {
-        reportError11(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       } else {
         CompilationUnitMember member = parseCompilationUnitMember(commentAndMetadata);
@@ -1779,7 +1853,7 @@
         }
       }
       if (identical(_currentToken, memberStart)) {
-        reportError11(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
         while (!matches5(TokenType.EOF) && !couldBeStartOfCompilationUnitMember()) {
           advance();
@@ -1845,12 +1919,17 @@
    *
    * @return the expression that was parsed
    */
-  Expression parseExpression2() {
+  Expression parseExpression3() {
     if (matches(Keyword.THROW)) {
       return parseThrowExpression();
     } else if (matches(Keyword.RETHROW)) {
       return parseRethrowExpression();
     }
+    //
+    // assignableExpression is a subset of conditionalExpression, so we can parse a conditional
+    // expression and then determine whether it is followed by an assignmentOperator, checking for
+    // conformance to the restricted grammar after making that determination.
+    //
     Expression expression = parseConditionalExpression();
     TokenType tokenType = _currentToken.type;
     if (identical(tokenType, TokenType.PERIOD_PERIOD)) {
@@ -1866,7 +1945,7 @@
     } else if (tokenType.isAssignmentOperator) {
       Token operator = andAdvance;
       ensureAssignable(expression);
-      return new AssignmentExpression(expression, operator, parseExpression2());
+      return new AssignmentExpression(expression, operator, parseExpression3());
     }
     return expression;
   }
@@ -1889,6 +1968,11 @@
     } else if (matches(Keyword.RETHROW)) {
       return parseRethrowExpression();
     }
+    //
+    // assignableExpression is a subset of conditionalExpression, so we can parse a conditional
+    // expression and then determine whether it is followed by an assignmentOperator, checking for
+    // conformance to the restricted grammar after making that determination.
+    //
     Expression expression = parseConditionalExpression();
     if (_currentToken.type.isAssignmentOperator) {
       Token operator = andAdvance;
@@ -1944,6 +2028,11 @@
     if (matches5(TokenType.CLOSE_PAREN)) {
       return new FormalParameterList(leftParenthesis, null, null, null, andAdvance);
     }
+    //
+    // Even though it is invalid to have default parameters outside of brackets, required parameters
+    // inside of brackets, or multiple groups of default and named parameters, we allow all of these
+    // cases so that we can recover better.
+    //
     List<FormalParameter> parameters = new List<FormalParameter>();
     List<FormalParameter> normalParameters = new List<FormalParameter>();
     List<FormalParameter> positionalParameters = new List<FormalParameter>();
@@ -1964,22 +2053,26 @@
       if (firstParameter) {
         firstParameter = false;
       } else if (!optional(TokenType.COMMA)) {
+        // TODO(brianwilkerson) The token is wrong, we need to recover from this case.
         if (getEndToken(leftParenthesis) != null) {
-          reportError10(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
+          reportError11(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
         } else {
-          reportError11(ParserErrorCode.MISSING_CLOSING_PARENTHESIS, _currentToken.previous, []);
+          reportError12(ParserErrorCode.MISSING_CLOSING_PARENTHESIS, _currentToken.previous, []);
           break;
         }
       }
       initialToken = _currentToken;
+      //
+      // Handle the beginning of parameter groups.
+      //
       if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
         wasOptionalParameter = true;
         if (leftSquareBracket != null && !reportedMuliplePositionalGroups) {
-          reportError10(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []);
+          reportError11(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []);
           reportedMuliplePositionalGroups = true;
         }
         if (leftCurlyBracket != null && !reportedMixedGroups) {
-          reportError10(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
+          reportError11(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
           reportedMixedGroups = true;
         }
         leftSquareBracket = andAdvance;
@@ -1988,33 +2081,40 @@
       } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
         wasOptionalParameter = true;
         if (leftCurlyBracket != null && !reportedMulipleNamedGroups) {
-          reportError10(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []);
+          reportError11(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []);
           reportedMulipleNamedGroups = true;
         }
         if (leftSquareBracket != null && !reportedMixedGroups) {
-          reportError10(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
+          reportError11(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
           reportedMixedGroups = true;
         }
         leftCurlyBracket = andAdvance;
         currentParameters = namedParameters;
         kind = ParameterKind.NAMED;
       }
+      //
+      // Parse and record the parameter.
+      //
       FormalParameter parameter = parseFormalParameter(kind);
       parameters.add(parameter);
       currentParameters.add(parameter);
       if (identical(kind, ParameterKind.REQUIRED) && wasOptionalParameter) {
-        reportError9(ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, parameter, []);
+        reportError10(ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, parameter, []);
       }
+      //
+      // Handle the end of parameter groups.
+      //
+      // TODO(brianwilkerson) Improve the detection and reporting of missing and mismatched delimiters.
       if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
         rightSquareBracket = andAdvance;
         currentParameters = normalParameters;
         if (leftSquareBracket == null) {
           if (leftCurlyBracket != null) {
-            reportError10(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
+            reportError11(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
             rightCurlyBracket = rightSquareBracket;
             rightSquareBracket = null;
           } else {
-            reportError10(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ["["]);
+            reportError11(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ["["]);
           }
         }
         kind = ParameterKind.REQUIRED;
@@ -2023,23 +2123,29 @@
         currentParameters = normalParameters;
         if (leftCurlyBracket == null) {
           if (leftSquareBracket != null) {
-            reportError10(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
+            reportError11(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
             rightSquareBracket = rightCurlyBracket;
             rightCurlyBracket = null;
           } else {
-            reportError10(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ["{"]);
+            reportError11(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ["{"]);
           }
         }
         kind = ParameterKind.REQUIRED;
       }
     } while (!matches5(TokenType.CLOSE_PAREN) && initialToken != _currentToken);
     Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+    //
+    // Check that the groups were closed correctly.
+    //
     if (leftSquareBracket != null && rightSquareBracket == null) {
-      reportError10(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
+      reportError11(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
     }
     if (leftCurlyBracket != null && rightCurlyBracket == null) {
-      reportError10(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
+      reportError11(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
     }
+    //
+    // Build the parameter list.
+    //
     if (leftSquareBracket == null) {
       leftSquareBracket = leftCurlyBracket;
     }
@@ -2152,9 +2258,9 @@
    * @return the map literal entry that was parsed
    */
   MapLiteralEntry parseMapLiteralEntry() {
-    Expression key = parseExpression2();
+    Expression key = parseExpression3();
     Token separator = expect2(TokenType.COLON);
-    Expression value = parseExpression2();
+    Expression value = parseExpression3();
     return new MapLiteralEntry(key, separator, value);
   }
 
@@ -2194,7 +2300,7 @@
       FormalParameterList parameters = parseFormalParameterList();
       if (thisKeyword == null) {
         if (holder.keyword != null) {
-          reportError11(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword, []);
+          reportError12(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword, []);
         }
         return new FunctionTypedFormalParameter(commentAndMetadata.comment, commentAndMetadata.metadata, holder.type, identifier, parameters);
       } else {
@@ -2204,9 +2310,9 @@
     TypeName type = holder.type;
     if (type != null) {
       if (matches3(type.name.beginToken, Keyword.VOID)) {
-        reportError11(ParserErrorCode.VOID_PARAMETER, type.name.beginToken, []);
+        reportError12(ParserErrorCode.VOID_PARAMETER, type.name.beginToken, []);
       } else if (holder.keyword != null && matches3(holder.keyword, Keyword.VAR)) {
-        reportError11(ParserErrorCode.VAR_AND_TYPE, holder.keyword, []);
+        reportError12(ParserErrorCode.VAR_AND_TYPE, holder.keyword, []);
       }
     }
     if (thisKeyword != null) {
@@ -2268,7 +2374,7 @@
     if (matchesIdentifier()) {
       return new SimpleIdentifier(andAdvance);
     }
-    reportError10(ParserErrorCode.MISSING_IDENTIFIER, []);
+    reportError11(ParserErrorCode.MISSING_IDENTIFIER, []);
     return createSyntheticIdentifier();
   }
 
@@ -2316,7 +2422,7 @@
       }
     }
     if (strings.length < 1) {
-      reportError10(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
+      reportError11(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
       return createSyntheticStringLiteral();
     } else if (strings.length == 1) {
       return strings[0];
@@ -2362,13 +2468,13 @@
   TypeName parseTypeName() {
     Identifier typeName;
     if (matches(Keyword.VAR)) {
-      reportError10(ParserErrorCode.VAR_AS_TYPE_NAME, []);
+      reportError11(ParserErrorCode.VAR_AS_TYPE_NAME, []);
       typeName = new SimpleIdentifier(andAdvance);
     } else if (matchesIdentifier()) {
       typeName = parsePrefixedIdentifier();
     } else {
       typeName = createSyntheticIdentifier();
-      reportError10(ParserErrorCode.EXPECTED_TYPE_NAME, []);
+      reportError11(ParserErrorCode.EXPECTED_TYPE_NAME, []);
     }
     TypeArgumentList typeArguments = null;
     if (matches5(TokenType.LT)) {
@@ -2463,11 +2569,11 @@
    */
   void appendScalarValue(JavaStringBuilder builder, String escapeSequence, int scalarValue, int startIndex, int endIndex) {
     if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValue >= 0xD800 && scalarValue <= 0xDFFF)) {
-      reportError10(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
+      reportError11(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
       return;
     }
     if (scalarValue < Character.MAX_VALUE) {
-      builder.appendChar(scalarValue as int);
+      builder.appendChar(scalarValue);
     } else {
       builder.append(Character.toChars(scalarValue));
     }
@@ -2538,15 +2644,20 @@
    */
   bool couldBeStartOfCompilationUnitMember() {
     if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.LIBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
+      // This looks like the start of a directive
       return true;
     } else if (matches(Keyword.CLASS)) {
+      // This looks like the start of a class definition
       return true;
     } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
+      // This looks like the start of a typedef
       return true;
     } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperator(peek()))) {
+      // This looks like the start of a function
       return true;
     } else if (matchesIdentifier()) {
       if (matches4(peek(), TokenType.OPEN_PAREN)) {
+        // This looks like the start of a function
         return true;
       }
       Token token = skipReturnType(_currentToken);
@@ -2568,6 +2679,10 @@
   SimpleIdentifier createSyntheticIdentifier() {
     Token syntheticToken;
     if (identical(_currentToken.type, TokenType.KEYWORD)) {
+      // Consider current keyword token as an identifier.
+      // It is not always true, e.g. "^is T" where "^" is place the place for synthetic identifier.
+      // By creating SyntheticStringToken we can distinguish a real identifier from synthetic.
+      // In the code completion behavior will depend on a cursor position - before or on "is".
       syntheticToken = injectToken(new SyntheticStringToken(TokenType.IDENTIFIER, _currentToken.lexeme, _currentToken.offset));
     } else {
       syntheticToken = createSyntheticToken2(TokenType.IDENTIFIER);
@@ -2614,7 +2729,7 @@
    */
   void ensureAssignable(Expression expression) {
     if (expression != null && !expression.isAssignable) {
-      reportError10(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
+      reportError11(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
     }
   }
 
@@ -2629,7 +2744,9 @@
     if (matches(keyword)) {
       return andAdvance;
     }
-    reportError10(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
+    // Remove uses of this method in favor of matches?
+    // Pass in the error code to use to report the error?
+    reportError11(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
     return _currentToken;
   }
 
@@ -2644,10 +2761,12 @@
     if (matches5(type)) {
       return andAdvance;
     }
+    // Remove uses of this method in favor of matches?
+    // Pass in the error code to use to report the error?
     if (identical(type, TokenType.SEMICOLON)) {
-      reportError11(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type.lexeme]);
+      reportError12(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type.lexeme]);
     } else {
-      reportError10(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
+      reportError11(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
     }
     return _currentToken;
   }
@@ -2736,7 +2855,7 @@
    */
   Token getEndToken(Token beginToken) {
     if (beginToken is BeginToken) {
-      return (beginToken as BeginToken).endToken;
+      return beginToken.endToken;
     }
     return null;
   }
@@ -2782,10 +2901,13 @@
     }
     Token afterReturnType = skipTypeName(_currentToken);
     if (afterReturnType == null) {
+      // There was no return type, but it is optional, so go back to where we started.
       afterReturnType = _currentToken;
     }
     Token afterIdentifier = skipSimpleIdentifier(afterReturnType);
     if (afterIdentifier == null) {
+      // It's possible that we parsed the function name as if it were a type name, so see whether
+      // it makes sense if we assume that there is no type.
       afterIdentifier = skipSimpleIdentifier(_currentToken);
     }
     if (afterIdentifier == null) {
@@ -2794,6 +2916,8 @@
     if (isFunctionExpression(afterIdentifier)) {
       return true;
     }
+    // It's possible that we have found a getter. While this isn't valid at this point we test for
+    // it in order to recover better.
     if (matches(Keyword.GET)) {
       Token afterName = skipSimpleIdentifier(_currentToken.next);
       if (afterName == null) {
@@ -2856,17 +2980,22 @@
    */
   bool isInitializedVariableDeclaration() {
     if (matches(Keyword.FINAL) || matches(Keyword.VAR)) {
+      // An expression cannot start with a keyword other than 'const', 'rethrow', or 'throw'.
       return true;
     }
     if (matches(Keyword.CONST)) {
+      // Look to see whether we might be at the start of a list or map literal, otherwise this
+      // should be the start of a variable declaration.
       return !matchesAny(peek(), [
           TokenType.LT,
           TokenType.OPEN_CURLY_BRACKET,
           TokenType.OPEN_SQUARE_BRACKET,
           TokenType.INDEX]);
     }
+    // We know that we have an identifier, and need to see whether it might be a type name.
     Token token = skipTypeName(_currentToken);
     if (token == null) {
+      // There was no type name, so this can't be a declaration.
       return false;
     }
     token = skipSimpleIdentifier(token);
@@ -2916,16 +3045,20 @@
    * @return `true` if the given token appears to be the beginning of an operator declaration
    */
   bool isOperator(Token startToken) {
+    // Accept any operator here, even if it is not user definable.
     if (!startToken.isOperator) {
       return false;
     }
+    // Token "=" means that it is actually field initializer.
     if (identical(startToken.type, TokenType.EQ)) {
       return false;
     }
+    // Consume all operator tokens.
     Token token = startToken.next;
     while (token.isOperator) {
       token = token.next;
     }
+    // Formal parameter list is expect now.
     return matches4(token, TokenType.OPEN_PAREN);
   }
 
@@ -3166,7 +3299,7 @@
   ArgumentDefinitionTest parseArgumentDefinitionTest() {
     Token question = expect2(TokenType.QUESTION);
     SimpleIdentifier identifier = parseSimpleIdentifier();
-    reportError11(ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST, question, []);
+    reportError12(ParserErrorCode.DEPRECATED_ARGUMENT_DEFINITION_TEST, question, []);
     return new ArgumentDefinitionTest(question, identifier);
   }
 
@@ -3183,15 +3316,15 @@
   AssertStatement parseAssertStatement() {
     Token keyword = expect(Keyword.ASSERT);
     Token leftParen = expect2(TokenType.OPEN_PAREN);
-    Expression expression = parseExpression2();
+    Expression expression = parseExpression3();
     if (expression is AssignmentExpression) {
-      reportError9(ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT, expression, []);
+      reportError10(ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT, expression, []);
     } else if (expression is CascadeExpression) {
-      reportError9(ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE, expression, []);
+      reportError10(ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE, expression, []);
     } else if (expression is ThrowExpression) {
-      reportError9(ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW, expression, []);
+      reportError10(ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW, expression, []);
     } else if (expression is RethrowExpression) {
-      reportError9(ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW, expression, []);
+      reportError10(ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW, expression, []);
     }
     Token rightParen = expect2(TokenType.CLOSE_PAREN);
     Token semicolon = expect2(TokenType.SEMICOLON);
@@ -3216,6 +3349,11 @@
     if (matches(Keyword.SUPER)) {
       return parseAssignableSelector(new SuperExpression(andAdvance), false);
     }
+    //
+    // A primary expression can start with an identifier. We resolve the ambiguity by determining
+    // whether the primary consists of anything other than an identifier and/or is followed by an
+    // assignableSelector.
+    //
     Expression expression = parsePrimaryExpression();
     bool isOptional = primaryAllowed || expression is SimpleIdentifier;
     while (true) {
@@ -3265,7 +3403,7 @@
   Expression parseAssignableSelector(Expression prefix, bool optional) {
     if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
       Token leftBracket = andAdvance;
-      Expression index = parseExpression2();
+      Expression index = parseExpression3();
       Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
       return new IndexExpression.forTarget(prefix, leftBracket, index, rightBracket);
     } else if (matches5(TokenType.PERIOD)) {
@@ -3273,7 +3411,8 @@
       return new PropertyAccess(prefix, period, parseSimpleIdentifier());
     } else {
       if (!optional) {
-        reportError10(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
+        // Report the missing selector.
+        reportError11(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
       }
       return prefix;
     }
@@ -3346,7 +3485,7 @@
       label = parseSimpleIdentifier();
     }
     if (!_inLoop && !_inSwitch && label == null) {
-      reportError11(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
+      reportError12(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
     return new BreakStatement(breakKeyword, label, semicolon);
@@ -3377,12 +3516,12 @@
       functionName = parseSimpleIdentifier();
     } else if (identical(_currentToken.type, TokenType.OPEN_SQUARE_BRACKET)) {
       Token leftBracket = andAdvance;
-      Expression index = parseExpression2();
+      Expression index = parseExpression3();
       Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
       expression = new IndexExpression.forCascade(period, leftBracket, index, rightBracket);
       period = null;
     } else {
-      reportError11(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, [_currentToken.lexeme]);
+      reportError12(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, [_currentToken.lexeme]);
       functionName = createSyntheticIdentifier();
     }
     if (identical(_currentToken.type, TokenType.OPEN_PAREN)) {
@@ -3392,6 +3531,7 @@
           period = null;
           functionName = null;
         } else if (expression == null) {
+          // It should not be possible to get here.
           expression = new MethodInvocation(expression, period, createSyntheticIdentifier(), parseArgumentList());
         } else {
           expression = new FunctionExpressionInvocation(expression, parseArgumentList());
@@ -3447,10 +3587,10 @@
       if (matches4(next, TokenType.LT)) {
         next = skipTypeParameterList(next);
         if (next != null && matches4(next, TokenType.EQ)) {
-          return parseClassTypeAlias(commentAndMetadata, keyword);
+          return parseClassTypeAlias(commentAndMetadata, abstractKeyword, keyword);
         }
       } else if (matches4(next, TokenType.EQ)) {
-        return parseClassTypeAlias(commentAndMetadata, keyword);
+        return parseClassTypeAlias(commentAndMetadata, abstractKeyword, keyword);
       }
     }
     SimpleIdentifier name = parseSimpleIdentifier();
@@ -3459,6 +3599,10 @@
     if (matches5(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
+    //
+    // Parse the clauses. The parser accepts clauses in any order, but will generate errors if they
+    // are not in the order required by the specification.
+    //
     ExtendsClause extendsClause = null;
     WithClause withClause = null;
     ImplementsClause implementsClause = null;
@@ -3468,29 +3612,29 @@
         if (extendsClause == null) {
           extendsClause = parseExtendsClause();
           if (withClause != null) {
-            reportError11(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKeyword, []);
+            reportError12(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKeyword, []);
           } else if (implementsClause != null) {
-            reportError11(ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, implementsClause.keyword, []);
+            reportError12(ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, implementsClause.keyword, []);
           }
         } else {
-          reportError11(ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, extendsClause.keyword, []);
+          reportError12(ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, extendsClause.keyword, []);
           parseExtendsClause();
         }
       } else if (matches(Keyword.WITH)) {
         if (withClause == null) {
           withClause = parseWithClause();
           if (implementsClause != null) {
-            reportError11(ParserErrorCode.IMPLEMENTS_BEFORE_WITH, implementsClause.keyword, []);
+            reportError12(ParserErrorCode.IMPLEMENTS_BEFORE_WITH, implementsClause.keyword, []);
           }
         } else {
-          reportError11(ParserErrorCode.MULTIPLE_WITH_CLAUSES, withClause.withKeyword, []);
+          reportError12(ParserErrorCode.MULTIPLE_WITH_CLAUSES, withClause.withKeyword, []);
           parseWithClause();
         }
       } else if (matches(Keyword.IMPLEMENTS)) {
         if (implementsClause == null) {
           implementsClause = parseImplementsClause();
         } else {
-          reportError11(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsClause.keyword, []);
+          reportError12(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsClause.keyword, []);
           parseImplementsClause();
         }
       } else {
@@ -3498,12 +3642,18 @@
       }
     }
     if (withClause != null && extendsClause == null) {
-      reportError11(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword, []);
+      reportError12(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword, []);
     }
+    //
+    // Look for and skip over the extra-lingual 'native' specification.
+    //
     NativeClause nativeClause = null;
     if (matches2(_NATIVE) && matches4(peek(), TokenType.STRING)) {
       nativeClause = parseNativeClause();
     }
+    //
+    // Parse the body of the class.
+    //
     Token leftBracket = null;
     List<ClassMember> members = null;
     Token rightBracket = null;
@@ -3514,7 +3664,7 @@
     } else {
       leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET);
       rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET);
-      reportError10(ParserErrorCode.MISSING_CLASS_BODY, []);
+      reportError11(ParserErrorCode.MISSING_CLASS_BODY, []);
     }
     ClassDeclaration classDeclaration = new ClassDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, withClause, implementsClause, leftBracket, members, rightBracket);
     classDeclaration.nativeClause = nativeClause;
@@ -3539,7 +3689,7 @@
     Token memberStart = _currentToken;
     while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && (closingBracket != null || (!matches(Keyword.CLASS) && !matches(Keyword.TYPEDEF)))) {
       if (matches5(TokenType.SEMICOLON)) {
-        reportError11(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       } else {
         ClassMember member = parseClassMember(className);
@@ -3548,7 +3698,7 @@
         }
       }
       if (identical(_currentToken, memberStart)) {
-        reportError11(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       memberStart = _currentToken;
@@ -3568,17 +3718,17 @@
    * </pre>
    *
    * @param commentAndMetadata the metadata to be associated with the member
-   * @param keyword the token representing the 'typedef' keyword
+   * @param abstractKeyword the token representing the 'abstract' keyword
+   * @param classKeyword the token representing the 'class' keyword
    * @return the class type alias that was parsed
    */
-  ClassTypeAlias parseClassTypeAlias(CommentAndMetadata commentAndMetadata, Token keyword) {
+  ClassTypeAlias parseClassTypeAlias(CommentAndMetadata commentAndMetadata, Token abstractKeyword, Token classKeyword) {
     SimpleIdentifier className = parseSimpleIdentifier();
     TypeParameterList typeParameters = null;
     if (matches5(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
     Token equals = expect2(TokenType.EQ);
-    Token abstractKeyword = null;
     if (matches(Keyword.ABSTRACT)) {
       abstractKeyword = andAdvance;
     }
@@ -3596,16 +3746,16 @@
       semicolon = andAdvance;
     } else {
       if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
-        reportError10(ParserErrorCode.EXPECTED_TOKEN, [TokenType.SEMICOLON.lexeme]);
+        reportError11(ParserErrorCode.EXPECTED_TOKEN, [TokenType.SEMICOLON.lexeme]);
         Token leftBracket = andAdvance;
         parseClassMembers(className.name, getEndToken(leftBracket));
         expect2(TokenType.CLOSE_CURLY_BRACKET);
       } else {
-        reportError11(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [TokenType.SEMICOLON.lexeme]);
+        reportError12(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [TokenType.SEMICOLON.lexeme]);
       }
       semicolon = createSyntheticToken2(TokenType.SEMICOLON);
     }
-    return new ClassTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, className, typeParameters, equals, abstractKeyword, superclass, withClause, implementsClause, semicolon);
+    return new ClassTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, classKeyword, className, typeParameters, equals, abstractKeyword, superclass, withClause, implementsClause, semicolon);
   }
 
   /**
@@ -3673,6 +3823,7 @@
    * @return the comment reference that was parsed, or `null` if no reference could be found
    */
   CommentReference parseCommentReference(String referenceSource, int sourceOffset) {
+    // TODO(brianwilkerson) The errors are not getting the right offset/length and are being duplicated.
     if (referenceSource.length == 0) {
       return null;
     }
@@ -3706,6 +3857,10 @@
         }
         return new CommentReference(newKeyword, identifier);
       } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyword.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword.FALSE)) {
+        // TODO(brianwilkerson) If we want to support this we will need to extend the definition
+        // of CommentReference to take an expression rather than an identifier. For now we just
+        // ignore it to reduce the number of errors produced, but that's probably not a valid
+        // long term approach.
         return null;
       }
     } on JavaException catch (exception) {
@@ -3793,9 +3948,9 @@
       TypeName returnType = parseReturnType();
       if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) {
         validateModifiersForTopLevelFunction(modifiers);
-        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
+        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType);
       } else if (matches(Keyword.OPERATOR) && isOperator(peek())) {
-        reportError11(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []);
+        reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []);
         return convertToFunctionDeclaration(parseOperator(commentAndMetadata, modifiers.externalKeyword, returnType));
       } else if (matchesIdentifier() && matchesAny(peek(), [
           TokenType.OPEN_PAREN,
@@ -3804,30 +3959,36 @@
         validateModifiersForTopLevelFunction(modifiers);
         return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType);
       } else {
+        //
+        // We have found an error of some kind. Try to recover.
+        //
         if (matchesIdentifier()) {
           if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
-            reportError9(ParserErrorCode.VOID_VARIABLE, returnType, []);
+            //
+            // We appear to have a variable declaration with a type of "void".
+            //
+            reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []);
             return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
           }
         }
-        reportError11(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
+        reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
         return null;
       }
     } else if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) {
       validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
     } else if (matches(Keyword.OPERATOR) && isOperator(peek())) {
-      reportError11(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []);
+      reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []);
       return convertToFunctionDeclaration(parseOperator(commentAndMetadata, modifiers.externalKeyword, null));
     } else if (!matchesIdentifier()) {
-      reportError11(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
+      reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
       return null;
     } else if (matches4(peek(), TokenType.OPEN_PAREN)) {
       validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null);
     } else if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
       if (modifiers.constKeyword == null && modifiers.finalKeyword == null && modifiers.varKeyword == null) {
-        reportError10(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
+        reportError11(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
       }
       return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
     }
@@ -3836,12 +3997,13 @@
       validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType);
     } else if (matches(Keyword.OPERATOR) && isOperator(peek())) {
-      reportError11(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []);
+      reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []);
       return convertToFunctionDeclaration(parseOperator(commentAndMetadata, modifiers.externalKeyword, returnType));
     } else if (matches5(TokenType.AT)) {
       return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersForTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
     } else if (!matchesIdentifier()) {
-      reportError11(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
+      // TODO(brianwilkerson) Generalize this error. We could also be parsing a top-level variable at this point.
+      reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []);
       Token semicolon;
       if (matches5(TokenType.SEMICOLON)) {
         semicolon = andAdvance;
@@ -3918,21 +4080,21 @@
       redirectedConstructor = parseConstructorName();
       body = new EmptyFunctionBody(expect2(TokenType.SEMICOLON));
       if (factoryKeyword == null) {
-        reportError9(ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR, redirectedConstructor, []);
+        reportError10(ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR, redirectedConstructor, []);
       }
     } else {
       body = parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION_BODY, false);
       if (constKeyword != null && factoryKeyword != null && externalKeyword == null) {
-        reportError11(ParserErrorCode.CONST_FACTORY, factoryKeyword, []);
+        reportError12(ParserErrorCode.CONST_FACTORY, factoryKeyword, []);
       } else if (body is EmptyFunctionBody) {
         if (factoryKeyword != null && externalKeyword == null) {
-          reportError11(ParserErrorCode.FACTORY_WITHOUT_BODY, factoryKeyword, []);
+          reportError12(ParserErrorCode.FACTORY_WITHOUT_BODY, factoryKeyword, []);
         }
       } else {
         if (constKeyword != null) {
-          reportError9(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body, []);
+          reportError10(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body, []);
         } else if (!bodyAllowed) {
-          reportError9(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body, []);
+          reportError10(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body, []);
         }
       }
     }
@@ -3987,14 +4149,14 @@
   Statement parseContinueStatement() {
     Token continueKeyword = expect(Keyword.CONTINUE);
     if (!_inLoop && !_inSwitch) {
-      reportError11(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, []);
+      reportError12(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, []);
     }
     SimpleIdentifier label = null;
     if (matchesIdentifier()) {
       label = parseSimpleIdentifier();
     }
     if (_inSwitch && !_inLoop && label == null) {
-      reportError11(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword, []);
+      reportError12(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword, []);
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
     return new ContinueStatement(continueKeyword, label, semicolon);
@@ -4024,6 +4186,8 @@
     } else if (matches(Keyword.PART)) {
       return parsePartDirective(commentAndMetadata);
     } else {
+      // Internal error: this method should not have been invoked if the current token was something
+      // other than one of the above.
       throw new IllegalStateException("parseDirective invoked in an invalid state; currentToken = ${_currentToken}");
     }
   }
@@ -4084,7 +4248,7 @@
       Statement body = parseStatement2();
       Token whileKeyword = expect(Keyword.WHILE);
       Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
-      Expression condition = parseExpression2();
+      Expression condition = parseExpression3();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       Token semicolon = expect2(TokenType.SEMICOLON);
       return new DoStatement(doKeyword, body, whileKeyword, leftParenthesis, condition, rightParenthesis, semicolon);
@@ -4127,7 +4291,7 @@
     while (_currentToken.type.isEqualityOperator) {
       Token operator = andAdvance;
       if (leftEqualityExpression) {
-        reportError9(ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, expression, []);
+        reportError10(ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, expression, []);
       }
       expression = new BinaryExpression(expression, operator, parseRelationalExpression());
       leftEqualityExpression = true;
@@ -4166,9 +4330,9 @@
    */
   List<Expression> parseExpressionList() {
     List<Expression> expressions = new List<Expression>();
-    expressions.add(parseExpression2());
+    expressions.add(parseExpression3());
     while (optional(TokenType.COMMA)) {
-      expressions.add(parseExpression2());
+      expressions.add(parseExpression3());
     }
     return expressions;
   }
@@ -4201,7 +4365,7 @@
       if (isTypedIdentifier(_currentToken)) {
         type = parseReturnType();
       } else if (!optional) {
-        reportError10(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
+        reportError11(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
       }
     }
     return new FinalConstVarOrType(keyword, type);
@@ -4227,20 +4391,20 @@
     NormalFormalParameter parameter = parseNormalFormalParameter();
     if (matches5(TokenType.EQ)) {
       Token seperator = andAdvance;
-      Expression defaultValue = parseExpression2();
+      Expression defaultValue = parseExpression3();
       if (identical(kind, ParameterKind.NAMED)) {
-        reportError11(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator, []);
+        reportError12(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator, []);
       } else if (identical(kind, ParameterKind.REQUIRED)) {
-        reportError9(ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter, []);
+        reportError10(ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter, []);
       }
       return new DefaultFormalParameter(parameter, kind, seperator, defaultValue);
     } else if (matches5(TokenType.COLON)) {
       Token seperator = andAdvance;
-      Expression defaultValue = parseExpression2();
+      Expression defaultValue = parseExpression3();
       if (identical(kind, ParameterKind.POSITIONAL)) {
-        reportError11(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, seperator, []);
+        reportError12(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, seperator, []);
       } else if (identical(kind, ParameterKind.REQUIRED)) {
-        reportError9(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, []);
+        reportError10(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, []);
       }
       return new DefaultFormalParameter(parameter, kind, seperator, defaultValue);
     } else if (kind != ParameterKind.REQUIRED) {
@@ -4286,21 +4450,22 @@
         } else if (isInitializedVariableDeclaration()) {
           variableList = parseVariableDeclarationList(commentAndMetadata);
         } else {
-          initialization = parseExpression2();
+          initialization = parseExpression3();
         }
         if (matches(Keyword.IN)) {
           DeclaredIdentifier loopVariable = null;
           SimpleIdentifier identifier = null;
           if (variableList == null) {
-            reportError10(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []);
+            // We found: <expression> 'in'
+            reportError11(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []);
           } else {
             NodeList<VariableDeclaration> variables = variableList.variables;
             if (variables.length > 1) {
-              reportError10(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [variables.length.toString()]);
+              reportError11(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [variables.length.toString()]);
             }
             VariableDeclaration variable = variables[0];
             if (variable.initializer != null) {
-              reportError10(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
+              reportError11(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
             }
             Token keyword = variableList.keyword;
             TypeName type = variableList.type;
@@ -4313,7 +4478,7 @@
             }
           }
           Token inKeyword = expect(Keyword.IN);
-          Expression iterator = parseExpression2();
+          Expression iterator = parseExpression3();
           Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
           Statement body = parseStatement2();
           if (loopVariable == null) {
@@ -4325,7 +4490,7 @@
       Token leftSeparator = expect2(TokenType.SEMICOLON);
       Expression condition = null;
       if (!matches5(TokenType.SEMICOLON)) {
-        condition = parseExpression2();
+        condition = parseExpression3();
       }
       Token rightSeparator = expect2(TokenType.SEMICOLON);
       List<Expression> updaters = null;
@@ -4367,12 +4532,12 @@
     try {
       if (matches5(TokenType.SEMICOLON)) {
         if (!mayBeEmpty) {
-          reportError10(emptyErrorCode, []);
+          reportError11(emptyErrorCode, []);
         }
         return new EmptyFunctionBody(andAdvance);
       } else if (matches5(TokenType.FUNCTION)) {
         Token functionDefinition = andAdvance;
-        Expression expression = parseExpression2();
+        Expression expression = parseExpression3();
         Token semicolon = null;
         if (!inExpression) {
           semicolon = expect2(TokenType.SEMICOLON);
@@ -4395,7 +4560,8 @@
         }
         return new NativeFunctionBody(nativeToken, stringLiteral, expect2(TokenType.SEMICOLON));
       } else {
-        reportError10(emptyErrorCode, []);
+        // Invalid function body
+        reportError11(emptyErrorCode, []);
         return new EmptyFunctionBody(createSyntheticToken2(TokenType.SEMICOLON));
       }
     } finally {
@@ -4436,10 +4602,10 @@
         parameters = parseFormalParameterList();
         validateFormalParameterList(parameters);
       } else {
-        reportError10(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, []);
+        reportError11(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, []);
       }
     } else if (matches5(TokenType.OPEN_PAREN)) {
-      reportError10(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
+      reportError11(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
       parseFormalParameterList();
     }
     FunctionBody body;
@@ -4448,6 +4614,11 @@
     } else {
       body = new EmptyFunctionBody(expect2(TokenType.SEMICOLON));
     }
+    //    if (!isStatement && matches(TokenType.SEMICOLON)) {
+    //      // TODO(brianwilkerson) Improve this error message.
+    //      reportError(ParserErrorCode.UNEXPECTED_TOKEN, currentToken.getLexeme());
+    //      advance();
+    //    }
     return new FunctionDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression(parameters, body));
   }
 
@@ -4485,9 +4656,9 @@
     Token propertyKeyword = declaration.propertyKeyword;
     if (propertyKeyword != null) {
       if (identical((propertyKeyword as KeywordToken).keyword, Keyword.GET)) {
-        reportError11(ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword, []);
+        reportError12(ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword, []);
       } else {
-        reportError11(ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword, []);
+        reportError12(ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword, []);
       }
     }
     return new FunctionDeclarationStatement(declaration);
@@ -4519,12 +4690,15 @@
       typeParameters = parseTypeParameterList();
     }
     if (matches5(TokenType.SEMICOLON) || matches5(TokenType.EOF)) {
-      reportError10(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
+      reportError11(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
       FormalParameterList parameters = new FormalParameterList(createSyntheticToken2(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken2(TokenType.CLOSE_PAREN));
       Token semicolon = expect2(TokenType.SEMICOLON);
       return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
     } else if (!matches5(TokenType.OPEN_PAREN)) {
-      reportError10(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
+      reportError11(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
+      // TODO(brianwilkerson) Recover from this error. At the very least we should skip to the start
+      // of the next valid compilation unit member, allowing for the possibility of finding the
+      // typedef parameters before that point.
       return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, new FormalParameterList(createSyntheticToken2(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken2(TokenType.CLOSE_PAREN)), createSyntheticToken2(TokenType.SEMICOLON));
     }
     FormalParameterList parameters = parseFormalParameterList();
@@ -4556,13 +4730,13 @@
     Token propertyKeyword = expect(Keyword.GET);
     SimpleIdentifier name = parseSimpleIdentifier();
     if (matches5(TokenType.OPEN_PAREN) && matches4(peek(), TokenType.CLOSE_PAREN)) {
-      reportError10(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
+      reportError11(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
       advance();
       advance();
     }
     FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeyword == null, ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
-      reportError10(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
+      reportError11(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
     }
     return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, null, body);
   }
@@ -4600,7 +4774,7 @@
   Statement parseIfStatement() {
     Token ifKeyword = expect(Keyword.IF);
     Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
-    Expression condition = parseExpression2();
+    Expression condition = parseExpression3();
     Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
     Statement thenStatement = parseStatement2();
     Token elseKeyword = null;
@@ -4717,10 +4891,12 @@
     if (matchesIdentifier()) {
       return parseLibraryIdentifier();
     } else if (matches5(TokenType.STRING)) {
+      // TODO(brianwilkerson) Recovery: This should be extended to handle arbitrary tokens until we
+      // can find a token that can start a compilation unit member.
       StringLiteral string = parseStringLiteral();
-      reportError9(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []);
+      reportError10(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []);
     } else {
-      reportError11(missingNameError, missingNameToken, []);
+      reportError12(missingNameError, missingNameToken, []);
     }
     List<SimpleIdentifier> components = new List<SimpleIdentifier>();
     components.add(createSyntheticIdentifier());
@@ -4742,6 +4918,7 @@
    * @return the list literal that was parsed
    */
   ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) {
+    // may be empty list literal
     if (matches5(TokenType.INDEX)) {
       BeginToken leftBracket = new BeginToken(TokenType.OPEN_SQUARE_BRACKET, _currentToken.offset);
       Token rightBracket = new Token(TokenType.CLOSE_SQUARE_BRACKET, _currentToken.offset + 1);
@@ -4752,17 +4929,18 @@
       _currentToken = _currentToken.next;
       return new ListLiteral(modifier, typeArguments, leftBracket, null, rightBracket);
     }
+    // open
     Token leftBracket = expect2(TokenType.OPEN_SQUARE_BRACKET);
     if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
       return new ListLiteral(modifier, typeArguments, leftBracket, null, andAdvance);
     }
     List<Expression> elements = new List<Expression>();
-    elements.add(parseExpression2());
+    elements.add(parseExpression3());
     while (optional(TokenType.COMMA)) {
       if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
         return new ListLiteral(modifier, typeArguments, leftBracket, elements, andAdvance);
       }
-      elements.add(parseExpression2());
+      elements.add(parseExpression3());
     }
     Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
     return new ListLiteral(modifier, typeArguments, leftBracket, elements, rightBracket);
@@ -4791,7 +4969,7 @@
     } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
       return parseListLiteral(modifier, typeArguments);
     }
-    reportError10(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
+    reportError11(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
     return new ListLiteral(modifier, typeArguments, createSyntheticToken2(TokenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken2(TokenType.CLOSE_SQUARE_BRACKET));
   }
 
@@ -4890,11 +5068,11 @@
     FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeyword == null, ParserErrorCode.MISSING_FUNCTION_BODY, false);
     if (externalKeyword != null) {
       if (body is! EmptyFunctionBody) {
-        reportError9(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []);
+        reportError10(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []);
       }
     } else if (staticKeyword != null) {
       if (body is EmptyFunctionBody) {
-        reportError9(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []);
+        reportError10(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []);
       }
     }
     return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, null, null, name, parameters, body);
@@ -4922,49 +5100,49 @@
       }
       if (matches(Keyword.ABSTRACT)) {
         if (modifiers.abstractKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.abstractKeyword = andAdvance;
         }
       } else if (matches(Keyword.CONST)) {
         if (modifiers.constKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.constKeyword = andAdvance;
         }
       } else if (matches(Keyword.EXTERNAL) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.externalKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.externalKeyword = andAdvance;
         }
       } else if (matches(Keyword.FACTORY) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.factoryKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.factoryKeyword = andAdvance;
         }
       } else if (matches(Keyword.FINAL)) {
         if (modifiers.finalKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.finalKeyword = andAdvance;
         }
       } else if (matches(Keyword.STATIC) && !matches4(peek(), TokenType.PERIOD) && !matches4(peek(), TokenType.LT)) {
         if (modifiers.staticKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.staticKeyword = andAdvance;
         }
       } else if (matches(Keyword.VAR)) {
         if (modifiers.varKeyword != null) {
-          reportError10(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          reportError11(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
           modifiers.varKeyword = andAdvance;
@@ -5053,17 +5231,19 @@
    * @return the non-labeled statement that was parsed
    */
   Statement parseNonLabeledStatement() {
+    // TODO(brianwilkerson) Pass the comment and metadata on where appropriate.
     CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
     if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
       if (matches4(peek(), TokenType.STRING)) {
         Token afterString = skipStringLiteral(_currentToken.next);
         if (afterString != null && identical(afterString.type, TokenType.COLON)) {
-          return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+          return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEMICOLON));
         }
       }
       return parseBlock();
     } else if (matches5(TokenType.KEYWORD) && !(_currentToken as KeywordToken).keyword.isPseudoKeyword) {
       Keyword keyword = (_currentToken as KeywordToken).keyword;
+      // TODO(jwren) compute some metrics to figure out a better order for this if-then sequence to optimize performance
       if (identical(keyword, Keyword.ASSERT)) {
         return parseAssertStatement();
       } else if (identical(keyword, Keyword.BREAK)) {
@@ -5098,15 +5278,26 @@
             TokenType.FUNCTION])) {
           return parseFunctionDeclarationStatement2(commentAndMetadata, returnType);
         } else {
+          //
+          // We have found an error of some kind. Try to recover.
+          //
           if (matchesIdentifier()) {
             if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
-              reportError9(ParserErrorCode.VOID_VARIABLE, returnType, []);
+              //
+              // We appear to have a variable declaration with a type of "void".
+              //
+              reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []);
               return parseVariableDeclarationStatement(commentAndMetadata);
             }
           } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+            //
+            // We appear to have found an incomplete statement at the end of a block. Parse it as a
+            // variable declaration.
+            //
             return parseVariableDeclarationStatement2(commentAndMetadata, null, returnType);
           }
-          reportError10(ParserErrorCode.MISSING_STATEMENT, []);
+          reportError11(ParserErrorCode.MISSING_STATEMENT, []);
+          // TODO(brianwilkerson) Recover from this error.
           return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON));
         }
       } else if (identical(keyword, Keyword.CONST)) {
@@ -5115,20 +5306,23 @@
             TokenType.OPEN_CURLY_BRACKET,
             TokenType.OPEN_SQUARE_BRACKET,
             TokenType.INDEX])) {
-          return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+          return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEMICOLON));
         } else if (matches4(peek(), TokenType.IDENTIFIER)) {
           Token afterType = skipTypeName(peek());
           if (afterType != null) {
             if (matches4(afterType, TokenType.OPEN_PAREN) || (matches4(afterType, TokenType.PERIOD) && matches4(afterType.next, TokenType.IDENTIFIER) && matches4(afterType.next.next, TokenType.OPEN_PAREN))) {
-              return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+              return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEMICOLON));
             }
           }
         }
         return parseVariableDeclarationStatement(commentAndMetadata);
       } else if (identical(keyword, Keyword.NEW) || identical(keyword, Keyword.TRUE) || identical(keyword, Keyword.FALSE) || identical(keyword, Keyword.NULL) || identical(keyword, Keyword.SUPER) || identical(keyword, Keyword.THIS)) {
-        return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+        return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEMICOLON));
       } else {
-        reportError10(ParserErrorCode.MISSING_STATEMENT, []);
+        //
+        // We have found an error of some kind. Try to recover.
+        //
+        reportError11(ParserErrorCode.MISSING_STATEMENT, []);
         return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON));
       }
     } else if (matches5(TokenType.SEMICOLON)) {
@@ -5138,10 +5332,10 @@
     } else if (isFunctionDeclaration()) {
       return parseFunctionDeclarationStatement();
     } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
-      reportError10(ParserErrorCode.MISSING_STATEMENT, []);
+      reportError11(ParserErrorCode.MISSING_STATEMENT, []);
       return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON));
     } else {
-      return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+      return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEMICOLON));
     }
   }
 
@@ -5168,17 +5362,17 @@
     if (matches(Keyword.OPERATOR)) {
       operatorKeyword = andAdvance;
     } else {
-      reportError11(ParserErrorCode.MISSING_KEYWORD_OPERATOR, _currentToken, []);
+      reportError12(ParserErrorCode.MISSING_KEYWORD_OPERATOR, _currentToken, []);
       operatorKeyword = createSyntheticToken(Keyword.OPERATOR);
     }
     if (!_currentToken.isUserDefinableOperator) {
-      reportError10(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
+      reportError11(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
     }
     SimpleIdentifier name = new SimpleIdentifier(andAdvance);
     if (matches5(TokenType.EQ)) {
       Token previous = _currentToken.previous;
       if ((matches4(previous, TokenType.EQ_EQ) || matches4(previous, TokenType.BANG_EQ)) && _currentToken.offset == previous.offset + 2) {
-        reportError10(ParserErrorCode.INVALID_OPERATOR, ["${previous.lexeme}${_currentToken.lexeme}"]);
+        reportError11(ParserErrorCode.INVALID_OPERATOR, ["${previous.lexeme}${_currentToken.lexeme}"]);
         advance();
       }
     }
@@ -5186,7 +5380,7 @@
     validateFormalParameterList(parameters);
     FunctionBody body = parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION_BODY, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
-      reportError10(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
+      reportError11(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
     }
     return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, parameters, body);
   }
@@ -5271,7 +5465,7 @@
       return operand;
     }
     if (operand is Literal || operand is FunctionExpressionInvocation) {
-      reportError10(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
+      reportError11(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
     }
     Token operator = andAdvance;
     return new PostfixExpression(operand, operator);
@@ -5346,6 +5540,16 @@
     } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
       return parseListLiteral(null, null);
     } else if (matchesIdentifier()) {
+      // TODO(brianwilkerson) The code below was an attempt to recover from an error case, but it
+      // needs to be applied as a recovery only after we know that parsing it as an identifier
+      // doesn't work. Leaving the code as a reminder of how to recover.
+      //      if (isFunctionExpression(peek())) {
+      //        //
+      //        // Function expressions were allowed to have names at one point, but this is now illegal.
+      //        //
+      //        reportError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, getAndAdvance());
+      //        return parseFunctionExpression();
+      //      }
       return parsePrefixedIdentifier();
     } else if (matches(Keyword.NEW)) {
       return parseNewExpression();
@@ -5356,7 +5560,7 @@
         return parseFunctionExpression();
       }
       Token leftParenthesis = andAdvance;
-      Expression expression = parseExpression2();
+      Expression expression = parseExpression3();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       return new ParenthesizedExpression(leftParenthesis, expression, rightParenthesis);
     } else if (matches5(TokenType.LT)) {
@@ -5364,13 +5568,17 @@
     } else if (matches5(TokenType.QUESTION)) {
       return parseArgumentDefinitionTest();
     } else if (matches(Keyword.VOID)) {
-      reportError10(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
+      //
+      // Recover from having a return type of "void" where a return type is not expected.
+      //
+      // TODO(brianwilkerson) Improve this error message.
+      reportError11(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
       advance();
       return parsePrimaryExpression();
     } else if (matches5(TokenType.HASH)) {
       return parseSymbolLiteral();
     } else {
-      reportError10(ParserErrorCode.MISSING_IDENTIFIER, []);
+      reportError11(ParserErrorCode.MISSING_IDENTIFIER, []);
       return createSyntheticIdentifier();
     }
   }
@@ -5460,7 +5668,7 @@
     if (matches5(TokenType.SEMICOLON)) {
       return new ReturnStatement(returnKeyword, null, andAdvance);
     }
-    Expression expression = parseExpression2();
+    Expression expression = parseExpression3();
     Token semicolon = expect2(TokenType.SEMICOLON);
     return new ReturnStatement(returnKeyword, expression, semicolon);
   }
@@ -5491,7 +5699,7 @@
     validateFormalParameterList(parameters);
     FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeyword == null, ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
-      reportError10(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
+      reportError11(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
     }
     return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, parameters, body);
   }
@@ -5537,7 +5745,7 @@
     while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) {
       statements.add(parseStatement2());
       if (identical(_currentToken, statementStart)) {
-        reportError11(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       statementStart = _currentToken;
@@ -5557,7 +5765,7 @@
     while (hasMore) {
       if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         Token openToken = andAdvance;
-        Expression expression = parseExpression2();
+        Expression expression = parseExpression3();
         Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
         elements.add(new InterpolationExpression(openToken, expression, rightBracket));
       } else {
@@ -5624,7 +5832,7 @@
       Set<String> definedLabels = new Set<String>();
       Token keyword = expect(Keyword.SWITCH);
       Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
-      Expression expression = parseExpression2();
+      Expression expression = parseExpression3();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
       Token defaultKeyword = null;
@@ -5635,7 +5843,7 @@
           SimpleIdentifier identifier = parseSimpleIdentifier();
           String label = identifier.token.lexeme;
           if (definedLabels.contains(label)) {
-            reportError11(ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, identifier.token, [label]);
+            reportError12(ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, identifier.token, [label]);
           } else {
             definedLabels.add(label);
           }
@@ -5644,21 +5852,23 @@
         }
         if (matches(Keyword.CASE)) {
           Token caseKeyword = andAdvance;
-          Expression caseExpression = parseExpression2();
+          Expression caseExpression = parseExpression3();
           Token colon = expect2(TokenType.COLON);
           members.add(new SwitchCase(labels, caseKeyword, caseExpression, colon, parseStatements2()));
           if (defaultKeyword != null) {
-            reportError11(ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, caseKeyword, []);
+            reportError12(ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, caseKeyword, []);
           }
         } else if (matches(Keyword.DEFAULT)) {
           if (defaultKeyword != null) {
-            reportError11(ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, peek(), []);
+            reportError12(ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, peek(), []);
           }
           defaultKeyword = andAdvance;
           Token colon = expect2(TokenType.COLON);
           members.add(new SwitchDefault(labels, defaultKeyword, colon, parseStatements2()));
         } else {
-          reportError10(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []);
+          // We need to advance, otherwise we could end up in an infinite loop, but this could be a
+          // lot smarter about recovering from the error.
+          reportError11(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []);
           while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !matches(Keyword.CASE) && !matches(Keyword.DEFAULT)) {
             advance();
           }
@@ -5691,7 +5901,7 @@
         if (matchesIdentifier()) {
           components.add(andAdvance);
         } else {
-          reportError10(ParserErrorCode.MISSING_IDENTIFIER, []);
+          reportError11(ParserErrorCode.MISSING_IDENTIFIER, []);
           components.add(createSyntheticToken2(TokenType.IDENTIFIER));
           break;
         }
@@ -5699,7 +5909,7 @@
     } else if (_currentToken.isOperator) {
       components.add(andAdvance);
     } else {
-      reportError10(ParserErrorCode.MISSING_IDENTIFIER, []);
+      reportError11(ParserErrorCode.MISSING_IDENTIFIER, []);
       components.add(createSyntheticToken2(TokenType.IDENTIFIER));
     }
     return new SymbolLiteral(poundSign, new List.from(components));
@@ -5718,10 +5928,10 @@
   Expression parseThrowExpression() {
     Token keyword = expect(Keyword.THROW);
     if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
-      reportError11(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, []);
+      reportError12(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, []);
       return new ThrowExpression(keyword, createSyntheticIdentifier());
     }
-    Expression expression = parseExpression2();
+    Expression expression = parseExpression3();
     return new ThrowExpression(keyword, expression);
   }
 
@@ -5738,7 +5948,7 @@
   Expression parseThrowExpressionWithoutCascade() {
     Token keyword = expect(Keyword.THROW);
     if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
-      reportError11(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, []);
+      reportError12(ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken, []);
       return new ThrowExpression(keyword, createSyntheticIdentifier());
     }
     Expression expression = parseExpressionWithoutCascade();
@@ -5802,7 +6012,7 @@
       finallyClause = parseBlock();
     } else {
       if (catchClauses.isEmpty) {
-        reportError10(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
+        reportError11(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
       }
     }
     return new TryStatement(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
@@ -5842,13 +6052,13 @@
       if (matches4(next, TokenType.LT)) {
         next = skipTypeParameterList(next);
         if (next != null && matches4(next, TokenType.EQ)) {
-          TypeAlias typeAlias = parseClassTypeAlias(commentAndMetadata, keyword);
-          reportError11(ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword, []);
+          TypeAlias typeAlias = parseClassTypeAlias(commentAndMetadata, null, keyword);
+          reportError12(ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword, []);
           return typeAlias;
         }
       } else if (matches4(next, TokenType.EQ)) {
-        TypeAlias typeAlias = parseClassTypeAlias(commentAndMetadata, keyword);
-        reportError11(ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword, []);
+        TypeAlias typeAlias = parseClassTypeAlias(commentAndMetadata, null, keyword);
+        reportError12(ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword, []);
         return typeAlias;
       }
     }
@@ -5874,6 +6084,10 @@
       Token operator = andAdvance;
       if (matches(Keyword.SUPER)) {
         if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(), TokenType.PERIOD)) {
+          //     "prefixOperator unaryExpression"
+          // --> "prefixOperator postfixExpression"
+          // --> "prefixOperator primary                    selector*"
+          // --> "prefixOperator 'super' assignableSelector selector*"
           return new PrefixExpression(operator, parseUnaryExpression());
         }
         return new PrefixExpression(operator, new SuperExpression(andAdvance));
@@ -5883,8 +6097,14 @@
       Token operator = andAdvance;
       if (matches(Keyword.SUPER)) {
         if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(), TokenType.PERIOD)) {
+          // --> "prefixOperator 'super' assignableSelector selector*"
           return new PrefixExpression(operator, parseUnaryExpression());
         }
+        //
+        // Even though it is not valid to use an incrementing operator ('++' or '--') before 'super',
+        // we can (and therefore must) interpret "--super" as semantically equivalent to "-(-super)".
+        // Unfortunately, we cannot do the same for "++super" because "+super" is also not valid.
+        //
         if (identical(operator.type, TokenType.MINUS_MINUS)) {
           int offset = operator.offset;
           Token firstOperator = new Token(TokenType.MINUS, offset);
@@ -5894,13 +6114,14 @@
           operator.previous.setNext(firstOperator);
           return new PrefixExpression(firstOperator, new PrefixExpression(secondOperator, new SuperExpression(andAdvance)));
         } else {
-          reportError10(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
+          // Invalid operator before 'super'
+          reportError11(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
           return new PrefixExpression(operator, new SuperExpression(andAdvance));
         }
       }
       return new PrefixExpression(operator, parseAssignableExpression(false));
     } else if (matches5(TokenType.PLUS)) {
-      reportError10(ParserErrorCode.MISSING_IDENTIFIER, []);
+      reportError11(ParserErrorCode.MISSING_IDENTIFIER, []);
       return createSyntheticIdentifier();
     }
     return parsePostfixExpression();
@@ -5923,7 +6144,7 @@
     Expression initializer = null;
     if (matches5(TokenType.EQ)) {
       equals = andAdvance;
-      initializer = parseExpression2();
+      initializer = parseExpression3();
     }
     return new VariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, name, equals, initializer);
   }
@@ -5961,7 +6182,7 @@
    */
   VariableDeclarationList parseVariableDeclarationList2(CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) {
     if (type != null && keyword != null && matches3(keyword, Keyword.VAR)) {
-      reportError11(ParserErrorCode.VAR_AND_TYPE, keyword, []);
+      reportError12(ParserErrorCode.VAR_AND_TYPE, keyword, []);
     }
     List<VariableDeclaration> variables = new List<VariableDeclaration>();
     variables.add(parseVariableDeclaration());
@@ -5985,7 +6206,14 @@
    * @return the variable declaration statement that was parsed
    */
   VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetadata commentAndMetadata) {
+    //    Token startToken = currentToken;
     VariableDeclarationList variableList = parseVariableDeclarationList(commentAndMetadata);
+    //    if (!matches(TokenType.SEMICOLON)) {
+    //      if (matches(startToken, Keyword.VAR) && isTypedIdentifier(startToken.getNext())) {
+    //        // TODO(brianwilkerson) This appears to be of the form "var type variable". We should do
+    //        // a better job of recovering in this case.
+    //      }
+    //    }
     Token semicolon = expect2(TokenType.SEMICOLON);
     return new VariableDeclarationStatement(variableList, semicolon);
   }
@@ -6027,7 +6255,7 @@
     try {
       Token keyword = expect(Keyword.WHILE);
       Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
-      Expression condition = parseExpression2();
+      Expression condition = parseExpression3();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       Statement body = parseStatement2();
       return new WhileStatement(keyword, leftParenthesis, condition, rightParenthesis, body);
@@ -6078,7 +6306,7 @@
    * @param node the node specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError9(ParserErrorCode errorCode, ASTNode node, List<Object> arguments) {
+  void reportError10(ParserErrorCode errorCode, ASTNode node, List<Object> arguments) {
     reportError(new AnalysisError.con2(_source, node.offset, node.length, errorCode, arguments));
   }
 
@@ -6088,8 +6316,8 @@
    * @param errorCode the error code of the error to be reported
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError10(ParserErrorCode errorCode, List<Object> arguments) {
-    reportError11(errorCode, _currentToken, arguments);
+  void reportError11(ParserErrorCode errorCode, List<Object> arguments) {
+    reportError12(errorCode, _currentToken, arguments);
   }
 
   /**
@@ -6099,7 +6327,7 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError11(ParserErrorCode errorCode, Token token, List<Object> arguments) {
+  void reportError12(ParserErrorCode errorCode, Token token, List<Object> arguments) {
     reportError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, arguments));
   }
 
@@ -6132,9 +6360,11 @@
       Token next = startToken.next;
       if (matchesIdentifier2(next)) {
         Token next2 = next.next;
+        // "Type parameter" or "Type<" or "prefix.Type"
         if (matchesIdentifier2(next2) || matches4(next2, TokenType.LT) || matches4(next2, TokenType.PERIOD)) {
           return skipTypeName(next);
         }
+        // "parameter"
         return next;
       }
     } else if (matches3(startToken, Keyword.VAR)) {
@@ -6193,18 +6423,29 @@
     if (matches4(next, TokenType.CLOSE_PAREN)) {
       return next.next;
     }
+    //
+    // Look to see whether the token after the open parenthesis is something that should only occur
+    // at the beginning of a parameter list.
+    //
     if (matchesAny(next, [
         TokenType.AT,
         TokenType.OPEN_SQUARE_BRACKET,
         TokenType.OPEN_CURLY_BRACKET]) || matches3(next, Keyword.VOID) || (matchesIdentifier2(next) && (matchesAny(next.next, [TokenType.COMMA, TokenType.CLOSE_PAREN])))) {
       return skipPastMatchingToken(startToken);
     }
+    //
+    // Look to see whether the first parameter is a function typed parameter without a return type.
+    //
     if (matchesIdentifier2(next) && matches4(next.next, TokenType.OPEN_PAREN)) {
       Token afterParameters = skipFormalParameterList(next.next);
       if (afterParameters != null && (matchesAny(afterParameters, [TokenType.COMMA, TokenType.CLOSE_PAREN]))) {
         return skipPastMatchingToken(startToken);
       }
     }
+    //
+    // Look to see whether the first parameter has a type or is a function typed parameter with a
+    // return type.
+    //
     Token afterType = skipFinalConstVarOrType(next);
     if (afterType == null) {
       return null;
@@ -6324,6 +6565,11 @@
       if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         token = token.next;
         type = token.type;
+        //
+        // Rather than verify that the following tokens represent a valid expression, we simply skip
+        // tokens until we reach the end of the interpolation, being careful to handle nested string
+        // literals.
+        //
         int bracketNestingLevel = 1;
         while (bracketNestingLevel > 0) {
           if (identical(type, TokenType.EOF)) {
@@ -6480,6 +6726,10 @@
     if (!matches4(startToken, TokenType.LT)) {
       return null;
     }
+    //
+    // We can't skip a type parameter because it can be preceeded by metadata, so we just assume
+    // that everything before the matching end token is valid.
+    //
     int depth = 1;
     Token next = startToken.next;
     while (depth > 0) {
@@ -6528,9 +6778,18 @@
       builder.appendChar(currentChar);
       return index + 1;
     }
+    //
+    // We have found an escape sequence, so we parse the string to determine what kind of escape
+    // sequence and what character to add to the builder.
+    //
     int length = lexeme.length;
     int currentIndex = index + 1;
     if (currentIndex >= length) {
+      // Illegal escape sequence: no char after escape
+      // This cannot actually happen because it would require the escape character to be the last
+      // character in the string, but if it were it would escape the closing quote, leaving the
+      // string unclosed.
+      // reportError(ParserErrorCode.MISSING_CHAR_IN_ESCAPE_SEQUENCE);
       return length;
     }
     currentChar = lexeme.codeUnitAt(currentIndex);
@@ -6548,28 +6807,32 @@
       builder.appendChar(0xB);
     } else if (currentChar == 0x78) {
       if (currentIndex + 2 >= length) {
-        reportError10(ParserErrorCode.INVALID_HEX_ESCAPE, []);
+        // Illegal escape sequence: not enough hex digits
+        reportError11(ParserErrorCode.INVALID_HEX_ESCAPE, []);
         return length;
       }
       int firstDigit = lexeme.codeUnitAt(currentIndex + 1);
       int secondDigit = lexeme.codeUnitAt(currentIndex + 2);
       if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) {
-        reportError10(ParserErrorCode.INVALID_HEX_ESCAPE, []);
+        // Illegal escape sequence: invalid hex digit
+        reportError11(ParserErrorCode.INVALID_HEX_ESCAPE, []);
       } else {
-        builder.appendChar(((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) as int);
+        builder.appendChar(((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)));
       }
       return currentIndex + 3;
     } else if (currentChar == 0x75) {
       currentIndex++;
       if (currentIndex >= length) {
-        reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+        // Illegal escape sequence: not enough hex digits
+        reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         return length;
       }
       currentChar = lexeme.codeUnitAt(currentIndex);
       if (currentChar == 0x7B) {
         currentIndex++;
         if (currentIndex >= length) {
-          reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          // Illegal escape sequence: incomplete escape
+          reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
           return length;
         }
         currentChar = lexeme.codeUnitAt(currentIndex);
@@ -6577,7 +6840,8 @@
         int value = 0;
         while (currentChar != 0x7D) {
           if (!isHexDigit(currentChar)) {
-            reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+            // Illegal escape sequence: invalid hex digit
+            reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
             currentIndex++;
             while (currentIndex < length && lexeme.codeUnitAt(currentIndex) != 0x7D) {
               currentIndex++;
@@ -6588,19 +6852,22 @@
           value = (value << 4) + Character.digit(currentChar, 16);
           currentIndex++;
           if (currentIndex >= length) {
-            reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+            // Illegal escape sequence: incomplete escape
+            reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
             return length;
           }
           currentChar = lexeme.codeUnitAt(currentIndex);
         }
         if (digitCount < 1 || digitCount > 6) {
-          reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          // Illegal escape sequence: not enough or too many hex digits
+          reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         }
         appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), value, index, currentIndex);
         return currentIndex + 1;
       } else {
         if (currentIndex + 3 >= length) {
-          reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          // Illegal escape sequence: not enough hex digits
+          reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
           return length;
         }
         int firstDigit = currentChar;
@@ -6608,7 +6875,8 @@
         int thirdDigit = lexeme.codeUnitAt(currentIndex + 2);
         int fourthDigit = lexeme.codeUnitAt(currentIndex + 3);
         if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit) || !isHexDigit(thirdDigit) || !isHexDigit(fourthDigit)) {
-          reportError10(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          // Illegal escape sequence: invalid hex digits
+          reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         } else {
           appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), (((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) << 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16), index, currentIndex + 3);
         }
@@ -6639,7 +6907,7 @@
   void validateFormalParameterList(FormalParameterList parameterList) {
     for (FormalParameter parameter in parameterList.parameters) {
       if (parameter is FieldFormalParameter) {
-        reportError9(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, (parameter as FieldFormalParameter).identifier, []);
+        reportError10(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, parameter.identifier, []);
       }
     }
   }
@@ -6653,16 +6921,16 @@
   Token validateModifiersForClass(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.constKeyword != null) {
-      reportError11(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
+      reportError12(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError11(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError11(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
+      reportError12(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError11(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
+      reportError12(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
     }
     return modifiers.abstractKeyword;
   }
@@ -6676,25 +6944,25 @@
    */
   Token validateModifiersForConstructor(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError10(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError11(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError11(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, []);
+      reportError12(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, []);
     }
     if (modifiers.staticKeyword != null) {
-      reportError11(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword, []);
+      reportError12(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError11(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError12(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varKeyword, []);
     }
     Token externalKeyword = modifiers.externalKeyword;
     Token constKeyword = modifiers.constKeyword;
     Token factoryKeyword = modifiers.factoryKeyword;
     if (externalKeyword != null && constKeyword != null && constKeyword.offset < externalKeyword.offset) {
-      reportError11(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword, []);
     }
     if (externalKeyword != null && factoryKeyword != null && factoryKeyword.offset < externalKeyword.offset) {
-      reportError11(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword, []);
     }
     return constKeyword;
   }
@@ -6708,13 +6976,13 @@
    */
   Token validateModifiersForField(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError10(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError11(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError11(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
     }
     if (modifiers.factoryKeyword != null) {
-      reportError11(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+      reportError12(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
     }
     Token staticKeyword = modifiers.staticKeyword;
     Token constKeyword = modifiers.constKeyword;
@@ -6722,23 +6990,23 @@
     Token varKeyword = modifiers.varKeyword;
     if (constKeyword != null) {
       if (finalKeyword != null) {
-        reportError11(ParserErrorCode.CONST_AND_FINAL, finalKeyword, []);
+        reportError12(ParserErrorCode.CONST_AND_FINAL, finalKeyword, []);
       }
       if (varKeyword != null) {
-        reportError11(ParserErrorCode.CONST_AND_VAR, varKeyword, []);
+        reportError12(ParserErrorCode.CONST_AND_VAR, varKeyword, []);
       }
       if (staticKeyword != null && constKeyword.offset < staticKeyword.offset) {
-        reportError11(ParserErrorCode.STATIC_AFTER_CONST, staticKeyword, []);
+        reportError12(ParserErrorCode.STATIC_AFTER_CONST, staticKeyword, []);
       }
     } else if (finalKeyword != null) {
       if (varKeyword != null) {
-        reportError11(ParserErrorCode.FINAL_AND_VAR, varKeyword, []);
+        reportError12(ParserErrorCode.FINAL_AND_VAR, varKeyword, []);
       }
       if (staticKeyword != null && finalKeyword.offset < staticKeyword.offset) {
-        reportError11(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword, []);
+        reportError12(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword, []);
       }
     } else if (varKeyword != null && staticKeyword != null && varKeyword.offset < staticKeyword.offset) {
-      reportError11(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword, []);
+      reportError12(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword, []);
     }
     return lexicallyFirst([constKeyword, finalKeyword, varKeyword]);
   }
@@ -6750,7 +7018,7 @@
    */
   void validateModifiersForFunctionDeclarationStatement(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null || modifiers.constKeyword != null || modifiers.externalKeyword != null || modifiers.factoryKeyword != null || modifiers.finalKeyword != null || modifiers.staticKeyword != null || modifiers.varKeyword != null) {
-      reportError10(ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER, []);
+      reportError11(ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER, []);
     }
   }
 
@@ -6761,24 +7029,24 @@
    */
   void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError10(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError11(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError11(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
+      reportError12(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
     }
     if (modifiers.factoryKeyword != null) {
-      reportError11(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+      reportError12(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError11(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
+      reportError12(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError11(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError12(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
     }
     Token externalKeyword = modifiers.externalKeyword;
     Token staticKeyword = modifiers.staticKeyword;
     if (externalKeyword != null && staticKeyword != null && staticKeyword.offset < externalKeyword.offset) {
-      reportError11(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword, []);
     }
   }
 
@@ -6789,22 +7057,22 @@
    */
   void validateModifiersForOperator(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
-      reportError10(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+      reportError11(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError11(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
+      reportError12(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
     }
     if (modifiers.factoryKeyword != null) {
-      reportError11(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+      reportError12(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError11(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
+      reportError12(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
     }
     if (modifiers.staticKeyword != null) {
-      reportError11(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []);
+      reportError12(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError11(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError12(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
     }
   }
 
@@ -6815,10 +7083,10 @@
    */
   void validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
     if (modifiers.factoryKeyword != null) {
-      reportError11(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.factoryKeyword, []);
+      reportError12(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.factoryKeyword, []);
     }
     if (modifiers.staticKeyword != null) {
-      reportError11(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.staticKeyword, []);
+      reportError12(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.staticKeyword, []);
     }
   }
 
@@ -6830,16 +7098,16 @@
   void validateModifiersForTopLevelFunction(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.abstractKeyword != null) {
-      reportError10(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
+      reportError11(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError11(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
+      reportError12(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError11(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
+      reportError12(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError11(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+      reportError12(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
     }
   }
 
@@ -6853,24 +7121,24 @@
   Token validateModifiersForTopLevelVariable(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.abstractKeyword != null) {
-      reportError10(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
+      reportError11(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError11(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
     }
     Token constKeyword = modifiers.constKeyword;
     Token finalKeyword = modifiers.finalKeyword;
     Token varKeyword = modifiers.varKeyword;
     if (constKeyword != null) {
       if (finalKeyword != null) {
-        reportError11(ParserErrorCode.CONST_AND_FINAL, finalKeyword, []);
+        reportError12(ParserErrorCode.CONST_AND_FINAL, finalKeyword, []);
       }
       if (varKeyword != null) {
-        reportError11(ParserErrorCode.CONST_AND_VAR, varKeyword, []);
+        reportError12(ParserErrorCode.CONST_AND_VAR, varKeyword, []);
       }
     } else if (finalKeyword != null) {
       if (varKeyword != null) {
-        reportError11(ParserErrorCode.FINAL_AND_VAR, varKeyword, []);
+        reportError12(ParserErrorCode.FINAL_AND_VAR, varKeyword, []);
       }
     }
     return lexicallyFirst([constKeyword, finalKeyword, varKeyword]);
@@ -6885,19 +7153,19 @@
   void validateModifiersForTypedef(Modifiers modifiers) {
     validateModifiersForTopLevelDeclaration(modifiers);
     if (modifiers.abstractKeyword != null) {
-      reportError11(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
+      reportError12(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
     }
     if (modifiers.constKeyword != null) {
-      reportError11(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []);
+      reportError12(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []);
     }
     if (modifiers.externalKeyword != null) {
-      reportError11(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []);
+      reportError12(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []);
     }
     if (modifiers.finalKeyword != null) {
-      reportError11(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []);
+      reportError12(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []);
     }
     if (modifiers.varKeyword != null) {
-      reportError11(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []);
+      reportError12(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []);
     }
   }
 }
@@ -7340,7 +7608,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction8;
+  String correction9;
 
   /**
    * Initialize a newly created error code to have the given severity and message.
@@ -7363,7 +7631,7 @@
   ParserErrorCode.con2(String name, int ordinal, ErrorSeverity severity, String message, String correction) : super(name, ordinal) {
     this._severity = severity;
     this._message = message;
-    this.correction8 = correction;
+    this.correction9 = correction;
   }
 
   /**
@@ -7373,7 +7641,7 @@
    */
   ParserErrorCode.con3(String name, int ordinal, String message) : this.con1(name, ordinal, ErrorSeverity.ERROR, message);
 
-  String get correction => correction8;
+  String get correction => correction9;
 
   ErrorSeverity get errorSeverity => _severity;
 
@@ -8165,14 +8433,17 @@
       this._toNode = toNode;
       return fromNode.accept(this);
     }
+    //
+    // Check for a simple transformation caused by entering a period.
+    //
     if (toNode is PrefixedIdentifier) {
-      SimpleIdentifier prefix = (toNode as PrefixedIdentifier).prefix;
+      SimpleIdentifier prefix = toNode.prefix;
       if (fromNode.runtimeType == prefix.runtimeType) {
         this._toNode = prefix;
         return fromNode.accept(this);
       }
     } else if (toNode is PropertyAccess) {
-      Expression target = (toNode as PropertyAccess).target;
+      Expression target = toNode.target;
       if (fromNode.runtimeType == target.runtimeType) {
         this._toNode = target;
         return fromNode.accept(this);
@@ -8253,6 +8524,8 @@
  * AST node (and all of it's children) to a writer.
  */
 class ToFormattedSourceVisitor implements ASTVisitor<Object> {
+  static String COMMENTS_KEY = "List of comments before statement";
+
   /**
    * The writer to which the source is to be written.
    */
@@ -8444,9 +8717,11 @@
     ScriptTag scriptTag = node.scriptTag;
     NodeList<Directive> directives = node.directives;
     visit(scriptTag);
+    // directives
     String prefix = scriptTag == null ? "" : " ";
     visitList7(prefix, directives, "\n");
     nl();
+    // declarations
     prefix = scriptTag == null && directives.isEmpty ? "" : "\n";
     visitList7(prefix, node.declarations, "\n\n");
     return null;
@@ -9160,6 +9435,18 @@
     indent();
   }
 
+  void printLeadingComments(Statement statement) {
+    List<String> comments = statement.getProperty(COMMENTS_KEY) as List<String>;
+    if (comments == null) {
+      return;
+    }
+    for (String comment in comments) {
+      _writer.print(comment);
+      _writer.print("\n");
+      indent();
+    }
+  }
+
   /**
    * Safely visit the given node.
    *
@@ -9265,10 +9552,12 @@
     if (nodes != null) {
       int size = nodes.length;
       if (size != 0) {
+        // prefix
         _writer.print(prefix);
         if (prefix.endsWith("\n")) {
           indent();
         }
+        // nodes
         bool newLineSeparator = separator.endsWith("\n");
         for (int i = 0; i < size; i++) {
           if (i > 0) {
@@ -9277,8 +9566,13 @@
               indent();
             }
           }
-          nodes[i].accept(this);
+          ASTNode node = nodes[i];
+          if (node is Statement) {
+            printLeadingComments(node);
+          }
+          node.accept(this);
         }
+        // suffix
         _writer.print(suffix);
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 021db55..f8b90e9 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -21,6 +25,760 @@
 import 'constant.dart';
 
 /**
+ * Instances of the class `AngularCompilationUnitBuilder` build an Angular specific element
+ * model for a single compilation unit.
+ *
+ * @coverage dart.engine.resolver
+ */
+class AngularCompilationUnitBuilder {
+  static String _NG_COMPONENT = "NgComponent";
+
+  static String _NG_CONTROLLER = "NgController";
+
+  static String _NG_DIRECTIVE = "NgDirective";
+
+  static String _NG_FILTER = "NgFilter";
+
+  static String _NAME = "name";
+
+  static String _SELECTOR = "selector";
+
+  static String _PUBLISH_AS = "publishAs";
+
+  static String _TEMPLATE_URL = "templateUrl";
+
+  static String _CSS_URL = "cssUrl";
+
+  static String _PREFIX_ATTR = "@";
+
+  static String _PREFIX_CALLBACK = "&";
+
+  static String _PREFIX_ONE_WAY = "=>";
+
+  static String _PREFIX_ONE_WAY_ONE_TIME = "=>!";
+
+  static String _PREFIX_TWO_WAY = "<=>";
+
+  static String _NG_ATTR = "NgAttr";
+
+  static String _NG_CALLBACK = "NgCallback";
+
+  static String _NG_ONE_WAY = "NgOneWay";
+
+  static String _NG_ONE_WAY_ONE_TIME = "NgOneWayOneTime";
+
+  static String _NG_TWO_WAY = "NgTwoWay";
+
+  static Element getElement(ASTNode node, int offset) {
+    // maybe no node
+    if (node == null) {
+      return null;
+    }
+    // prepare enclosing ClassDeclaration
+    ClassDeclaration classDeclaration = node.getAncestor(ClassDeclaration);
+    if (classDeclaration == null) {
+      return null;
+    }
+    // prepare ClassElement
+    ClassElement classElement = classDeclaration.element;
+    if (classElement == null) {
+      return null;
+    }
+    // check toolkit objects
+    for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) {
+      List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARRAY;
+      // try properties of AngularComponentElement
+      if (toolkitObject is AngularComponentElement) {
+        AngularComponentElement component = toolkitObject;
+        properties = component.properties;
+      }
+      // try properties of AngularDirectiveElement
+      if (toolkitObject is AngularDirectiveElement) {
+        AngularDirectiveElement directive = toolkitObject;
+        properties = directive.properties;
+      }
+      // check properties
+      for (AngularPropertyElement property in properties) {
+        // property name (use complete node range)
+        int propertyOffset = property.nameOffset;
+        int propertyEnd = propertyOffset + property.name.length;
+        if (node.offset <= propertyOffset && propertyEnd < node.end) {
+          return property;
+        }
+        // field name (use complete node range, including @, => and <=>)
+        FieldElement field = property.field;
+        if (field != null) {
+          int fieldOffset = property.fieldNameOffset;
+          int fieldEnd = fieldOffset + field.name.length;
+          if (node.offset <= fieldOffset && fieldEnd < node.end) {
+            return field;
+          }
+        }
+      }
+    }
+    // no Element
+    return null;
+  }
+
+  /**
+   * Checks if given [Type] is an Angular <code>Module</code> or its subclass.
+   */
+  static bool isModule(Type2 type) {
+    if (type is! InterfaceType) {
+      return false;
+    }
+    InterfaceType interfaceType = type as InterfaceType;
+    // check hierarchy
+    Set<Type2> seenTypes = new Set();
+    while (interfaceType != null) {
+      // check for recursion
+      if (!seenTypes.add(interfaceType)) {
+        return false;
+      }
+      // check for "Module"
+      if (interfaceType.element.name == "Module") {
+        return true;
+      }
+      // try supertype
+      interfaceType = interfaceType.superclass;
+    }
+    // no
+    return false;
+  }
+
+  /**
+   * Parses given selector text and returns [AngularSelectorElement]. May be `null` if
+   * cannot parse.
+   */
+  static AngularSelectorElement parseSelector(int offset, String text) {
+    if (text.startsWith("[") && text.endsWith("]")) {
+      int nameOffset = offset + "[".length;
+      String attributeName = text.substring(1, text.length - 1);
+      // TODO(scheglov) report warning if there are spaces between [ and identifier
+      return new HasAttributeSelectorElementImpl(attributeName, nameOffset);
+    }
+    if (StringUtilities.isTagName(text)) {
+      return new IsTagSelectorElementImpl(text, offset);
+    }
+    return null;
+  }
+
+  /**
+   * Returns the [FieldElement] of the first field in the given [FieldDeclaration].
+   */
+  static FieldElement getOnlyFieldElement(FieldDeclaration fieldDeclaration) {
+    NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables;
+    return fields[0].element as FieldElement;
+  }
+
+  /**
+   * If given [Annotation] has one argument and it is [SimpleStringLiteral], returns it,
+   * otherwise returns `null`.
+   */
+  static SimpleStringLiteral getOnlySimpleStringLiteralArgument(Annotation annotation) {
+    SimpleStringLiteral nameLiteral = null;
+    ArgumentList argsNode = annotation.arguments;
+    if (argsNode != null) {
+      NodeList<Expression> args = argsNode.arguments;
+      if (args.length == 1) {
+        Expression arg = args[0];
+        if (arg is SimpleStringLiteral) {
+          nameLiteral = arg;
+        }
+      }
+    }
+    return nameLiteral;
+  }
+
+  /**
+   * Checks if given [LocalVariableElement] is an Angular <code>Module</code>.
+   */
+  static bool isModule2(VariableDeclaration node) {
+    Type2 type = node.name.bestType;
+    return isModule(type);
+  }
+
+  /**
+   * Parses given [SimpleStringLiteral] using [parseSelector].
+   */
+  static AngularSelectorElement parseSelector2(SimpleStringLiteral literal) {
+    int offset = literal.valueOffset;
+    String text = literal.stringValue;
+    return parseSelector(offset, text);
+  }
+
+  /**
+   * The source containing the unit that will be analyzed.
+   */
+  Source _source;
+
+  /**
+   * The listener to which errors will be reported.
+   */
+  AnalysisErrorListener _errorListener;
+
+  /**
+   * The [ClassDeclaration] that is currently being analyzed.
+   */
+  ClassDeclaration _classDeclaration;
+
+  /**
+   * The [ClassElementImpl] that is currently being analyzed.
+   */
+  ClassElementImpl _classElement;
+
+  /**
+   * The [ToolkitObjectElement]s to set for [classElement].
+   */
+  List<ToolkitObjectElement> _classToolkitObjects = [];
+
+  /**
+   * The [Annotation] that is currently being analyzed.
+   */
+  Annotation _annotation;
+
+  /**
+   * Initialize a newly created compilation unit element builder.
+   *
+   * @param errorListener the listener to which errors will be reported.
+   * @param source the source containing the unit that will be analyzed
+   */
+  AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source source) {
+    this._errorListener = errorListener;
+    this._source = source;
+  }
+
+  /**
+   * Builds Angular specific element models and adds them to the existing Dart elements.
+   *
+   * @param unit the compilation unit with built Dart element models
+   */
+  void build(CompilationUnit unit) {
+    // process classes
+    for (CompilationUnitMember unitMember in unit.declarations) {
+      if (unitMember is ClassDeclaration) {
+        this._classDeclaration = unitMember;
+        this._classElement = _classDeclaration.element as ClassElementImpl;
+        this._classToolkitObjects.clear();
+        parseModuleClass();
+        // process annotations
+        NodeList<Annotation> annotations = _classDeclaration.metadata;
+        for (Annotation annotation in annotations) {
+          this._annotation = annotation;
+          // @NgFilter
+          if (isAngularAnnotation2(_NG_FILTER)) {
+            parseNgFilter();
+            continue;
+          }
+          // @NgComponent
+          if (isAngularAnnotation2(_NG_COMPONENT)) {
+            parseNgComponent();
+            continue;
+          }
+          // @NgController
+          if (isAngularAnnotation2(_NG_CONTROLLER)) {
+            parseNgController();
+            continue;
+          }
+          // @NgDirective
+          if (isAngularAnnotation2(_NG_DIRECTIVE)) {
+            parseNgDirective();
+            continue;
+          }
+        }
+        // set toolkit objects
+        if (!_classToolkitObjects.isEmpty) {
+          List<ToolkitObjectElement> objects = _classToolkitObjects;
+          _classElement.toolkitObjects = new List.from(objects);
+        }
+      }
+    }
+    // process modules in variables
+    parseModuleVariables(unit);
+  }
+
+  /**
+   * Creates [AngularModuleElementImpl] for given information.
+   */
+  AngularModuleElementImpl createModuleElement(List<AngularModuleElement> childModules, List<ClassElement> keyTypes) {
+    AngularModuleElementImpl module = new AngularModuleElementImpl();
+    module.childModules = new List.from(childModules);
+    module.keyTypes = new List.from(keyTypes);
+    return module;
+  }
+
+  /**
+   * @return the argument [Expression] with given name form [annotation], may be
+   *         `null` if not found.
+   */
+  Expression getArgument(String name) {
+    List<Expression> arguments = _annotation.arguments.arguments;
+    for (Expression argument in arguments) {
+      if (argument is NamedExpression) {
+        NamedExpression namedExpression = argument;
+        String argumentName = namedExpression.name.label.name;
+        if (name == argumentName) {
+          return namedExpression.expression;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * @return the [String] value of the named argument.
+   */
+  String getStringArgument(String name) => getStringLiteral(name).value;
+
+  /**
+   * @return the offset of the value of the named argument.
+   */
+  int getStringArgumentOffset(String name) {
+    Expression argument = getArgument(name);
+    return (argument as SimpleStringLiteral).valueOffset;
+  }
+
+  /**
+   * @return the [SimpleStringLiteral] of the named argument.
+   */
+  SimpleStringLiteral getStringLiteral(String name) {
+    Expression argument = getArgument(name);
+    return argument as SimpleStringLiteral;
+  }
+
+  /**
+   * Checks if [namedArguments] has string value for the argument with the given name.
+   */
+  bool hasStringArgument(String name) {
+    Expression argument = getArgument(name);
+    return argument is SimpleStringLiteral;
+  }
+
+  /**
+   * Checks if given [Annotation] is an annotation with required name.
+   */
+  bool isAngularAnnotation(Annotation annotation, String name) {
+    Element element = annotation.element;
+    if (element is ConstructorElement) {
+      ConstructorElement constructorElement = element;
+      return constructorElement.returnType.displayName == name;
+    }
+    return false;
+  }
+
+  /**
+   * Checks if [annotation] is an annotation with required name.
+   */
+  bool isAngularAnnotation2(String name) => isAngularAnnotation(_annotation, name);
+
+  /**
+   * Checks if [classElement] is an Angular <code>Module</code>.
+   */
+  bool get isModule4 {
+    InterfaceType supertype = _classElement.supertype;
+    return isModule(supertype);
+  }
+
+  /**
+   * Analyzes [classDeclaration] and if it is a module, creates [AngularModuleElement]
+   * model for it.
+   */
+  void parseModuleClass() {
+    if (!isModule4) {
+      return;
+    }
+    // check install(), type() and value() invocations
+    List<AngularModuleElement> childModules = [];
+    List<ClassElement> keyTypes = [];
+    _classDeclaration.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleClass(this, childModules, keyTypes));
+    // set module element
+    AngularModuleElementImpl module = createModuleElement(childModules, keyTypes);
+    _classToolkitObjects.add(module);
+  }
+
+  /**
+   * Checks if given [MethodInvocation] is an interesting <code>Module</code> method
+   * invocation and remembers corresponding elements into lists.
+   */
+  void parseModuleInvocation(MethodInvocation node, List<AngularModuleElement> childModules, List<ClassElement> keyTypes) {
+    String methodName = node.methodName.name;
+    NodeList<Expression> arguments = node.argumentList.arguments;
+    // install()
+    if (arguments.length == 1 && methodName == "install") {
+      Type2 argType = arguments[0].bestType;
+      if (argType is InterfaceType) {
+        ClassElement argElement = argType.element;
+        List<ToolkitObjectElement> toolkitObjects = argElement.toolkitObjects;
+        for (ToolkitObjectElement toolkitObject in toolkitObjects) {
+          if (toolkitObject is AngularModuleElement) {
+            childModules.add(toolkitObject);
+          }
+        }
+      }
+      return;
+    }
+    // type() and value()
+    if (arguments.length >= 1 && (methodName == "type" || methodName == "value")) {
+      Expression arg = arguments[0];
+      if (arg is Identifier) {
+        Element argElement = arg.staticElement;
+        if (argElement is ClassElement) {
+          keyTypes.add(argElement);
+        }
+      }
+      return;
+    }
+  }
+
+  /**
+   * Checks every local variable in the given unit to see if it is a <code>Module</code> and creates
+   * [AngularModuleElement] for it.
+   */
+  void parseModuleVariables(CompilationUnit unit) {
+    unit.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables(this));
+  }
+
+  void parseNgComponent() {
+    bool isValid = true;
+    // publishAs
+    if (!hasStringArgument(_PUBLISH_AS)) {
+      reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []);
+      isValid = false;
+    }
+    // selector
+    AngularSelectorElement selector = null;
+    if (!hasStringArgument(_SELECTOR)) {
+      reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []);
+      isValid = false;
+    } else {
+      SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR);
+      selector = parseSelector2(selectorLiteral);
+      if (selector == null) {
+        reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [selectorLiteral]);
+        isValid = false;
+      }
+    }
+    // templateUrl
+    if (!hasStringArgument(_TEMPLATE_URL)) {
+      reportErrorForAnnotation(AngularCode.MISSING_TEMPLATE_URL, []);
+      isValid = false;
+    }
+    // cssUrl
+    if (!hasStringArgument(_CSS_URL)) {
+      reportErrorForAnnotation(AngularCode.MISSING_CSS_URL, []);
+      isValid = false;
+    }
+    // create
+    if (isValid) {
+      String name = getStringArgument(_PUBLISH_AS);
+      int nameOffset = getStringArgumentOffset(_PUBLISH_AS);
+      String templateUri = getStringArgument(_TEMPLATE_URL);
+      int templateUriOffset = getStringArgumentOffset(_TEMPLATE_URL);
+      String styleUri = getStringArgument(_CSS_URL);
+      int styleUriOffset = getStringArgumentOffset(_CSS_URL);
+      AngularComponentElementImpl element = new AngularComponentElementImpl(name, nameOffset);
+      element.selector = selector;
+      element.templateUri = templateUri;
+      element.templateUriOffset = templateUriOffset;
+      element.styleUri = styleUri;
+      element.styleUriOffset = styleUriOffset;
+      element.properties = parseNgComponentProperties(true);
+      _classToolkitObjects.add(element);
+    }
+  }
+
+  /**
+   * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration].
+   */
+  List<AngularPropertyElement> parseNgComponentProperties(bool fromFields) {
+    List<AngularPropertyElement> properties = [];
+    parseNgComponentProperties_fromMap(properties);
+    if (fromFields) {
+      parseNgComponentProperties_fromFields(properties);
+    }
+    return new List.from(properties);
+  }
+
+  /**
+   * Parses [AngularPropertyElement]s from [annotation].
+   */
+  void parseNgComponentProperties_fromFields(List<AngularPropertyElement> properties) {
+    NodeList<ClassMember> members = _classDeclaration.members;
+    for (ClassMember member in members) {
+      if (member is FieldDeclaration) {
+        FieldDeclaration fieldDeclaration = member;
+        for (Annotation annotation in fieldDeclaration.metadata) {
+          // prepare property kind (if property annotation at all)
+          AngularPropertyKind kind = null;
+          if (isAngularAnnotation(annotation, _NG_ATTR)) {
+            kind = AngularPropertyKind.ATTR;
+          } else if (isAngularAnnotation(annotation, _NG_CALLBACK)) {
+            kind = AngularPropertyKind.CALLBACK;
+          } else if (isAngularAnnotation(annotation, _NG_ONE_WAY)) {
+            kind = AngularPropertyKind.ONE_WAY;
+          } else if (isAngularAnnotation(annotation, _NG_ONE_WAY_ONE_TIME)) {
+            kind = AngularPropertyKind.ONE_WAY_ONE_TIME;
+          } else if (isAngularAnnotation(annotation, _NG_TWO_WAY)) {
+            kind = AngularPropertyKind.TWO_WAY;
+          }
+          // add property
+          if (kind != null) {
+            SimpleStringLiteral nameLiteral = getOnlySimpleStringLiteralArgument(annotation);
+            FieldElement field = getOnlyFieldElement(fieldDeclaration);
+            if (nameLiteral != null && field != null) {
+              AngularPropertyElementImpl property = new AngularPropertyElementImpl(nameLiteral.value, nameLiteral.valueOffset);
+              property.field = field;
+              property.propertyKind = kind;
+              properties.add(property);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Parses [AngularPropertyElement]s from [annotation].
+   */
+  void parseNgComponentProperties_fromMap(List<AngularPropertyElement> properties) {
+    Expression mapExpression = getArgument("map");
+    // may be not properties
+    if (mapExpression == null) {
+      return;
+    }
+    // prepare map literal
+    if (mapExpression is! MapLiteral) {
+      reportError(mapExpression, AngularCode.INVALID_PROPERTY_MAP, []);
+      return;
+    }
+    MapLiteral mapLiteral = mapExpression as MapLiteral;
+    // analyze map entries
+    for (MapLiteralEntry entry in mapLiteral.entries) {
+      // prepare property name
+      Expression nameExpression = entry.key;
+      if (nameExpression is! SimpleStringLiteral) {
+        reportError(nameExpression, AngularCode.INVALID_PROPERTY_NAME, []);
+        continue;
+      }
+      SimpleStringLiteral nameLiteral = nameExpression as SimpleStringLiteral;
+      String name = nameLiteral.value;
+      int nameOffset = nameLiteral.valueOffset;
+      // prepare field specification
+      Expression specExpression = entry.value;
+      if (specExpression is! SimpleStringLiteral) {
+        reportError(specExpression, AngularCode.INVALID_PROPERTY_SPEC, []);
+        continue;
+      }
+      SimpleStringLiteral specLiteral = specExpression as SimpleStringLiteral;
+      String spec = specLiteral.value;
+      // parse binding kind and field name
+      AngularPropertyKind kind;
+      int fieldNameOffset;
+      if (spec.startsWith(_PREFIX_ATTR)) {
+        kind = AngularPropertyKind.ATTR;
+        fieldNameOffset = 1;
+      } else if (spec.startsWith(_PREFIX_CALLBACK)) {
+        kind = AngularPropertyKind.CALLBACK;
+        fieldNameOffset = 1;
+      } else if (spec.startsWith(_PREFIX_ONE_WAY_ONE_TIME)) {
+        kind = AngularPropertyKind.ONE_WAY_ONE_TIME;
+        fieldNameOffset = 3;
+      } else if (spec.startsWith(_PREFIX_ONE_WAY)) {
+        kind = AngularPropertyKind.ONE_WAY;
+        fieldNameOffset = 2;
+      } else if (spec.startsWith(_PREFIX_TWO_WAY)) {
+        kind = AngularPropertyKind.TWO_WAY;
+        fieldNameOffset = 3;
+      } else {
+        reportError(specLiteral, AngularCode.INVALID_PROPERTY_KIND, [spec]);
+        continue;
+      }
+      String fieldName = spec.substring(fieldNameOffset);
+      fieldNameOffset += specLiteral.valueOffset;
+      // prepare field
+      FieldElement field = _classElement.getField(fieldName);
+      if (field == null) {
+        reportError2(fieldNameOffset, fieldName.length, AngularCode.INVALID_PROPERTY_FIELD, [fieldName]);
+        continue;
+      }
+      // add property
+      AngularPropertyElementImpl property = new AngularPropertyElementImpl(name, nameOffset);
+      property.field = field;
+      property.propertyKind = kind;
+      property.fieldNameOffset = fieldNameOffset;
+      properties.add(property);
+    }
+  }
+
+  void parseNgController() {
+    bool isValid = true;
+    // publishAs
+    if (!hasStringArgument(_PUBLISH_AS)) {
+      reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []);
+      isValid = false;
+    }
+    // selector
+    AngularSelectorElement selector = null;
+    if (!hasStringArgument(_SELECTOR)) {
+      reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []);
+      isValid = false;
+    } else {
+      SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR);
+      selector = parseSelector2(selectorLiteral);
+      if (selector == null) {
+        reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [selectorLiteral]);
+        isValid = false;
+      }
+    }
+    // create
+    if (isValid) {
+      String name = getStringArgument(_PUBLISH_AS);
+      int nameOffset = getStringArgumentOffset(_PUBLISH_AS);
+      AngularControllerElementImpl element = new AngularControllerElementImpl(name, nameOffset);
+      element.selector = selector;
+      _classToolkitObjects.add(element);
+    }
+  }
+
+  void parseNgDirective() {
+    bool isValid = true;
+    // selector
+    AngularSelectorElement selector = null;
+    if (!hasStringArgument(_SELECTOR)) {
+      reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []);
+      isValid = false;
+    } else {
+      SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR);
+      selector = parseSelector2(selectorLiteral);
+      if (selector == null) {
+        reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [selectorLiteral]);
+        isValid = false;
+      }
+    }
+    // create
+    if (isValid) {
+      int offset = _annotation.offset;
+      AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offset);
+      element.selector = selector;
+      element.properties = parseNgComponentProperties(false);
+      _classToolkitObjects.add(element);
+    }
+  }
+
+  void parseNgFilter() {
+    bool isValid = true;
+    // name
+    if (!hasStringArgument(_NAME)) {
+      reportErrorForAnnotation(AngularCode.MISSING_NAME, []);
+      isValid = false;
+    }
+    // create
+    if (isValid) {
+      String name = getStringArgument(_NAME);
+      int nameOffset = getStringArgumentOffset(_NAME);
+      _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset));
+    }
+  }
+
+  void reportError(ASTNode node, ErrorCode errorCode, List<Object> arguments) {
+    int offset = node.offset;
+    int length = node.length;
+    reportError2(offset, length, errorCode, arguments);
+  }
+
+  void reportError2(int offset, int length, ErrorCode errorCode, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, offset, length, errorCode, arguments));
+  }
+
+  void reportErrorForAnnotation(ErrorCode errorCode, List<Object> arguments) {
+    reportError(_annotation, errorCode, arguments);
+  }
+
+  void reportErrorForArgument(String argumentName, ErrorCode errorCode, List<Object> arguments) {
+    Expression argument = getArgument(argumentName);
+    reportError(argument, errorCode, arguments);
+  }
+}
+
+class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleClass extends RecursiveASTVisitor<Object> {
+  final AngularCompilationUnitBuilder AngularCompilationUnitBuilder_this;
+
+  List<AngularModuleElement> childModules;
+
+  List<ClassElement> keyTypes;
+
+  RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleClass(this.AngularCompilationUnitBuilder_this, this.childModules, this.keyTypes) : super();
+
+  Object visitMethodInvocation(MethodInvocation node) {
+    if (node.target == null) {
+      AngularCompilationUnitBuilder_this.parseModuleInvocation(node, childModules, keyTypes);
+    }
+    return null;
+  }
+}
+
+class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables extends RecursiveASTVisitor<Object> {
+  final AngularCompilationUnitBuilder AngularCompilationUnitBuilder_this;
+
+  RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables(this.AngularCompilationUnitBuilder_this) : super();
+
+  LocalVariableElementImpl _variable = null;
+
+  Expression _variableInit = null;
+
+  List<AngularModuleElement> _childModules = [];
+
+  List<ClassElement> _keyTypes = [];
+
+  Object visitClassDeclaration(ClassDeclaration node) => null;
+
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    _childModules.clear();
+    _keyTypes.clear();
+    super.visitFunctionDeclaration(node);
+    if (_variable != null) {
+      AngularModuleElementImpl module = AngularCompilationUnitBuilder_this.createModuleElement(_childModules, _keyTypes);
+      _variable.toolkitObjects = <ToolkitObjectElement> [module];
+    }
+    return null;
+  }
+
+  Object visitMethodInvocation(MethodInvocation node) {
+    if (_variable != null) {
+      if (isVariableInvocation(node)) {
+        AngularCompilationUnitBuilder_this.parseModuleInvocation(node, _childModules, _keyTypes);
+      }
+    }
+    return null;
+  }
+
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    VariableElement element = node.element;
+    if (element is LocalVariableElementImpl && AngularCompilationUnitBuilder.isModule2(node)) {
+      _variable = element;
+      _variableInit = node.initializer;
+    }
+    return super.visitVariableDeclaration(node);
+  }
+
+  bool isVariableInvocation(MethodInvocation node) {
+    Expression target = node.realTarget;
+    // var module = new Module()..type(t1)..type(t2);
+    if (_variableInit is CascadeExpression && target != null && identical(target.parent, _variableInit)) {
+      return true;
+    }
+    // var module = new Module();
+    // module.type(t);
+    if (target is Identifier) {
+      Element targetElement = target.staticElement;
+      return identical(targetElement, _variable);
+    }
+    // no
+    return false;
+  }
+}
+
+/**
  * Instances of the class `CompilationUnitBuilder` build an element model for a single
  * compilation unit.
  *
@@ -143,6 +901,9 @@
     element.type = interfaceType;
     List<ConstructorElement> constructors = holder.constructors;
     if (constructors.length == 0) {
+      //
+      // Create the default constructor.
+      //
       constructors = createDefaultConstructors(interfaceType);
     }
     element.abstract = node.abstractKeyword != null;
@@ -177,6 +938,7 @@
     InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
+    // set default constructor
     element.constructors = createDefaultConstructors(interfaceType);
     for (FunctionTypeImpl functionType in _functionTypesToFix) {
       functionType.typeArguments = typeArguments;
@@ -249,6 +1011,7 @@
     parameter.const3 = node.isConst;
     parameter.final2 = node.isFinal;
     parameter.parameterKind = node.kind;
+    // set initializer, default value range
     Expression defaultValue = node.defaultValue;
     if (defaultValue != null) {
       visit(holder, defaultValue);
@@ -261,6 +1024,7 @@
       parameter.initializer = initializer;
       parameter.setDefaultValueRange(defaultValue.offset, defaultValue.length);
     }
+    // visible range
     setParameterVisibleRange(node, parameter);
     _currentHolder.addParameter(parameter);
     parameterName.staticElement = parameter;
@@ -290,6 +1054,9 @@
       _currentHolder.addParameter(parameter);
       parameterName.staticElement = parameter;
     }
+    //
+    // The children of this parameter include any parameters defined on the type of this parameter.
+    //
     ElementHolder holder = new ElementHolder();
     visitChildren(holder, node);
     (node.element as ParameterElementImpl).parameters = holder.parameters;
@@ -330,6 +1097,7 @@
       } else {
         SimpleIdentifier propertyNameNode = node.name;
         if (propertyNameNode == null) {
+          // TODO(brianwilkerson) Report this internal error.
           return null;
         }
         String propertyName = propertyNameNode.name;
@@ -433,6 +1201,9 @@
       _currentHolder.addParameter(parameter);
       parameterName.staticElement = parameter;
     }
+    //
+    // The children of this parameter include any parameters defined on the type of this parameter.
+    //
     ElementHolder holder = new ElementHolder();
     visitChildren(holder, node);
     (node.element as ParameterElementImpl).parameters = holder.parameters;
@@ -598,6 +1369,7 @@
       Block enclosingBlock = node.getAncestor(Block);
       int functionEnd = node.offset + node.length;
       int blockEnd = enclosingBlock.offset + enclosingBlock.length;
+      // TODO(brianwilkerson) This isn't right for variables declared in a for loop.
       variable.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
       _currentHolder.addLocalVariable(variable);
       variableName.staticElement = element;
@@ -1225,6 +1997,7 @@
           _resolvedLibraries.addAll(resolver.resolvedLibraries);
           _errorListener.addAll(resolver.errorListener);
         } on AnalysisException catch (exception) {
+          //TODO (danrubel): Handle or forward the exception
           AnalysisEngine.instance.logger.logError3(exception);
         }
         node.scriptElement = script;
@@ -1234,6 +2007,8 @@
         if (scriptSourcePath != null) {
           try {
             scriptSourcePath = Uri.encodeFull(scriptSourcePath);
+            // Force an exception to be thrown if the URI is invalid so that we can report the
+            // problem.
             parseUriWithException(scriptSourcePath);
             Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
             script.scriptSource = scriptSource;
@@ -1297,7 +2072,7 @@
    */
   ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) {
     for (ht.XmlAttributeNode attribute in node.attributes) {
-      if (attribute.name.lexeme == _SRC) {
+      if (attribute.name == _SRC) {
         return attribute;
       }
     }
@@ -1305,6 +2080,11 @@
   }
 
   Object reportCircularity(ht.XmlTagNode node) {
+    //
+    // This should not be possible, but we have an error report that suggests that it happened at
+    // least once. This code will guard against infinite recursion and might help us identify the
+    // cause of the issue.
+    //
     JavaStringBuilder builder = new JavaStringBuilder();
     builder.append("Found circularity in XML nodes: ");
     bool first = true;
@@ -1314,7 +2094,7 @@
       } else {
         builder.append(", ");
       }
-      String tagName = pathNode.tag.lexeme;
+      String tagName = pathNode.tag;
       if (identical(pathNode, node)) {
         builder.append("*");
         builder.append(tagName);
@@ -1350,8 +2130,8 @@
    * @param arguments the arguments used to compose the error message
    */
   void reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, List<Object> arguments) {
-    int offset = attribute.value.offset + 1;
-    int length = attribute.value.length - 2;
+    int offset = attribute.valueToken.offset + 1;
+    int length = attribute.valueToken.length - 2;
     reportError(errorCode, offset, length, arguments);
   }
 
@@ -1439,6 +2219,8 @@
     ClassElement outerClass = _enclosingClass;
     try {
       _enclosingClass = node.element;
+      // Commented out until we decide that we want this hint in the analyzer
+      //    checkForOverrideEqualsButNotHashCode(node);
       return super.visitClassDeclaration(node);
     } finally {
       _enclosingClass = outerClass;
@@ -1450,6 +2232,11 @@
     return super.visitExportDirective(node);
   }
 
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    checkForMissingReturn(node.returnType, node.functionExpression.body);
+    return super.visitFunctionDeclaration(node);
+  }
+
   Object visitImportDirective(ImportDirective node) {
     checkForDeprecatedMemberUse(node.uriElement, node);
     return super.visitImportDirective(node);
@@ -1471,7 +2258,9 @@
   }
 
   Object visitMethodDeclaration(MethodDeclaration node) {
-    checkForOverridingPrivateMember(node);
+    // This was determined to not be a good hint, see: dartbug.com/16029
+    //checkForOverridingPrivateMember(node);
+    checkForMissingReturn(node.returnType, node.body);
     return super.visitMethodDeclaration(node);
   }
 
@@ -1520,29 +2309,37 @@
       return false;
     }
     String rhsNameStr = typeName.name.name;
+    // if x is dynamic
     if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) {
       if (node.notOperator == null) {
-        _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
+        // the is case
+        _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
       } else {
-        _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node, []);
+        // the is not case
+        _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node, []);
       }
       return true;
     }
     Element rhsElement = rhsType.element;
     LibraryElement libraryElement = rhsElement != null ? rhsElement.library : null;
     if (libraryElement != null && libraryElement.isDartCore) {
+      // if x is Object or null is Null
       if (rhsType.isObject || (expression is NullLiteral && rhsNameStr == _NULL_TYPE_NAME)) {
         if (node.notOperator == null) {
-          _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
+          // the is case
+          _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
         } else {
-          _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node, []);
+          // the is not case
+          _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node, []);
         }
         return true;
       } else if (rhsNameStr == _NULL_TYPE_NAME) {
         if (node.notOperator == null) {
-          _errorReporter.reportError2(HintCode.TYPE_CHECK_IS_NULL, node, []);
+          // the is case
+          _errorReporter.reportError3(HintCode.TYPE_CHECK_IS_NULL, node, []);
         } else {
-          _errorReporter.reportError2(HintCode.TYPE_CHECK_IS_NOT_NULL, node, []);
+          // the is not case
+          _errorReporter.reportError3(HintCode.TYPE_CHECK_IS_NOT_NULL, node, []);
         }
         return true;
       }
@@ -1563,13 +2360,15 @@
     if (element != null && element.isDeprecated) {
       String displayName = element.displayName;
       if (element is ConstructorElement) {
-        ConstructorElement constructorElement = element as ConstructorElement;
+        // TODO(jwren) We should modify ConstructorElement.getDisplayName(), or have the logic
+        // centralized elsewhere, instead of doing this logic here.
+        ConstructorElement constructorElement = element;
         displayName = constructorElement.enclosingElement.displayName;
         if (!constructorElement.displayName.isEmpty) {
           displayName = "${displayName}.${constructorElement.displayName}";
         }
       }
-      _errorReporter.reportError2(HintCode.DEPRECATED_MEMBER_USE, node, [displayName]);
+      _errorReporter.reportError3(HintCode.DEPRECATED_MEMBER_USE, node, [displayName]);
       return true;
     }
     return false;
@@ -1594,7 +2393,7 @@
       return false;
     }
     ASTNode parent = identifier.parent;
-    if ((parent is ConstructorName && identical(identifier, (parent as ConstructorName).name)) || (parent is SuperConstructorInvocation && identical(identifier, (parent as SuperConstructorInvocation).constructorName)) || parent is HideCombinator) {
+    if ((parent is ConstructorName && identical(identifier, parent.name)) || (parent is SuperConstructorInvocation && identical(identifier, parent.constructorName)) || parent is HideCombinator) {
       return false;
     }
     return checkForDeprecatedMemberUse(identifier.bestElement, identifier);
@@ -1608,9 +2407,11 @@
    * @see HintCode#DIVISION_OPTIMIZATION
    */
   bool checkForDivisionOptimizationHint(BinaryExpression node) {
+    // Return if the operator is not '/'
     if (node.operator.type != sc.TokenType.SLASH) {
       return false;
     }
+    // Return if the '/' operator is not defined in core, or if we don't know its static or propagated type
     MethodElement methodElement = node.bestElement;
     if (methodElement == null) {
       return false;
@@ -1619,12 +2420,13 @@
     if (libraryElement != null && !libraryElement.isDartCore) {
       return false;
     }
+    // Report error if the (x/y) has toInt() invoked on it
     if (node.parent is ParenthesizedExpression) {
       ParenthesizedExpression parenthesizedExpression = wrapParenthesizedExpression(node.parent as ParenthesizedExpression);
       if (parenthesizedExpression.parent is MethodInvocation) {
         MethodInvocation methodInvocation = parenthesizedExpression.parent as MethodInvocation;
         if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && methodInvocation.argumentList.arguments.isEmpty) {
-          _errorReporter.reportError2(HintCode.DIVISION_OPTIMIZATION, methodInvocation, []);
+          _errorReporter.reportError3(HintCode.DIVISION_OPTIMIZATION, methodInvocation, []);
           return true;
         }
       }
@@ -1633,6 +2435,18 @@
   }
 
   /**
+   * Generate a hint for functions or methods that have a return type, but do not have a return
+   * statement on all branches. At the end of blocks with no return, Dart implicitly returns
+   * `null`, avoiding these implicit returns is considered a best practice.
+   *
+   * @param node the binary expression to check
+   * @param body the function body
+   * @return `true` if and only if a hint code is generated on the passed node
+   * @see HintCode#MISSING_RETURN
+   */
+  bool checkForMissingReturn(TypeName returnType, FunctionBody body) => false;
+
+  /**
    * Check for the passed class declaration for the
    * [HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
    *
@@ -1649,7 +2463,7 @@
     if (equalsOperatorMethodElement != null) {
       PropertyAccessorElement hashCodeElement = classElement.getGetter(_HASHCODE_GETTER_NAME);
       if (hashCodeElement == null) {
-        _errorReporter.reportError2(HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE, node.name, [classElement.displayName]);
+        _errorReporter.reportError3(HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE, node.name, [classElement.displayName]);
         return true;
       }
     }
@@ -1657,24 +2471,31 @@
   }
 
   /**
-   * Check for the passed class declaration for the
-   * [HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+   * Checks that if the passed method declaration is private, it does not override a private member
+   * in a superclass.
    *
-   * @param node the class declaration to check
+   * @param node the method declaration to check
    * @return `true` if and only if a hint code is generated on the passed node
    * @see HintCode#OVERRIDDING_PRIVATE_MEMBER
    */
   bool checkForOverridingPrivateMember(MethodDeclaration node) {
+    // If not in an enclosing class, return false
     if (_enclosingClass == null) {
       return false;
     }
+    // If the member is not private, return false
     if (!Identifier.isPrivateName(node.name.name)) {
       return false;
     }
+    // Get the element of the member, if null, return false
     ExecutableElement executableElement = node.element;
     if (executableElement == null) {
       return false;
     }
+    // Loop through all of the superclasses looking for a matching method or accessor
+    // TODO(jwren) If the HintGenerator needs or has easy access to the InheritanceManager in the
+    // future then this could be refactored down to be more readable, however, since we are only
+    // looking through super classes (and not the entire interface graph) there is no pressing need
     String elementName = executableElement.name;
     bool isGetterOrSetter = executableElement is PropertyAccessorElement;
     InterfaceType superType = _enclosingClass.supertype;
@@ -1695,7 +2516,7 @@
           }
           if (overriddenAccessor != null) {
             String memberType = (executableElement as PropertyAccessorElement).isGetter ? _GETTER : _SETTER;
-            _errorReporter.reportError2(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
+            _errorReporter.reportError3(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
                 memberType,
                 executableElement.displayName,
                 classElement.displayName]);
@@ -1704,7 +2525,7 @@
         } else {
           MethodElement overriddenMethod = classElement.getMethod(elementName);
           if (overriddenMethod != null) {
-            _errorReporter.reportError2(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
+            _errorReporter.reportError3(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
                 _METHOD,
                 executableElement.displayName,
                 classElement.displayName]);
@@ -1730,8 +2551,10 @@
     TypeName typeName = node.type;
     Type2 lhsType = expression.staticType;
     Type2 rhsType = typeName.type;
+    // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to remove the
+    // !(x instanceof TypeParameterType) checks.
     if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isDynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsType.isSubtypeOf(rhsType)) {
-      _errorReporter.reportError2(HintCode.UNNECESSARY_CAST, node, []);
+      _errorReporter.reportError3(HintCode.UNNECESSARY_CAST, node, []);
       return true;
     }
     return false;
@@ -1787,11 +2610,20 @@
       Element element = type.element;
       String typeNameStr = element.name;
       LibraryElement libraryElement = element.library;
+      //      if (typeNameStr.equals(INT_TYPE_NAME) && libraryElement != null
+      //          && libraryElement.isDartCore()) {
+      //        if (node.getNotOperator() == null) {
+      //          errorReporter.reportError(HintCode.IS_INT, node);
+      //        } else {
+      //          errorReporter.reportError(HintCode.IS_NOT_INT, node);
+      //        }
+      //        return true;
+      //      } else
       if (typeNameStr == _DOUBLE_TYPE_NAME && libraryElement != null && libraryElement.isDartCore) {
         if (node.notOperator == null) {
-          _errorReporter.reportError2(HintCode.IS_DOUBLE, node, []);
+          _errorReporter.reportError3(HintCode.IS_DOUBLE, node, []);
         } else {
-          _errorReporter.reportError2(HintCode.IS_NOT_DOUBLE, node, []);
+          _errorReporter.reportError3(HintCode.IS_NOT_DOUBLE, node, []);
         }
         return true;
       }
@@ -1830,12 +2662,16 @@
       if (!isDebugConstant(lhsCondition)) {
         ValidResult lhsResult = getConstantBooleanValue(lhsCondition);
         if (lhsResult != null) {
-          if (identical(lhsResult, ValidResult.RESULT_TRUE) && isBarBar) {
-            _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, []);
+          if (lhsResult.isTrue && isBarBar) {
+            // report error on else block: true || !e!
+            _errorReporter.reportError3(HintCode.DEAD_CODE, node.rightOperand, []);
+            // only visit the LHS:
             safelyVisit(lhsCondition);
             return null;
-          } else if (identical(lhsResult, ValidResult.RESULT_FALSE) && isAmpAmp) {
-            _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, []);
+          } else if (lhsResult.isFalse && isAmpAmp) {
+            // report error on if block: false && !e!
+            _errorReporter.reportError3(HintCode.DEAD_CODE, node.rightOperand, []);
+            // only visit the LHS:
             safelyVisit(lhsCondition);
             return null;
           }
@@ -1862,7 +2698,7 @@
         Statement lastStatement = statements[size - 1];
         int offset = nextStatement.offset;
         int length = lastStatement.end - offset;
-        _errorReporter.reportError4(HintCode.DEAD_CODE, offset, length, []);
+        _errorReporter.reportError5(HintCode.DEAD_CODE, offset, length, []);
         return null;
       }
     }
@@ -1875,12 +2711,14 @@
     if (!isDebugConstant(conditionExpression)) {
       ValidResult result = getConstantBooleanValue(conditionExpression);
       if (result != null) {
-        if (identical(result, ValidResult.RESULT_TRUE)) {
-          _errorReporter.reportError2(HintCode.DEAD_CODE, node.elseExpression, []);
+        if (result.isTrue) {
+          // report error on else block: true ? 1 : !2!
+          _errorReporter.reportError3(HintCode.DEAD_CODE, node.elseExpression, []);
           safelyVisit(node.thenExpression);
           return null;
         } else {
-          _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenExpression, []);
+          // report error on if block: false ? !1! : 2
+          _errorReporter.reportError3(HintCode.DEAD_CODE, node.thenExpression, []);
           safelyVisit(node.elseExpression);
           return null;
         }
@@ -1895,15 +2733,17 @@
     if (!isDebugConstant(conditionExpression)) {
       ValidResult result = getConstantBooleanValue(conditionExpression);
       if (result != null) {
-        if (identical(result, ValidResult.RESULT_TRUE)) {
+        if (result.isTrue) {
+          // report error on else block: if(true) {} else {!}
           Statement elseStatement = node.elseStatement;
           if (elseStatement != null) {
-            _errorReporter.reportError2(HintCode.DEAD_CODE, elseStatement, []);
+            _errorReporter.reportError3(HintCode.DEAD_CODE, elseStatement, []);
             safelyVisit(node.thenStatement);
             return null;
           }
         } else {
-          _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenStatement, []);
+          // report error on if block: if (false) {!} else {}
+          _errorReporter.reportError3(HintCode.DEAD_CODE, node.thenStatement, []);
           safelyVisit(node.elseStatement);
           return null;
         }
@@ -1921,17 +2761,23 @@
     for (int i = 0; i < numOfCatchClauses; i++) {
       CatchClause catchClause = catchClauses[i];
       if (catchClause.onKeyword != null) {
+        // on-catch clause found, verify that the exception type is not a subtype of a previous
+        // on-catch exception type
         TypeName typeName = catchClause.exceptionType;
         if (typeName != null && typeName.type != null) {
           Type2 currentType = typeName.type;
           if (currentType.isObject) {
+            // Found catch clause clause that has Object as an exception type, this is equivalent to
+            // having a catch clause that doesn't have an exception type, visit the block, but
+            // generate an error on any following catch clauses (and don't visit them).
             safelyVisit(catchClause);
             if (i + 1 != numOfCatchClauses) {
+              // this catch clause is not the last in the try statement
               CatchClause nextCatchClause = catchClauses[i + 1];
               CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
               int offset = nextCatchClause.offset;
               int length = lastCatchClause.end - offset;
-              _errorReporter.reportError4(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length, []);
+              _errorReporter.reportError5(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length, []);
               return null;
             }
           }
@@ -1940,7 +2786,7 @@
               CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
               int offset = catchClause.offset;
               int length = lastCatchClause.end - offset;
-              _errorReporter.reportError4(HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, offset, length, [currentType.displayName, type.displayName]);
+              _errorReporter.reportError5(HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, offset, length, [currentType.displayName, type.displayName]);
               return null;
             }
           }
@@ -1948,13 +2794,16 @@
         }
         safelyVisit(catchClause);
       } else {
+        // Found catch clause clause that doesn't have an exception type, visit the block, but
+        // generate an error on any following catch clauses (and don't visit them).
         safelyVisit(catchClause);
         if (i + 1 != numOfCatchClauses) {
+          // this catch clause is not the last in the try statement
           CatchClause nextCatchClause = catchClauses[i + 1];
           CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
           int offset = nextCatchClause.offset;
           int length = lastCatchClause.end - offset;
-          _errorReporter.reportError4(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length, []);
+          _errorReporter.reportError5(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length, []);
           return null;
         }
       }
@@ -1968,8 +2817,9 @@
     if (!isDebugConstant(conditionExpression)) {
       ValidResult result = getConstantBooleanValue(conditionExpression);
       if (result != null) {
-        if (identical(result, ValidResult.RESULT_FALSE)) {
-          _errorReporter.reportError2(HintCode.DEAD_CODE, node.body, []);
+        if (result.isFalse) {
+          // report error on if block: while (false) {!}
+          _errorReporter.reportError3(HintCode.DEAD_CODE, node.body, []);
           return null;
         }
       }
@@ -1990,12 +2840,23 @@
    */
   ValidResult getConstantBooleanValue(Expression expression) {
     if (expression is BooleanLiteral) {
-      if ((expression as BooleanLiteral).value) {
-        return ValidResult.RESULT_TRUE;
+      if (expression.value) {
+        return new ValidResult(new DartObjectImpl(null, BoolState.from(true)));
       } else {
-        return ValidResult.RESULT_FALSE;
+        return new ValidResult(new DartObjectImpl(null, BoolState.from(false)));
       }
     }
+    // Don't consider situations where we could evaluate to a constant boolean expression with the
+    // ConstantVisitor
+    //    else {
+    //      EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+    //      if (result == ValidResult.RESULT_TRUE) {
+    //        return ValidResult.RESULT_TRUE;
+    //      } else if (result == ValidResult.RESULT_FALSE) {
+    //        return ValidResult.RESULT_FALSE;
+    //      }
+    //      return null;
+    //    }
     return null;
   }
 
@@ -2008,10 +2869,10 @@
   bool isDebugConstant(Expression expression) {
     Element element = null;
     if (expression is Identifier) {
-      Identifier identifier = expression as Identifier;
+      Identifier identifier = expression;
       element = identifier.staticElement;
     } else if (expression is PropertyAccess) {
-      PropertyAccess propertyAccess = expression as PropertyAccess;
+      PropertyAccess propertyAccess = expression;
       element = propertyAccess.propertyName.staticElement;
     }
     if (element is PropertyAccessorElement) {
@@ -2087,11 +2948,15 @@
   void generateForCompilationUnit(CompilationUnit unit, Source source) {
     ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
     _importsVerifier.visitCompilationUnit(unit);
+    // dead code analysis
     new DeadCodeVerifier(errorReporter).visitCompilationUnit(unit);
+    // dart2js analysis
     if (_enableDart2JSHints) {
       new Dart2JSVerifier(errorReporter).visitCompilationUnit(unit);
     }
+    // Dart best practices
     new BestPracticesVerifier(errorReporter).visitCompilationUnit(unit);
+    // Find to-do comments
     new ToDoFinder(errorReporter).findIn(unit);
   }
 }
@@ -2189,7 +3054,7 @@
    */
   void generateDuplicateImportHints(ErrorReporter errorReporter) {
     for (ImportDirective duplicateImport in _duplicateImports) {
-      errorReporter.reportError2(HintCode.DUPLICATE_IMPORT, duplicateImport.uri, []);
+      errorReporter.reportError3(HintCode.DUPLICATE_IMPORT, duplicateImport.uri, []);
     }
   }
 
@@ -2203,6 +3068,7 @@
    */
   void generateUnusedImportHints(ErrorReporter errorReporter) {
     for (ImportDirective unusedImport in _unusedImports) {
+      // Check that the import isn't dart:core
       ImportElement importElement = unusedImport.element;
       if (importElement != null) {
         LibraryElement libraryElement = importElement.importedLibrary;
@@ -2210,7 +3076,7 @@
           continue;
         }
       }
-      errorReporter.reportError2(HintCode.UNUSED_IMPORT, unusedImport.uri, []);
+      errorReporter.reportError3(HintCode.UNUSED_IMPORT, unusedImport.uri, []);
     }
   }
 
@@ -2219,36 +3085,51 @@
       NodeList<Directive> directives = node.directives;
       for (Directive directive in directives) {
         if (directive is ImportDirective) {
-          ImportDirective importDirective = directive as ImportDirective;
+          ImportDirective importDirective = directive;
           LibraryElement libraryElement = importDirective.uriElement;
           if (libraryElement != null) {
             _unusedImports.add(importDirective);
+            //
+            // Initialize prefixElementMap
+            //
             if (importDirective.asToken != null) {
               SimpleIdentifier prefixIdentifier = importDirective.prefix;
               if (prefixIdentifier != null) {
                 Element element = prefixIdentifier.staticElement;
                 if (element is PrefixElement) {
-                  PrefixElement prefixElementKey = element as PrefixElement;
+                  PrefixElement prefixElementKey = element;
                   _prefixElementMap[prefixElementKey] = importDirective;
                 }
               }
             }
+            //
+            // Initialize libraryMap: libraryElement -> importDirective
+            //
             putIntoLibraryMap(libraryElement, importDirective);
+            //
+            // For this new addition to the libraryMap, also recursively add any exports from the
+            // libraryElement
+            //
             addAdditionalLibrariesForExports(libraryElement, importDirective, new List<LibraryElement>());
           }
         }
       }
     }
+    // If there are no imports in this library, don't visit the identifiers in the library- there
+    // can be no unused imports.
     if (_unusedImports.isEmpty) {
       return null;
     }
     if (_unusedImports.length > 1) {
+      // order the list of unusedImports to find duplicates in faster than O(n^2) time
       List<ImportDirective> importDirectiveArray = new List.from(_unusedImports);
       importDirectiveArray.sort(ImportDirective.COMPARATOR);
       ImportDirective currentDirective = importDirectiveArray[0];
       for (int i = 1; i < importDirectiveArray.length; i++) {
         ImportDirective nextDirective = importDirectiveArray[i];
         if (ImportDirective.COMPARATOR(currentDirective, nextDirective) == 0) {
+          // Add either the currentDirective or nextDirective depending on which comes second, this
+          // guarantees that the first of the duplicates won't be highlighted.
           if (currentDirective.offset < nextDirective.offset) {
             _duplicateImports.add(nextDirective);
           } else {
@@ -2277,12 +3158,16 @@
   }
 
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    // If the prefixed identifier references some A.B, where A is a library prefix, then we can
+    // lookup the associated ImportDirective in prefixElementMap and remove it from the
+    // unusedImports list.
     SimpleIdentifier prefixIdentifier = node.prefix;
     Element element = prefixIdentifier.staticElement;
     if (element is PrefixElement) {
       _unusedImports.remove(_prefixElementMap[element]);
       return null;
     }
+    // Otherwise, pass the prefixed identifier element and name onto visitIdentifier.
     return visitIdentifier(element, prefixIdentifier.name);
   }
 
@@ -2317,6 +3202,7 @@
   Namespace computeNamespace(ImportDirective importDirective) {
     Namespace namespace = _namespaceMap[importDirective];
     if (namespace == null) {
+      // If the namespace isn't in the namespaceMap, then compute and put it in the map
       ImportElement importElement = importDirective.element;
       if (importElement != null) {
         NamespaceBuilder builder = new NamespaceBuilder();
@@ -2346,8 +3232,9 @@
     if (element == null) {
       return null;
     }
+    // If the element is multiply defined then call this method recursively for each of the conflicting elements.
     if (element is MultiplyDefinedElement) {
-      MultiplyDefinedElement multiplyDefinedElement = element as MultiplyDefinedElement;
+      MultiplyDefinedElement multiplyDefinedElement = element;
       for (Element elt in multiplyDefinedElement.conflictingElements) {
         visitIdentifier(elt, name);
       }
@@ -2360,6 +3247,7 @@
     if (containingLibrary == null) {
       return null;
     }
+    // If the element is declared in the current library, return.
     if (_currentLibrary == containingLibrary) {
       return null;
     }
@@ -2368,10 +3256,14 @@
       return null;
     }
     if (importsFromSameLibrary.length == 1) {
+      // If there is only one import directive for this library, then it must be the directive that
+      // this element is imported with, remove it from the unusedImports list.
       ImportDirective usedImportDirective = importsFromSameLibrary[0];
       _unusedImports.remove(usedImportDirective);
     } else {
+      // Otherwise, for each of the imported directives, use the namespaceMap to
       for (ImportDirective importDirective in importsFromSameLibrary) {
+        // Get the namespace for this import
         Namespace namespace = computeNamespace(importDirective);
         if (namespace != null && namespace.get(name) != null) {
           _unusedImports.remove(importDirective);
@@ -2443,11 +3335,13 @@
         if (fullNameIndex < 4) {
           return false;
         }
+        // Check for "/lib" at a specified place in the fullName
         if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) {
           String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSPEC_YAML;
           Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePubspecPath);
           if (pubspecSource != null && pubspecSource.exists()) {
-            _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, uriLiteral, []);
+            // Files inside the lib directory hierarchy should not reference files outside
+            _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, uriLiteral, []);
           }
           return true;
         }
@@ -2493,7 +3387,9 @@
     String fullName = getSourceFullName(source);
     if (fullName != null) {
       if (!fullName.contains("/lib/")) {
-        _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, uriLiteral, []);
+        // Files outside the lib directory hierarchy should not reference files inside
+        // ... use package: url instead
+        _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, uriLiteral, []);
         return true;
       }
     }
@@ -2510,7 +3406,8 @@
    */
   bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path) {
     if (path.startsWith("../") || path.contains("/../")) {
-      _errorReporter.reportError2(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, uriLiteral, []);
+      // Package import should not to contain ".."
+      _errorReporter.reportError3(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, uriLiteral, []);
       return true;
     }
     return false;
@@ -2658,7 +3555,7 @@
     if (matcher.find()) {
       int offset = commentToken.offset + matcher.start() + matcher.group(1).length;
       int length = matcher.group(2).length;
-      _errorReporter.reportError4(TodoCode.TODO, offset, length, [matcher.group(2)]);
+      _errorReporter.reportError5(TodoCode.TODO, offset, length, [matcher.group(2)]);
     }
   }
 }
@@ -3203,7 +4100,7 @@
   }
 
   void gatherElements(Element element) {
-    element.accept(new GeneralizingElementVisitor_7(this));
+    element.accept(new GeneralizingElementVisitor_DeclarationMatcher_gatherElements(this));
   }
 
   /**
@@ -3265,10 +4162,10 @@
 class DeclarationMatcher_DeclarationMismatchException extends RuntimeException {
 }
 
-class GeneralizingElementVisitor_7 extends GeneralizingElementVisitor<Object> {
+class GeneralizingElementVisitor_DeclarationMatcher_gatherElements extends GeneralizingElementVisitor<Object> {
   final DeclarationMatcher DeclarationMatcher_this;
 
-  GeneralizingElementVisitor_7(this.DeclarationMatcher_this) : super();
+  GeneralizingElementVisitor_DeclarationMatcher_gatherElements(this.DeclarationMatcher_this) : super();
 
   Object visitElement(Element element) {
     DeclarationMatcher_this._allElements.add(element);
@@ -3853,7 +4750,7 @@
    */
   static ClassElementImpl getTypeReference(Expression expr) {
     if (expr is Identifier) {
-      Identifier identifier = expr as Identifier;
+      Identifier identifier = expr;
       if (identifier.staticElement is ClassElementImpl) {
         return identifier.staticElement as ClassElementImpl;
       }
@@ -3867,7 +4764,7 @@
   static bool isConstructorReturnType(SimpleIdentifier node) {
     ASTNode parent = node.parent;
     if (parent is ConstructorDeclaration) {
-      ConstructorDeclaration constructor = parent as ConstructorDeclaration;
+      ConstructorDeclaration constructor = parent;
       return identical(constructor.returnType, node);
     }
     return false;
@@ -3880,7 +4777,7 @@
   static bool isFactoryConstructorReturnType(SimpleIdentifier node) {
     ASTNode parent = node.parent;
     if (parent is ConstructorDeclaration) {
-      ConstructorDeclaration constructor = parent as ConstructorDeclaration;
+      ConstructorDeclaration constructor = parent;
       return identical(constructor.returnType, node) && constructor.factoryKeyword != null;
     }
     return false;
@@ -3991,6 +4888,10 @@
         node.propagatedElement = propagatedMethod;
         bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod);
         bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+        //
+        // If we are about to generate the hint (propagated version of this warning), then check
+        // that the member is not in a subtype of the propagated type.
+        //
         if (shouldReportMissingMember_propagated) {
           if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
             shouldReportMissingMember_propagated = false;
@@ -4021,6 +4922,10 @@
         node.propagatedElement = propagatedMethod;
         bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod);
         bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+        //
+        // If we are about to generate the hint (propagated version of this warning), then check
+        // that the member is not in a subtype of the propagated type.
+        //
         if (shouldReportMissingMember_propagated) {
           if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
             shouldReportMissingMember_propagated = false;
@@ -4041,7 +4946,7 @@
     SimpleIdentifier labelNode = node.label;
     LabelElementImpl labelElement = lookupLabel(node, labelNode);
     if (labelElement != null && labelElement.isOnSwitchMember) {
-      _resolver.reportError6(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
+      _resolver.reportError7(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
     }
     return null;
   }
@@ -4059,11 +4964,15 @@
   Object visitCommentReference(CommentReference node) {
     Identifier identifier = node.identifier;
     if (identifier is SimpleIdentifier) {
-      SimpleIdentifier simpleIdentifier = identifier as SimpleIdentifier;
+      SimpleIdentifier simpleIdentifier = identifier;
       Element element = resolveSimpleIdentifier(simpleIdentifier);
       if (element == null) {
+        //
+        // This might be a reference to an imported name that is missing the prefix.
+        //
         element = findImportWithoutPrefix(simpleIdentifier);
         if (element is MultiplyDefinedElement) {
+          // TODO(brianwilkerson) Report this error?
           element = null;
         }
       }
@@ -4084,7 +4993,7 @@
         }
       }
     } else if (identifier is PrefixedIdentifier) {
-      PrefixedIdentifier prefixedIdentifier = identifier as PrefixedIdentifier;
+      PrefixedIdentifier prefixedIdentifier = identifier;
       SimpleIdentifier prefix = prefixedIdentifier.prefix;
       SimpleIdentifier name = prefixedIdentifier.identifier;
       Element element = resolveSimpleIdentifier(prefix);
@@ -4092,12 +5001,14 @@
       } else {
         if (element is PrefixElement) {
           prefix.staticElement = element;
+          // TODO(brianwilkerson) Report this error?
           element = _resolver.nameScope.lookup(identifier, _definingLibrary);
           name.staticElement = element;
           return null;
         }
         LibraryElement library = element.library;
         if (library == null) {
+          // TODO(brianwilkerson) We need to understand how the library could ever be null.
           AnalysisEngine.instance.logger.logError("Found element with null library: ${element.name}");
         } else if (library != _definingLibrary) {
         }
@@ -4136,15 +5047,17 @@
     super.visitConstructorDeclaration(node);
     ConstructorElement element = node.element;
     if (element is ConstructorElementImpl) {
-      ConstructorElementImpl constructorElement = element as ConstructorElementImpl;
+      ConstructorElementImpl constructorElement = element;
+      // set redirected factory constructor
       ConstructorName redirectedNode = node.redirectedConstructor;
       if (redirectedNode != null) {
         ConstructorElement redirectedElement = redirectedNode.staticElement;
         constructorElement.redirectedConstructor = redirectedElement;
       }
+      // set redirected generate constructor
       for (ConstructorInitializer initializer in node.initializers) {
         if (initializer is RedirectingConstructorInvocation) {
-          ConstructorElement redirectedElement = (initializer as RedirectingConstructorInvocation).staticElement;
+          ConstructorElement redirectedElement = initializer.staticElement;
           constructorElement.redirectedConstructor = redirectedElement;
         }
       }
@@ -4156,12 +5069,12 @@
   Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     SimpleIdentifier fieldName = node.fieldName;
     ClassElement enclosingClass = _resolver.enclosingClass;
-    FieldElement fieldElement = (enclosingClass as ClassElementImpl).getField(fieldName.name);
+    FieldElement fieldElement = enclosingClass.getField(fieldName.name);
     fieldName.staticElement = fieldElement;
     if (fieldElement == null || fieldElement.isSynthetic) {
-      _resolver.reportError6(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+      _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
     } else if (fieldElement.isStatic) {
-      _resolver.reportError6(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
+      _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
     }
     return null;
   }
@@ -4171,15 +5084,17 @@
     if (type != null && type.isDynamic) {
       return null;
     } else if (type is! InterfaceType) {
+      // TODO(brianwilkerson) Report these errors.
       ASTNode parent = node.parent;
       if (parent is InstanceCreationExpression) {
-        if ((parent as InstanceCreationExpression).isConst) {
+        if (parent.isConst) {
         } else {
         }
       } else {
       }
       return null;
     }
+    // look up ConstructorElement
     ConstructorElement constructor;
     SimpleIdentifier name = node.name;
     InterfaceType interfaceType = type as InterfaceType;
@@ -4197,7 +5112,7 @@
     SimpleIdentifier labelNode = node.label;
     LabelElementImpl labelElement = lookupLabel(node, labelNode);
     if (labelElement != null && labelElement.isOnSwitchStatement) {
-      _resolver.reportError6(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
+      _resolver.reportError7(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
     }
     return null;
   }
@@ -4210,7 +5125,10 @@
   Object visitExportDirective(ExportDirective node) {
     Element element = node.element;
     if (element is ExportElement) {
-      resolveCombinators((element as ExportElement).exportedLibrary, node.combinators);
+      // The element is null when the URI is invalid
+      // TODO(brianwilkerson) Figure out whether the element can ever be something other than an
+      // ExportElement
+      resolveCombinators(element.exportedLibrary, node.combinators);
       setMetadata(element, node);
     }
     return null;
@@ -4220,13 +5138,13 @@
     String fieldName = node.identifier.name;
     ClassElement classElement = _resolver.enclosingClass;
     if (classElement != null) {
-      FieldElement fieldElement = (classElement as ClassElementImpl).getField(fieldName);
+      FieldElement fieldElement = classElement.getField(fieldName);
       if (fieldElement == null) {
-        _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+        _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
       } else {
         ParameterElement parameterElement = node.element;
         if (parameterElement is FieldFormalParameterElementImpl) {
-          FieldFormalParameterElementImpl fieldFormal = parameterElement as FieldFormalParameterElementImpl;
+          FieldFormalParameterElementImpl fieldFormal = parameterElement;
           fieldFormal.field = fieldElement;
           Type2 declaredType = fieldFormal.type;
           Type2 fieldType = fieldElement.type;
@@ -4234,21 +5152,27 @@
             fieldFormal.type = fieldType;
           }
           if (fieldElement.isSynthetic) {
-            _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+            _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
           } else if (fieldElement.isStatic) {
-            _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
+            _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
           } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) {
-            _resolver.reportError6(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
+            // TODO(brianwilkerson) We should implement a displayName() method for types that will
+            // work nicely with function types and then use that below.
+            _resolver.reportError7(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
           }
         } else {
           if (fieldElement.isSynthetic) {
-            _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
+            _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD, node, [fieldName]);
           } else if (fieldElement.isStatic) {
-            _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
+            _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
           }
         }
       }
     }
+    //    else {
+    //    // TODO(jwren) Report error, constructor initializer variable is a top level element
+    //    // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCodes)
+    //    }
     return super.visitFieldFormalParameter(node);
   }
 
@@ -4258,9 +5182,10 @@
   }
 
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    // TODO(brianwilkerson) Can we ever resolve the function being invoked?
     Expression expression = node.function;
     if (expression is FunctionExpression) {
-      FunctionExpression functionExpression = expression as FunctionExpression;
+      FunctionExpression functionExpression = expression;
       ExecutableElement functionElement = functionExpression.element;
       ArgumentList argumentList = node.argumentList;
       List<ParameterElement> parameters = resolveArgumentsToParameters(false, argumentList, functionElement);
@@ -4289,6 +5214,7 @@
     }
     ImportElement importElement = node.element;
     if (importElement != null) {
+      // The element is null when the URI is invalid
       LibraryElement library = importElement.importedLibrary;
       if (library != null) {
         resolveCombinators(library, node.combinators);
@@ -4307,27 +5233,39 @@
     bool isInGetterContext = node.inGetterContext();
     bool isInSetterContext = node.inSetterContext();
     if (isInGetterContext && isInSetterContext) {
+      // lookup setter
       MethodElement setterStaticMethod = lookUpMethod(target, staticType, setterMethodName);
       MethodElement setterPropagatedMethod = lookUpMethod(target, propagatedType, setterMethodName);
+      // set setter element
       node.staticElement = setterStaticMethod;
       node.propagatedElement = setterPropagatedMethod;
+      // generate undefined method warning
       checkForUndefinedIndexOperator(node, target, getterMethodName, setterStaticMethod, setterPropagatedMethod, staticType, propagatedType);
+      // lookup getter method
       MethodElement getterStaticMethod = lookUpMethod(target, staticType, getterMethodName);
       MethodElement getterPropagatedMethod = lookUpMethod(target, propagatedType, getterMethodName);
+      // set getter element
       AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMethod, getterPropagatedMethod);
       node.auxiliaryElements = auxiliaryElements;
+      // generate undefined method warning
       checkForUndefinedIndexOperator(node, target, getterMethodName, getterStaticMethod, getterPropagatedMethod, staticType, propagatedType);
     } else if (isInGetterContext) {
+      // lookup getter method
       MethodElement staticMethod = lookUpMethod(target, staticType, getterMethodName);
       MethodElement propagatedMethod = lookUpMethod(target, propagatedType, getterMethodName);
+      // set getter element
       node.staticElement = staticMethod;
       node.propagatedElement = propagatedMethod;
+      // generate undefined method warning
       checkForUndefinedIndexOperator(node, target, getterMethodName, staticMethod, propagatedMethod, staticType, propagatedType);
     } else if (isInSetterContext) {
+      // lookup setter method
       MethodElement staticMethod = lookUpMethod(target, staticType, setterMethodName);
       MethodElement propagatedMethod = lookUpMethod(target, propagatedType, setterMethodName);
+      // set setter element
       node.staticElement = staticMethod;
       node.propagatedElement = propagatedMethod;
+      // generate undefined method warning
       checkForUndefinedIndexOperator(node, target, setterMethodName, staticMethod, propagatedMethod, staticType, propagatedType);
     }
     return null;
@@ -4356,11 +5294,19 @@
 
   Object visitMethodInvocation(MethodInvocation node) {
     SimpleIdentifier methodName = node.methodName;
+    //
+    // Synthetic identifiers have been already reported during parsing.
+    //
     if (methodName.isSynthetic) {
       return null;
     }
+    //
+    // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm(a1, ..., an)'. The
+    // first step is to figure out which executable is being invoked, using both the static and the
+    // propagated type information.
+    //
     Expression target = node.realTarget;
-    if (target is SuperExpression && !isSuperInValidContext(target as SuperExpression)) {
+    if (target is SuperExpression && !isSuperInValidContext(target)) {
       return null;
     }
     Element staticElement;
@@ -4370,9 +5316,14 @@
       propagatedElement = null;
     } else {
       Type2 staticType = getStaticType(target);
+      //
+      // If this method invocation is of the form 'C.m' where 'C' is a class, then we don't call
+      // resolveInvokedElement(..) which walks up the class hierarchy, instead we just look for the
+      // member in the type only.
+      //
       ClassElementImpl typeReference = getTypeReference(target);
       if (typeReference != null) {
-        staticElement = propagatedElement = resolveElement(typeReference, methodName.name);
+        staticElement = propagatedElement = resolveElement(typeReference, methodName);
       } else {
         staticElement = resolveInvokedElement(target, staticType, methodName);
         propagatedElement = resolveInvokedElement(target, getPropagatedType(target), methodName);
@@ -4380,6 +5331,9 @@
     }
     staticElement = convertSetterToGetter(staticElement);
     propagatedElement = convertSetterToGetter(propagatedElement);
+    //
+    // Record the results.
+    //
     methodName.staticElement = staticElement;
     methodName.propagatedElement = propagatedElement;
     ArgumentList argumentList = node.argumentList;
@@ -4395,6 +5349,9 @@
         argumentList.correspondingPropagatedParameters = parameters;
       }
     }
+    //
+    // Then check for error conditions.
+    //
     ErrorCode errorCode = checkForInvocationError(target, true, staticElement);
     bool generatedWithTypePropagation = false;
     if (_enableHints && errorCode == null && staticElement == null) {
@@ -4427,9 +5384,9 @@
       return null;
     }
     if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
-      _resolver.reportError6(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
+      _resolver.reportError7(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
     } else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) {
-      _resolver.reportError6(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
+      _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
     } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
       String targetTypeName;
       if (target == null) {
@@ -4438,16 +5395,22 @@
         ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode;
         _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
       } else {
+        // ignore Function "call"
+        // (if we are about to create a hint using type propagation, then we can use type
+        // propagation here as well)
         Type2 targetType = null;
         if (!generatedWithTypePropagation) {
           targetType = getStaticType(target);
         } else {
+          // choose the best type
           targetType = getPropagatedType(target);
           if (targetType == null) {
             targetType = getStaticType(target);
           }
         }
         if (targetType != null && targetType.isDartCoreFunction && methodName.name == CALL_METHOD_NAME) {
+          // TODO(brianwilkerson) Can we ever resolve the function being invoked?
+          //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
           return null;
         }
         targetTypeName = targetType == null ? null : targetType.displayName;
@@ -4455,9 +5418,11 @@
         _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
       }
     } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
+      // Generate the type name.
+      // The error code will never be generated via type propagation
       Type2 targetType = getStaticType(target);
       String targetTypeName = targetType == null ? null : targetType.name;
-      _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
+      _resolver.reportError7(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
     }
     return null;
   }
@@ -4483,6 +5448,10 @@
     node.propagatedElement = propagatedMethod;
     bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod);
     bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+    //
+    // If we are about to generate the hint (propagated version of this warning), then check
+    // that the member is not in a subtype of the propagated type.
+    //
     if (shouldReportMissingMember_propagated) {
       if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
         shouldReportMissingMember_propagated = false;
@@ -4500,6 +5469,9 @@
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
     SimpleIdentifier prefix = node.prefix;
     SimpleIdentifier identifier = node.identifier;
+    //
+    // First, check to see whether the prefix is really a prefix.
+    //
     Element prefixElement = prefix.staticElement;
     if (prefixElement is PrefixElement) {
       Element element = _resolver.nameScope.lookup(node, _definingLibrary);
@@ -4508,13 +5480,13 @@
       }
       if (element == null) {
         if (identifier.inSetterContext()) {
-          _resolver.reportError6(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, prefixElement.name]);
+          _resolver.reportError7(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, prefixElement.name]);
         } else if (node.parent is Annotation) {
           Annotation annotation = node.parent as Annotation;
-          _resolver.reportError6(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+          _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
           return null;
         } else {
-          _resolver.reportError6(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, prefixElement.name]);
+          _resolver.reportError7(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, prefixElement.name]);
         }
         return null;
       }
@@ -4527,7 +5499,10 @@
           }
         }
       }
+      // TODO(brianwilkerson) The prefix needs to be resolved to the element for the import that
+      // defines the prefix, not the prefix's element.
       identifier.staticElement = element;
+      // Validate annotation element.
       if (node.parent is Annotation) {
         Annotation annotation = node.parent as Annotation;
         resolveAnnotationElement(annotation);
@@ -4535,10 +5510,15 @@
       }
       return null;
     }
+    // May be annotation, resolve invocation of "const" constructor.
     if (node.parent is Annotation) {
       Annotation annotation = node.parent as Annotation;
       resolveAnnotationElement(annotation);
     }
+    //
+    // Otherwise, the prefix is really an expression that happens to be a simple identifier and this
+    // is really equivalent to a property access node.
+    //
     resolvePropertyAccess(prefix, identifier);
     return null;
   }
@@ -4557,6 +5537,10 @@
       node.propagatedElement = propagatedMethod;
       bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod);
       bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+      //
+      // If we are about to generate the hint (propagated version of this warning), then check
+      // that the member is not in a subtype of the propagated type.
+      //
       if (shouldReportMissingMember_propagated) {
         if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
           shouldReportMissingMember_propagated = false;
@@ -4574,7 +5558,7 @@
 
   Object visitPropertyAccess(PropertyAccess node) {
     Expression target = node.realTarget;
-    if (target is SuperExpression && !isSuperInValidContext(target as SuperExpression)) {
+    if (target is SuperExpression && !isSuperInValidContext(target)) {
       return null;
     }
     SimpleIdentifier propertyName = node.propertyName;
@@ -4585,6 +5569,7 @@
   Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
     ClassElement enclosingClass = _resolver.enclosingClass;
     if (enclosingClass == null) {
+      // TODO(brianwilkerson) Report this error.
       return null;
     }
     SimpleIdentifier name = node.constructorName;
@@ -4595,6 +5580,7 @@
       element = enclosingClass.getNamedConstructor(name.name);
     }
     if (element == null) {
+      // TODO(brianwilkerson) Report this error and decide what element to associate with the node.
       return null;
     }
     if (name != null) {
@@ -4610,30 +5596,44 @@
   }
 
   Object visitSimpleIdentifier(SimpleIdentifier node) {
+    //
+    // Synthetic identifiers have been already reported during parsing.
+    //
     if (node.isSynthetic) {
       return null;
     }
+    //
+    // We ignore identifiers that have already been resolved, such as identifiers representing the
+    // name in a declaration.
+    //
     if (node.staticElement != null) {
       return null;
     }
+    //
+    // The name dynamic denotes a Type object even though dynamic is not a class.
+    //
     if (node.name == _dynamicType.name) {
       node.staticElement = _dynamicType.element;
       node.staticType = _typeType;
       return null;
     }
+    //
+    // Otherwise, the node should be resolved.
+    //
     Element element = resolveSimpleIdentifier(node);
     ClassElement enclosingClass = _resolver.enclosingClass;
     if (isFactoryConstructorReturnType(node) && element != enclosingClass) {
-      _resolver.reportError6(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
+      _resolver.reportError7(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
     } else if (isConstructorReturnType(node) && element != enclosingClass) {
-      _resolver.reportError6(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
+      _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
       element = null;
     } else if (element == null || (element is PrefixElement && !isValidAsPrefix(node))) {
+      // TODO(brianwilkerson) Recover from this error.
       if (isConstructorReturnType(node)) {
-        _resolver.reportError6(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
+        _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
       } else if (node.parent is Annotation) {
         Annotation annotation = node.parent as Annotation;
-        _resolver.reportError6(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+        _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
       } else {
         _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
       }
@@ -4644,6 +5644,9 @@
       AuxiliaryElements auxiliaryElements = new AuxiliaryElements(lookUpGetter(null, enclosingType, node.name), null);
       node.auxiliaryElements = auxiliaryElements;
     }
+    //
+    // Validate annotation element.
+    //
     if (node.parent is Annotation) {
       Annotation annotation = node.parent as Annotation;
       resolveAnnotationElement(annotation);
@@ -4654,10 +5657,12 @@
   Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     ClassElement enclosingClass = _resolver.enclosingClass;
     if (enclosingClass == null) {
+      // TODO(brianwilkerson) Report this error.
       return null;
     }
     InterfaceType superType = enclosingClass.supertype;
     if (superType == null) {
+      // TODO(brianwilkerson) Report this error.
       return null;
     }
     SimpleIdentifier name = node.constructorName;
@@ -4665,14 +5670,14 @@
     ConstructorElement element = superType.lookUpConstructor(superName, _definingLibrary);
     if (element == null) {
       if (name != null) {
-        _resolver.reportError6(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
+        _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
       } else {
-        _resolver.reportError6(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
+        _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
       }
       return null;
     } else {
       if (element.isFactory) {
-        _resolver.reportError6(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
+        _resolver.reportError7(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
       }
     }
     if (name != null) {
@@ -4689,7 +5694,7 @@
 
   Object visitSuperExpression(SuperExpression node) {
     if (!isSuperInValidContext(node)) {
-      _resolver.reportError6(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
+      _resolver.reportError7(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
     }
     return super.visitSuperExpression(node);
   }
@@ -4738,11 +5743,16 @@
    * @return the error code that should be reported
    */
   ErrorCode checkForInvocationError(Expression target, bool useStaticContext, Element element) {
+    // Prefix is not declared, instead "prefix.id" are declared.
     if (element is PrefixElement) {
       element = null;
     }
     if (element is PropertyAccessorElement) {
-      FunctionType getterType = (element as PropertyAccessorElement).type;
+      //
+      // This is really a function expression invocation.
+      //
+      // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
+      FunctionType getterType = element.type;
       if (getterType != null) {
         Type2 returnType = getterType.returnType;
         if (!isExecutableType(returnType)) {
@@ -4752,10 +5762,17 @@
     } else if (element is ExecutableElement) {
       return null;
     } else if (element == null && target is SuperExpression) {
+      // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes, this one, and
+      // a code that describes the situation where the method was found, but it was not
+      // accessible from the current library.
       return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD;
     } else {
+      //
+      // This is really a function expression invocation.
+      //
+      // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
       if (element is PropertyInducingElement) {
-        PropertyAccessorElement getter = (element as PropertyInducingElement).getter;
+        PropertyAccessorElement getter = element.getter;
         FunctionType getterType = getter.type;
         if (getterType != null) {
           Type2 returnType = getterType.returnType;
@@ -4764,7 +5781,7 @@
           }
         }
       } else if (element is VariableElement) {
-        Type2 variableType = (element as VariableElement).type;
+        Type2 variableType = element.type;
         if (!isExecutableType(variableType)) {
           return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
         }
@@ -4774,6 +5791,7 @@
           if (enclosingClass == null) {
             return CompileTimeErrorCode.UNDEFINED_FUNCTION;
           } else if (element == null) {
+            // Proxy-conditional warning, based on state of resolver.getEnclosingClass()
             return StaticTypeWarningCode.UNDEFINED_METHOD;
           } else {
             return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
@@ -4783,11 +5801,14 @@
           if (useStaticContext) {
             targetType = getStaticType(target);
           } else {
+            // Compute and use the propagated type, if it is null, then it may be the case that
+            // static type is some type, in which the static type should be used.
             targetType = target.bestType;
           }
           if (targetType == null) {
             return CompileTimeErrorCode.UNDEFINED_FUNCTION;
           } else if (!targetType.isDynamic && !targetType.isBottom) {
+            // Proxy-conditional warning, based on state of targetType.getElement()
             return StaticTypeWarningCode.UNDEFINED_METHOD;
           }
         }
@@ -4809,6 +5830,10 @@
   bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, String methodName, MethodElement staticMethod, MethodElement propagatedMethod, Type2 staticType, Type2 propagatedType) {
     bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod);
     bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+    //
+    // If we are about to generate the hint (propagated version of this warning), then check
+    // that the member is not in a subtype of the propagated type.
+    //
     if (shouldReportMissingMember_propagated) {
       if (memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
         shouldReportMissingMember_propagated = false;
@@ -4845,32 +5870,36 @@
    */
   List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentList, Element element) {
     if (element is PropertyAccessorElement) {
-      FunctionType getterType = (element as PropertyAccessorElement).type;
+      //
+      // This is an invocation of the call method defined on the value returned by the getter.
+      //
+      FunctionType getterType = element.type;
       if (getterType != null) {
         Type2 getterReturnType = getterType.returnType;
         if (getterReturnType is InterfaceType) {
-          MethodElement callMethod = (getterReturnType as InterfaceType).lookUpMethod(CALL_METHOD_NAME, _definingLibrary);
+          MethodElement callMethod = getterReturnType.lookUpMethod(CALL_METHOD_NAME, _definingLibrary);
           if (callMethod != null) {
             return resolveArgumentsToParameters(false, argumentList, callMethod);
           }
         } else if (getterReturnType is FunctionType) {
-          Element functionElement = (getterReturnType as FunctionType).element;
+          Element functionElement = getterReturnType.element;
           if (functionElement is ExecutableElement) {
-            return resolveArgumentsToParameters(false, argumentList, functionElement as ExecutableElement);
+            return resolveArgumentsToParameters(false, argumentList, functionElement);
           }
         }
       }
     } else if (element is ExecutableElement) {
-      return resolveArgumentsToParameters(false, argumentList, element as ExecutableElement);
+      return resolveArgumentsToParameters(false, argumentList, element);
     } else if (element is VariableElement) {
-      VariableElement variable = element as VariableElement;
+      VariableElement variable = element;
       Type2 type = _promoteManager.getStaticType(variable);
       if (type is FunctionType) {
-        FunctionType functionType = type as FunctionType;
+        FunctionType functionType = type;
         List<ParameterElement> parameters = functionType.parameters;
         return resolveArgumentsToParameters2(false, argumentList, parameters);
       } else if (type is InterfaceType) {
-        MethodElement callMethod = (type as InterfaceType).lookUpMethod(CALL_METHOD_NAME, _definingLibrary);
+        // "call" invocation
+        MethodElement callMethod = type.lookUpMethod(CALL_METHOD_NAME, _definingLibrary);
         if (callMethod != null) {
           List<ParameterElement> parameters = callMethod.parameters;
           return resolveArgumentsToParameters2(false, argumentList, parameters);
@@ -4888,8 +5917,9 @@
    * @return a non-setter element derived from the given element
    */
   Element convertSetterToGetter(Element element) {
+    // TODO(brianwilkerson) Determine whether and why the element could ever be a setter.
     if (element is PropertyAccessorElement) {
-      return (element as PropertyAccessorElement).variable.getter;
+      return element.variable.getter;
     }
     return element;
   }
@@ -4958,6 +5988,9 @@
   Type2 getPropagatedType(Expression expression) {
     Type2 propagatedType = resolveTypeParameter(expression.propagatedType);
     if (propagatedType is FunctionType) {
+      //
+      // All function types are subtypes of 'Function', which is itself a subclass of 'Object'.
+      //
       propagatedType = _resolver.typeProvider.functionType;
     }
     return propagatedType;
@@ -4975,6 +6008,9 @@
     }
     Type2 staticType = resolveTypeParameter(expression.staticType);
     if (staticType is FunctionType) {
+      //
+      // All function types are subtypes of 'Function', which is itself a subclass of 'Object'.
+      //
       staticType = _resolver.typeProvider.functionType;
     }
     return staticType;
@@ -4991,7 +6027,7 @@
     if (type.isDynamic || (type is FunctionType) || type.isDartCoreFunction || type.isObject) {
       return true;
     } else if (type is InterfaceType) {
-      ClassElement classElement = (type as InterfaceType).element;
+      ClassElement classElement = type.element;
       MethodElement methodElement = classElement.lookUpMethod(CALL_METHOD_NAME, _definingLibrary);
       return methodElement != null;
     }
@@ -5004,7 +6040,7 @@
   bool get isInConstConstructor {
     ExecutableElement function = _resolver.enclosingFunction;
     if (function is ConstructorElement) {
-      return (function as ConstructorElement).isConst;
+      return function.isConst;
     }
     return false;
   }
@@ -5017,9 +6053,9 @@
    */
   bool isStatic(Element element) {
     if (element is ExecutableElement) {
-      return (element as ExecutableElement).isStatic;
+      return element.isStatic;
     } else if (element is PropertyInducingElement) {
-      return (element as PropertyInducingElement).isStatic;
+      return element.isStatic;
     }
     return false;
   }
@@ -5037,11 +6073,11 @@
   bool isValidAsPrefix(SimpleIdentifier node) {
     ASTNode parent = node.parent;
     if (parent is ImportDirective) {
-      return identical((parent as ImportDirective).prefix, node);
+      return identical(parent.prefix, node);
     } else if (parent is PrefixedIdentifier) {
       return true;
     } else if (parent is MethodInvocation) {
-      return identical((parent as MethodInvocation).target, node);
+      return identical(parent.target, node);
     }
     return false;
   }
@@ -5058,7 +6094,7 @@
   PropertyAccessorElement lookUpGetter(Expression target, Type2 type, String getterName) {
     type = resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type as InterfaceType;
+      InterfaceType interfaceType = type;
       PropertyAccessorElement accessor;
       if (target is SuperExpression) {
         accessor = interfaceType.lookUpGetterInSuperclass(getterName, _definingLibrary);
@@ -5086,6 +6122,10 @@
    * @return the element representing the getter that was found
    */
   PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, bool includeTargetType, String getterName, Set<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
     ClassElement targetClass = targetType.element;
     if (visitedInterfaces.contains(targetClass)) {
       return null;
@@ -5128,7 +6168,7 @@
   ExecutableElement lookupGetterOrMethod(Type2 type, String memberName) {
     type = resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type as InterfaceType;
+      InterfaceType interfaceType = type;
       ExecutableElement member = interfaceType.lookUpMethod(memberName, _definingLibrary);
       if (member != null) {
         return member;
@@ -5155,6 +6195,10 @@
    * @return the element representing the method or getter that was found
    */
   ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, bool includeTargetType, String memberName, Set<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
     ClassElement targetClass = targetType.element;
     if (visitedInterfaces.contains(targetClass)) {
       return null;
@@ -5205,15 +6249,19 @@
         labelElement = labelScope.lookup2(LabelScope.EMPTY_LABEL) as LabelElementImpl;
         if (labelElement == null) {
         }
+        //
+        // The label element that was returned was a marker for look-up and isn't stored in the
+        // element model.
+        //
         labelElement = null;
       }
     } else {
       if (labelScope == null) {
-        _resolver.reportError6(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
+        _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
       } else {
         labelElement = labelScope.lookup(labelNode) as LabelElementImpl;
         if (labelElement == null) {
-          _resolver.reportError6(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
+          _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
         } else {
           labelNode.staticElement = labelElement;
         }
@@ -5222,7 +6270,7 @@
     if (labelElement != null) {
       ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElement);
       if (labelContainer != _resolver.enclosingFunction) {
-        _resolver.reportError6(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
+        _resolver.reportError7(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
         labelElement = null;
       }
     }
@@ -5241,7 +6289,7 @@
   MethodElement lookUpMethod(Expression target, Type2 type, String methodName) {
     type = resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type as InterfaceType;
+      InterfaceType interfaceType = type;
       MethodElement method;
       if (target is SuperExpression) {
         method = interfaceType.lookUpMethodInSuperclass(methodName, _definingLibrary);
@@ -5269,6 +6317,10 @@
    * @return the element representing the method that was found
    */
   MethodElement lookUpMethodInInterfaces(InterfaceType targetType, bool includeTargetType, String methodName, Set<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
     ClassElement targetClass = targetType.element;
     if (visitedInterfaces.contains(targetClass)) {
       return null;
@@ -5311,7 +6363,7 @@
   PropertyAccessorElement lookUpSetter(Expression target, Type2 type, String setterName) {
     type = resolveTypeParameter(type);
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type as InterfaceType;
+      InterfaceType interfaceType = type;
       PropertyAccessorElement accessor;
       if (target is SuperExpression) {
         accessor = interfaceType.lookUpSetterInSuperclass(setterName, _definingLibrary);
@@ -5339,6 +6391,10 @@
    * @return the element representing the setter that was found
    */
   PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, bool includeTargetType, String setterName, Set<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
     ClassElement targetClass = targetType.element;
     if (visitedInterfaces.contains(targetClass)) {
       return null;
@@ -5385,7 +6441,7 @@
   bool memberFoundInSubclass(Element element, String memberName, bool asMethod, bool asAccessor) {
     if (element is ClassElement) {
       _subtypeManager.ensureLibraryVisited(_definingLibrary);
-      Set<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(element as ClassElement);
+      Set<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(element);
       for (ClassElement subtypeElement in subtypeElements) {
         if (asMethod && subtypeElement.getMethod(memberName) != null) {
           return true;
@@ -5430,15 +6486,18 @@
       }
       break;
     }
+    // Internal error: Unmapped assignment operator.
     AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
     return operator;
   }
 
   void resolveAnnotationConstructorInvocationArguments(Annotation annotation, ConstructorElement constructor) {
     ArgumentList argumentList = annotation.arguments;
+    // error will be reported in ConstantVerifier
     if (argumentList == null) {
       return;
     }
+    // resolve arguments to parameters
     List<ParameterElement> parameters = resolveArgumentsToParameters(true, argumentList, constructor);
     if (parameters != null) {
       argumentList.correspondingStaticParameters = parameters;
@@ -5456,7 +6515,7 @@
     {
       Identifier annName = annotation.name;
       if (annName is PrefixedIdentifier) {
-        PrefixedIdentifier prefixed = annName as PrefixedIdentifier;
+        PrefixedIdentifier prefixed = annName;
         nameNode1 = prefixed.prefix;
         nameNode2 = prefixed.identifier;
       } else {
@@ -5466,45 +6525,62 @@
     }
     SimpleIdentifier nameNode3 = annotation.constructorName;
     ConstructorElement constructor = null;
+    //
+    // CONST or Class(args)
+    //
     if (nameNode1 != null && nameNode2 == null && nameNode3 == null) {
       Element element1 = nameNode1.staticElement;
+      // CONST
       if (element1 is PropertyAccessorElement) {
-        resolveAnnotationElementGetter(annotation, element1 as PropertyAccessorElement);
+        resolveAnnotationElementGetter(annotation, element1);
         return;
       }
+      // Class(args)
       if (element1 is ClassElement) {
-        ClassElement classElement = element1 as ClassElement;
+        ClassElement classElement = element1;
         constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(null, _definingLibrary);
       }
     }
+    //
+    // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args)
+    //
     if (nameNode1 != null && nameNode2 != null && nameNode3 == null) {
       Element element1 = nameNode1.staticElement;
       Element element2 = nameNode2.staticElement;
+      // Class.CONST - not resolved yet
       if (element1 is ClassElement) {
-        ClassElement classElement = element1 as ClassElement;
+        ClassElement classElement = element1;
         element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary);
       }
+      // prefix.CONST or Class.CONST
       if (element2 is PropertyAccessorElement) {
         nameNode2.staticElement = element2;
         annotation.element = element2;
         resolveAnnotationElementGetter(annotation, element2 as PropertyAccessorElement);
         return;
       }
+      // prefix.Class()
       if (element2 is ClassElement) {
         ClassElement classElement = element2 as ClassElement;
         constructor = classElement.unnamedConstructor;
       }
+      // Class.constructor(args)
       if (element1 is ClassElement) {
-        ClassElement classElement = element1 as ClassElement;
+        ClassElement classElement = element1;
         constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(nameNode2.name, _definingLibrary);
         nameNode2.staticElement = constructor;
       }
     }
+    //
+    // prefix.Class.CONST or prefix.Class.constructor(args)
+    //
     if (nameNode1 != null && nameNode2 != null && nameNode3 != null) {
       Element element2 = nameNode2.staticElement;
+      // element2 should be ClassElement
       if (element2 is ClassElement) {
-        ClassElement classElement = element2 as ClassElement;
+        ClassElement classElement = element2;
         String name3 = nameNode3.name;
+        // prefix.Class.CONST
         PropertyAccessorElement getter = classElement.lookUpGetter(name3, _definingLibrary);
         if (getter != null) {
           nameNode3.staticElement = getter;
@@ -5512,27 +6588,34 @@
           resolveAnnotationElementGetter(annotation, getter);
           return;
         }
+        // prefix.Class.constructor(args)
         constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(name3, _definingLibrary);
         nameNode3.staticElement = constructor;
       }
     }
+    // we need constructor
     if (constructor == null) {
-      _resolver.reportError6(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+      _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
       return;
     }
+    // record element
     annotation.element = constructor;
+    // resolve arguments
     resolveAnnotationConstructorInvocationArguments(annotation, constructor);
   }
 
   void resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorElement accessorElement) {
+    // accessor should be synthetic
     if (!accessorElement.isSynthetic) {
-      _resolver.reportError6(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+      _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
       return;
     }
+    // variable should be constant
     VariableElement variableElement = accessorElement.variable;
     if (!variableElement.isConst) {
-      _resolver.reportError6(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+      _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
     }
+    // OK
     return;
   }
 
@@ -5592,18 +6675,18 @@
     for (int i = 0; i < argumentCount; i++) {
       Expression argument = arguments[i];
       if (argument is NamedExpression) {
-        SimpleIdentifier nameNode = (argument as NamedExpression).name.label;
+        SimpleIdentifier nameNode = argument.name.label;
         String name = nameNode.name;
         ParameterElement element = namedParameters[name];
         if (element == null) {
           ErrorCode errorCode = (reportError ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER) as ErrorCode;
-          _resolver.reportError6(errorCode, nameNode, [name]);
+          _resolver.reportError7(errorCode, nameNode, [name]);
         } else {
           resolvedParameters[i] = element;
           nameNode.staticElement = element;
         }
         if (!usedNames.add(name)) {
-          _resolver.reportError6(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
+          _resolver.reportError7(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
         }
       } else {
         positionalArgumentCount++;
@@ -5614,10 +6697,10 @@
     }
     if (positionalArgumentCount < requiredParameters.length) {
       ErrorCode errorCode = (reportError ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS) as ErrorCode;
-      _resolver.reportError6(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
+      _resolver.reportError7(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
     } else if (positionalArgumentCount > unnamedParameterCount) {
       ErrorCode errorCode = (reportError ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS) as ErrorCode;
-      _resolver.reportError6(errorCode, argumentList, [unnamedParameterCount, positionalArgumentCount]);
+      _resolver.reportError7(errorCode, argumentList, [unnamedParameterCount, positionalArgumentCount]);
     }
     return resolvedParameters;
   }
@@ -5630,13 +6713,17 @@
    */
   void resolveCombinators(LibraryElement library, NodeList<Combinator> combinators) {
     if (library == null) {
+      //
+      // The library will be null if the directive containing the combinators has a URI that is not
+      // valid.
+      //
       return;
     }
     Namespace namespace = new NamespaceBuilder().createExportNamespace2(library);
     for (Combinator combinator in combinators) {
       NodeList<SimpleIdentifier> names;
       if (combinator is HideCombinator) {
-        names = (combinator as HideCombinator).hiddenNames;
+        names = combinator.hiddenNames;
       } else {
         names = (combinator as ShowCombinator).shownNames;
       }
@@ -5654,17 +6741,17 @@
    * in 'C'.
    *
    * @param classElement the class element
-   * @param memberName the member name
+   * @param nameNode the member name node
    */
-  Element resolveElement(ClassElementImpl classElement, String memberName) {
+  Element resolveElement(ClassElementImpl classElement, SimpleIdentifier nameNode) {
+    String name = nameNode.name;
     Element element = null;
-    String methodNameStr = memberName;
-    element = classElement.getMethod(methodNameStr);
-    if (element == null) {
-      element = classElement.getSetter(memberName);
-      if (element == null) {
-        element = classElement.getGetter(memberName);
-      }
+    element = classElement.getMethod(name);
+    if (element == null && nameNode.inSetterContext()) {
+      element = classElement.getSetter(name);
+    }
+    if (element == null && nameNode.inGetterContext()) {
+      element = classElement.getGetter(name);
     }
     if (element != null && element.isAccessibleIn(_definingLibrary)) {
       return element;
@@ -5685,23 +6772,33 @@
    */
   Element resolveInvokedElement(Expression target, Type2 targetType, SimpleIdentifier methodName) {
     if (targetType is InterfaceType) {
-      InterfaceType classType = targetType as InterfaceType;
+      InterfaceType classType = targetType;
       Element element = lookUpMethod(target, classType, methodName.name);
       if (element == null) {
+        //
+        // If there's no method, then it's possible that 'm' is a getter that returns a function.
+        //
         element = lookUpGetter(target, classType, methodName.name);
       }
       return element;
     } else if (target is SimpleIdentifier) {
-      Element targetElement = (target as SimpleIdentifier).staticElement;
+      Element targetElement = target.staticElement;
       if (targetElement is PrefixElement) {
-        String name = "${(target as SimpleIdentifier).name}.${methodName}";
+        //
+        // Look to see whether the name of the method is really part of a prefixed identifier for an
+        // imported top-level function or top-level getter that returns a function.
+        //
+        String name = "${target.name}.${methodName}";
         Identifier functionName = new ElementResolver_SyntheticIdentifier(name);
         Element element = _resolver.nameScope.lookup(functionName, _definingLibrary);
         if (element != null) {
+          // TODO(brianwilkerson) This isn't a method invocation, it's a function invocation where
+          // the function name is a prefixed identifier. Consider re-writing the AST.
           return element;
         }
       }
     }
+    // TODO(brianwilkerson) Report this error.
     return null;
   }
 
@@ -5715,17 +6812,28 @@
    * @return the element being invoked
    */
   Element resolveInvokedElement2(SimpleIdentifier methodName) {
+    //
+    // Look first in the lexical scope.
+    //
     Element element = _resolver.nameScope.lookup(methodName, _definingLibrary);
     if (element == null) {
+      //
+      // If it isn't defined in the lexical scope, and the invocation is within a class, then look
+      // in the inheritance scope.
+      //
       ClassElement enclosingClass = _resolver.enclosingClass;
       if (enclosingClass != null) {
         InterfaceType enclosingType = enclosingClass.type;
         element = lookUpMethod(null, enclosingType, methodName.name);
         if (element == null) {
+          //
+          // If there's no method, then it's possible that 'm' is a getter that returns a function.
+          //
           element = lookUpGetter(null, enclosingType, methodName.name);
         }
       }
     }
+    // TODO(brianwilkerson) Report this error.
     return element;
   }
 
@@ -5757,13 +6865,20 @@
     Type2 propagatedType = getPropagatedType(target);
     Element staticElement = null;
     Element propagatedElement = null;
+    //
+    // If this property access is of the form 'C.m' where 'C' is a class, then we don't call
+    // resolveProperty(..) which walks up the class hierarchy, instead we just look for the
+    // member in the type only.
+    //
     ClassElementImpl typeReference = getTypeReference(target);
     if (typeReference != null) {
-      staticElement = propagatedElement = resolveElement(typeReference, propertyName.name);
+      staticElement = propagatedElement = resolveElement(typeReference, propertyName);
     } else {
       staticElement = resolveProperty(target, staticType, propertyName);
       propagatedElement = resolveProperty(target, propagatedType, propertyName);
     }
+    // May be part of annotation, record property element only if exists.
+    // Error was already reported in validateAnnotationElement().
     if (target.parent.parent is Annotation) {
       if (staticElement != null) {
         propertyName.staticElement = staticElement;
@@ -5774,6 +6889,8 @@
     propertyName.propagatedElement = propagatedElement;
     bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticElement);
     bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints ? shouldReportMissingMember(propagatedType, propagatedElement) : false;
+    // If we are about to generate the hint (propagated version of this warning), then check
+    // that the member is not in a subtype of the propagated type.
     if (shouldReportMissingMember_propagated) {
       if (memberFoundInSubclass(propagatedType.element, propertyName.name, false, true)) {
         shouldReportMissingMember_propagated = false;
@@ -5781,33 +6898,35 @@
     }
     if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
       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(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
-              propertyName.name,
-              staticOrPropagatedEnclosingElt.displayName]);
+      if (staticOrPropagatedEnclosingElt != null) {
+        bool isStaticProperty = isStatic(staticOrPropagatedEnclosingElt);
+        if (propertyName.inSetterContext()) {
+          if (isStaticProperty) {
+            ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
+            _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
+                propertyName.name,
+                staticOrPropagatedEnclosingElt.displayName]);
+          } else {
+            ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
+            _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
+                propertyName.name,
+                staticOrPropagatedEnclosingElt.displayName]);
+          }
+        } else if (propertyName.inGetterContext()) {
+          if (isStaticProperty) {
+            ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
+            _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
+                propertyName.name,
+                staticOrPropagatedEnclosingElt.displayName]);
+          } else {
+            ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
+            _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
+                propertyName.name,
+                staticOrPropagatedEnclosingElt.displayName]);
+          }
         } else {
-          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
-              propertyName.name,
-              staticOrPropagatedEnclosingElt.displayName]);
+          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
         }
-      } else if (propertyName.inGetterContext()) {
-        if (isStaticProperty) {
-          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
-              propertyName.name,
-              staticOrPropagatedEnclosingElt.displayName]);
-        } else {
-          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
-              propertyName.name,
-              staticOrPropagatedEnclosingElt.displayName]);
-        }
-      } else {
-        _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
       }
     }
   }
@@ -5827,6 +6946,9 @@
       if (variable != null) {
         PropertyAccessorElement setter = variable.setter;
         if (setter == null) {
+          //
+          // Check to see whether there might be a locally defined getter and an inherited setter.
+          //
           ClassElement enclosingClass = _resolver.enclosingClass;
           if (enclosingClass != null) {
             setter = lookUpSetter(null, enclosingClass.type, node.name);
@@ -5865,7 +6987,7 @@
    */
   Type2 resolveTypeParameter(Type2 type) {
     if (type is TypeParameterType) {
-      Type2 bound = (type as TypeParameterType).element.bound;
+      Type2 bound = type.element.bound;
       if (bound == null) {
         return _resolver.typeProvider.objectType;
       }
@@ -6073,9 +7195,9 @@
    */
   Element getElement(ASTNode node) {
     if (node is Declaration) {
-      return (node as Declaration).element;
+      return node.element;
     } else if (node is CompilationUnit) {
-      return (node as CompilationUnit).element;
+      return node.element;
     }
     return null;
   }
@@ -6254,12 +7376,15 @@
     if (baseFunctionType == null) {
       return baseFunctionType;
     }
+    // First, generate the path from the defining type to the overridden member
     Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>();
     computeInheritancePath(inheritancePath, definingType, memberName);
     if (inheritancePath == null || inheritancePath.isEmpty) {
+      // TODO(jwren) log analysis engine error
       return baseFunctionType;
     }
     FunctionType functionTypeToReturn = baseFunctionType;
+    // loop backward through the list substituting as we go:
     while (!inheritancePath.isEmpty) {
       InterfaceType lastType = inheritancePath.removeLast();
       List<Type2> parameterTypes = lastType.element.type.typeArguments;
@@ -6292,6 +7417,7 @@
     if (supertype != null) {
       superclassElt = supertype.element;
     } else {
+      // classElt is Object
       _classLookup[classElt] = resultMap;
       return resultMap;
     }
@@ -6300,12 +7426,23 @@
         visitedClasses.add(classElt);
         resultMap = new MemberMap.con2(computeClassChainLookupMap(superclassElt, visitedClasses));
       } else {
+        // This case happens only when the superclass was previously visited and not in the lookup,
+        // meaning this is meant to shorten the compute for recursive cases.
         _classLookup[superclassElt] = resultMap;
         return resultMap;
       }
+      //
+      // Substitute the supertypes down the hierarchy
+      //
       substituteTypeParametersDownHierarchy(supertype, resultMap);
+      //
+      // Include the members from the superclass in the resultMap
+      //
       recordMapWithClassMembers(resultMap, supertype);
     }
+    //
+    // Include the members from the mixins in the resultMap
+    //
     List<InterfaceType> mixins = classElt.mixins;
     for (int i = mixins.length - 1; i >= 0; i--) {
       recordMapWithClassMembers(resultMap, mixins[i]);
@@ -6324,33 +7461,46 @@
    * @param memberName the name of the member that is being looked up the inheritance path
    */
   void computeInheritancePath(Queue<InterfaceType> chain, InterfaceType currentType, String memberName) {
+    // TODO (jwren) create a public version of this method which doesn't require the initial chain
+    // to be provided, then provided tests for this functionality in InheritanceManagerTest
     chain.add(currentType);
     ClassElement classElt = currentType.element;
     InterfaceType supertype = classElt.supertype;
+    // Base case- reached Object
     if (supertype == null) {
+      // Looked up the chain all the way to Object, return null.
+      // This should never happen.
       return;
     }
+    // If we are done, return the chain
+    // We are not done if this is the first recursive call on this method.
     if (chain.length != 1) {
+      // We are done however if the member is in this classElt
       if (lookupMemberInClass(classElt, memberName) != null) {
         return;
       }
     }
+    // Mixins- note that mixins call lookupMemberInClass, not lookupMember
     List<InterfaceType> mixins = classElt.mixins;
     for (int i = mixins.length - 1; i >= 0; i--) {
       ClassElement mixinElement = mixins[i].element;
       if (mixinElement != null) {
         ExecutableElement elt = lookupMemberInClass(mixinElement, memberName);
         if (elt != null) {
+          // this is equivalent (but faster than) calling this method recursively
+          // (return computeInheritancePath(chain, mixins[i], memberName);)
           chain.add(mixins[i]);
           return;
         }
       }
     }
+    // Superclass
     ClassElement superclassElt = supertype.element;
     if (lookupMember(superclassElt, memberName) != null) {
       computeInheritancePath(chain, supertype, memberName);
       return;
     }
+    // Interfaces
     List<InterfaceType> interfaces = classElt.interfaces;
     for (InterfaceType interfaceType in interfaces) {
       ClassElement interfaceElement = interfaceType.element;
@@ -6383,14 +7533,25 @@
     ClassElement superclassElement = supertype != null ? supertype.element : null;
     List<InterfaceType> mixins = classElt.mixins;
     List<InterfaceType> interfaces = classElt.interfaces;
+    // Recursively collect the list of mappings from all of the interface types
     List<MemberMap> lookupMaps = new List<MemberMap>();
+    // Superclass element
     if (superclassElement != null) {
       if (!visitedInterfaces.contains(superclassElement)) {
         try {
           visitedInterfaces.add(superclassElement);
+          //
+          // Recursively compute the map for the supertype.
+          //
           MemberMap map = computeInterfaceLookupMap(superclassElement, visitedInterfaces);
           map = new MemberMap.con2(map);
+          //
+          // Substitute the supertypes down the hierarchy
+          //
           substituteTypeParametersDownHierarchy(supertype, map);
+          //
+          // Add any members from the supertype into the map as well.
+          //
           recordMapWithClassMembers(map, supertype);
           lookupMaps.add(map);
         } finally {
@@ -6406,20 +7567,31 @@
         }
       }
     }
+    // Mixin elements
     for (InterfaceType mixinType in mixins) {
       MemberMap mapWithMixinMembers = new MemberMap();
       recordMapWithClassMembers(mapWithMixinMembers, mixinType);
       lookupMaps.add(mapWithMixinMembers);
     }
+    // Interface elements
     for (InterfaceType interfaceType in interfaces) {
       ClassElement interfaceElement = interfaceType.element;
       if (interfaceElement != null) {
         if (!visitedInterfaces.contains(interfaceElement)) {
           try {
             visitedInterfaces.add(interfaceElement);
+            //
+            // Recursively compute the map for the interfaces.
+            //
             MemberMap map = computeInterfaceLookupMap(interfaceElement, visitedInterfaces);
             map = new MemberMap.con2(map);
+            //
+            // Substitute the supertypes down the hierarchy
+            //
             substituteTypeParametersDownHierarchy(interfaceType, map);
+            //
+            // And add any members from the interface into the map as well.
+            //
             recordMapWithClassMembers(map, interfaceType);
             lookupMaps.add(map);
           } finally {
@@ -6440,6 +7612,9 @@
       _interfaceLookup[classElt] = resultMap;
       return resultMap;
     }
+    //
+    // Union all of the maps together, grouping the ExecutableElements into sets.
+    //
     Map<String, Set<ExecutableElement>> unionMap = new Map<String, Set<ExecutableElement>>();
     for (MemberMap lookupMap in lookupMaps) {
       for (int i = 0; i < lookupMap.size; i++) {
@@ -6455,6 +7630,9 @@
         set.add(lookupMap.getValue(i));
       }
     }
+    //
+    // Loop through the entries in the union map, adding them to the resultMap appropriately.
+    //
     for (MapEntry<String, Set<ExecutableElement>> entry in getMapEntrySet(unionMap)) {
       String key = entry.getKey();
       Set<ExecutableElement> set = entry.getValue();
@@ -6468,7 +7646,7 @@
         for (ExecutableElement executableElement in set) {
           if (executableElement is PropertyAccessorElement) {
             allMethods = false;
-            if ((executableElement as PropertyAccessorElement).isSetter) {
+            if (executableElement.isSetter) {
               allGetters = false;
             } else {
               allSetters = false;
@@ -6479,6 +7657,7 @@
           }
         }
         if (allMethods || allGetters || allSetters) {
+          // Compute the element whose type is the subtype of all of the other types.
           List<ExecutableElement> elements = new List.from(set);
           List<FunctionType> executableElementTypes = new List<FunctionType>(numOfEltsWithMatchingNames);
           for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
@@ -6978,19 +8157,28 @@
     List<Directive> directivesToResolve = new List<Directive>();
     List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<CompilationUnitElementImpl>();
     for (Directive directive in directives) {
+      //
+      // We do not build the elements representing the import and export directives at this point.
+      // That is not done until we get to LibraryResolver.buildDirectiveModels() because we need the
+      // LibraryElements for the referenced libraries, which might not exist at this point (due to
+      // the possibility of circular references).
+      //
       if (directive is LibraryDirective) {
         if (libraryNameNode == null) {
-          libraryNameNode = (directive as LibraryDirective).name;
+          libraryNameNode = directive.name;
           directivesToResolve.add(directive);
         }
       } else if (directive is PartDirective) {
-        PartDirective partDirective = directive as PartDirective;
+        PartDirective partDirective = directive;
         StringLiteral partUri = partDirective.uri;
         Source partSource = library.getSource(partDirective);
         if (partSource != null && partSource.exists()) {
           hasPartDirective = true;
           CompilationUnitElementImpl part = builder.buildCompilationUnit(partSource, library.getAST(partSource));
           part.uri = library.getUri(partDirective);
+          //
+          // Validate that the part contains a part-of directive with the same name as the library.
+          //
           String partLibraryName = getPartLibraryName(library, partSource, directivesToResolve);
           if (partLibraryName == null) {
             _errorListener.onError(new AnalysisError.con2(librarySource, partUri.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()]));
@@ -7009,6 +8197,9 @@
     if (hasPartDirective && libraryNameNode == null) {
       _errorListener.onError(new AnalysisError.con1(librarySource, ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, []));
     }
+    //
+    // Create and populate the library element.
+    //
     LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext, libraryNameNode);
     libraryElement.definingCompilationUnit = definingCompilationUnitElement;
     if (entryPoint != null) {
@@ -7080,7 +8271,7 @@
       for (Directive directive in partUnit.directives) {
         if (directive is PartOfDirective) {
           directivesToResolve.add(directive);
-          LibraryIdentifier libraryName = (directive as PartOfDirective).libraryName;
+          LibraryIdentifier libraryName = directive.libraryName;
           if (libraryName != null) {
             return libraryName.name;
           }
@@ -7202,14 +8393,35 @@
     try {
       instrumentation.metric("fullAnalysis", fullAnalysis);
       instrumentation.data3("fullName", librarySource.fullName);
+      //
+      // Create the objects representing the library being resolved and the core library.
+      //
       Library targetLibrary = createLibrary2(librarySource, modificationStamp, unit);
       _coreLibrary = _libraryMap[_coreLibrarySource];
       if (_coreLibrary == null) {
+        // This will be true unless the library being analyzed is the core library.
         _coreLibrary = createLibrary(_coreLibrarySource);
       }
       instrumentation.metric3("createLibrary", "complete");
+      //
+      // Compute the set of libraries that need to be resolved together.
+      //
       computeLibraryDependencies2(targetLibrary, unit);
       _librariesInCycles = computeLibrariesInCycles(targetLibrary);
+      //
+      // Build the element models representing the libraries being resolved. This is done in three
+      // steps:
+      //
+      // 1. Build the basic element models without making any connections between elements other than
+      //    the basic parent/child relationships. This includes building the elements representing the
+      //    libraries.
+      // 2. Build the elements for the import and export directives. This requires that we have the
+      //    elements built for the referenced libraries, but because of the possibility of circular
+      //    references needs to happen after all of the library elements have been created.
+      // 3. Build the rest of the type model by connecting superclasses, mixins, and interfaces. This
+      //    requires that we be able to compute the names visible in the libraries being resolved,
+      //    which in turn requires that we have resolved the import directives.
+      //
       buildElementModels();
       instrumentation.metric3("buildElementModels", "complete");
       LibraryElement coreElement = _coreLibrary.libraryElement;
@@ -7221,8 +8433,21 @@
       _typeProvider = new TypeProviderImpl(coreElement);
       buildTypeHierarchies();
       instrumentation.metric3("buildTypeHierarchies", "complete");
+      //
+      // Perform resolution and type analysis.
+      //
+      // TODO(brianwilkerson) Decide whether we want to resolve all of the libraries or whether we
+      // want to only resolve the target library. The advantage to resolving everything is that we
+      // have already done part of the work so we'll avoid duplicated effort. The disadvantage of
+      // resolving everything is that we might do extra work that we don't really care about. Another
+      // possibility is to add a parameter to this method and punt the decision to the clients.
+      //
+      //if (analyzeAll) {
       resolveReferencesAndTypes();
       instrumentation.metric3("resolveReferencesAndTypes", "complete");
+      //} else {
+      //  resolveReferencesAndTypes(targetLibrary);
+      //}
       performConstantEvaluation();
       instrumentation.metric3("performConstantEvaluation", "complete");
       return targetLibrary.libraryElement;
@@ -7249,17 +8474,38 @@
     try {
       instrumentation.metric("fullAnalysis", fullAnalysis);
       instrumentation.data3("fullName", librarySource.fullName);
+      //
+      // Create the objects representing the library being resolved and the core library.
+      //
       Library targetLibrary = createLibrary(librarySource);
       _coreLibrary = _libraryMap[_coreLibrarySource];
       if (_coreLibrary == null) {
+        // This will be true unless the library being analyzed is the core library.
         _coreLibrary = createLibraryOrNull(_coreLibrarySource);
         if (_coreLibrary == null) {
           throw new AnalysisException.con1("Core library does not exist");
         }
       }
       instrumentation.metric3("createLibrary", "complete");
+      //
+      // Compute the set of libraries that need to be resolved together.
+      //
       computeLibraryDependencies(targetLibrary);
       _librariesInCycles = computeLibrariesInCycles(targetLibrary);
+      //
+      // Build the element models representing the libraries being resolved. This is done in three
+      // steps:
+      //
+      // 1. Build the basic element models without making any connections between elements other than
+      //    the basic parent/child relationships. This includes building the elements representing the
+      //    libraries.
+      // 2. Build the elements for the import and export directives. This requires that we have the
+      //    elements built for the referenced libraries, but because of the possibility of circular
+      //    references needs to happen after all of the library elements have been created.
+      // 3. Build the rest of the type model by connecting superclasses, mixins, and interfaces. This
+      //    requires that we be able to compute the names visible in the libraries being resolved,
+      //    which in turn requires that we have resolved the import directives.
+      //
       buildElementModels();
       instrumentation.metric3("buildElementModels", "complete");
       LibraryElement coreElement = _coreLibrary.libraryElement;
@@ -7271,8 +8517,21 @@
       _typeProvider = new TypeProviderImpl(coreElement);
       buildTypeHierarchies();
       instrumentation.metric3("buildTypeHierarchies", "complete");
+      //
+      // Perform resolution and type analysis.
+      //
+      // TODO(brianwilkerson) Decide whether we want to resolve all of the libraries or whether we
+      // want to only resolve the target library. The advantage to resolving everything is that we
+      // have already done part of the work so we'll avoid duplicated effort. The disadvantage of
+      // resolving everything is that we might do extra work that we don't really care about. Another
+      // possibility is to add a parameter to this method and punt the decision to the clients.
+      //
+      //if (analyzeAll) {
       resolveReferencesAndTypes();
       instrumentation.metric3("resolveReferencesAndTypes", "complete");
+      //} else {
+      //  resolveReferencesAndTypes(targetLibrary);
+      //}
       performConstantEvaluation();
       instrumentation.metric3("performConstantEvaluation", "complete");
       instrumentation.metric2("librariesInCycles", _librariesInCycles.length);
@@ -7354,7 +8613,7 @@
     for (Combinator combinator in directive.combinators) {
       if (combinator is HideCombinator) {
         HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
-        hide.hiddenNames = getIdentifiers((combinator as HideCombinator).hiddenNames);
+        hide.hiddenNames = getIdentifiers(combinator.hiddenNames);
         combinators.add(hide);
       } else {
         ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
@@ -7381,13 +8640,13 @@
       List<ExportElement> exports = new List<ExportElement>();
       for (Directive directive in library.definingCompilationUnit.directives) {
         if (directive is ImportDirective) {
-          ImportDirective importDirective = directive as ImportDirective;
+          ImportDirective importDirective = directive;
           Source importedSource = library.getSource(importDirective);
           if (importedSource != null) {
+            // The imported source will be null if the URI in the import directive was invalid.
             Library importedLibrary = _libraryMap[importedSource];
             if (importedLibrary != null) {
-              ImportElementImpl importElement = new ImportElementImpl();
-              importElement.offset = directive.offset;
+              ImportElementImpl importElement = new ImportElementImpl(directive.offset);
               StringLiteral uriLiteral = importDirective.uri;
               if (uriLiteral != null) {
                 importElement.uriEnd = uriLiteral.end;
@@ -7398,7 +8657,7 @@
               if (importedLibraryElement != null) {
                 importElement.importedLibrary = importedLibraryElement;
               }
-              SimpleIdentifier prefixNode = (directive as ImportDirective).prefix;
+              SimpleIdentifier prefixNode = directive.prefix;
               if (prefixNode != null) {
                 importElement.prefixOffset = prefixNode.offset;
                 String prefixName = prefixNode.name;
@@ -7418,9 +8677,10 @@
             }
           }
         } else if (directive is ExportDirective) {
-          ExportDirective exportDirective = directive as ExportDirective;
+          ExportDirective exportDirective = directive;
           Source exportedSource = library.getSource(exportDirective);
           if (exportedSource != null) {
+            // The exported source will be null if the URI in the export directive was invalid.
             Library exportedLibrary = _libraryMap[exportedSource];
             if (exportedLibrary != null) {
               ExportElementImpl exportElement = new ExportElementImpl();
@@ -7442,7 +8702,7 @@
       }
       Source librarySource = library.librarySource;
       if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource) {
-        ImportElementImpl importElement = new ImportElementImpl();
+        ImportElementImpl importElement = new ImportElementImpl(-1);
         importElement.importedLibrary = _coreLibrary.libraryElement;
         importElement.synthetic = true;
         imports.add(importElement);
@@ -7543,12 +8803,12 @@
     Set<Source> importedSources = new Set<Source>();
     for (Directive directive in unit.directives) {
       if (directive is ExportDirective) {
-        Source exportSource = resolveSource(librarySource, directive as ExportDirective);
+        Source exportSource = resolveSource(librarySource, directive);
         if (exportSource != null) {
           exportedSources.add(exportSource);
         }
       } else if (directive is ImportDirective) {
-        Source importSource = resolveSource(librarySource, directive as ImportDirective);
+        Source importSource = resolveSource(librarySource, directive);
         if (importSource != null) {
           importedSources.add(importSource);
         }
@@ -7682,7 +8942,7 @@
   void performConstantEvaluation() {
     TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
     try {
-      ConstantValueComputer computer = new ConstantValueComputer();
+      ConstantValueComputer computer = new ConstantValueComputer(_typeProvider);
       for (Library library in _librariesInCycles) {
         for (Source source in library.compilationUnitSources) {
           try {
@@ -7737,6 +8997,16 @@
     } finally {
       timeCounter.stop();
     }
+    // Angular
+    timeCounter = PerformanceStatistics.angular.start();
+    try {
+      for (Source source in library.compilationUnitSources) {
+        CompilationUnit ast = library.getAST(source);
+        new AngularCompilationUnitBuilder(_errorListener, source).build(ast);
+      }
+    } finally {
+      timeCounter.stop();
+    }
   }
 
   /**
@@ -7861,12 +9131,14 @@
    * @param value the ExecutableElement value to store in the map
    */
   void put(String key, ExecutableElement value) {
+    // If we already have a value with this key, override the value
     for (int i = 0; i < _size; i++) {
       if (_keys[i] != null && _keys[i] == key) {
         _values[i] = value;
         return;
       }
     }
+    // If needed, double the size of our arrays and copy values over in both arrays
     if (_size == _keys.length) {
       int newArrayLength = _size * 2;
       List<String> keys_new_array = new List<String>(newArrayLength);
@@ -7880,6 +9152,7 @@
       _keys = keys_new_array;
       _values = values_new_array;
     }
+    // Put new value at end of array
     _keys[_size] = key;
     _values[_size] = value;
     _size++;
@@ -7937,7 +9210,7 @@
    * @param element the class being tested
    * @return `true` if the given element represents a class that has the proxy annotation
    */
-  static bool classHasProxyAnnotation(Element element) => (element is ClassElement) && (element as ClassElement).isProxy;
+  static bool classHasProxyAnnotation(Element element) => (element is ClassElement) && element.isProxy;
 
   /**
    * The enclosing [ClassElement], this is what will determine if the error code should, or
@@ -8004,6 +9277,12 @@
   ExecutableElement _enclosingFunction = null;
 
   /**
+   * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that
+   * cannot be resolved where we visited it, because it should be resolved in the scope of the body.
+   */
+  Comment _commentBeforeFunction = null;
+
+  /**
    * The object keeping track of which elements have had their types overridden.
    */
   TypeOverrideManager _overrideManager = new TypeOverrideManager();
@@ -8102,10 +9381,12 @@
           _overrideManager.enterScope();
           _promoteManager.enterScope();
           propagateTrueState(leftOperand);
+          // Type promotion.
           promoteTypes(leftOperand);
           clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
           clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
           clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(rightOperand);
+          // Visit right operand.
           rightOperand.accept(this);
         } finally {
           _overrideManager.exitScope();
@@ -8133,6 +9414,7 @@
   }
 
   Object visitBlockFunctionBody(BlockFunctionBody node) {
+    safelyVisit(_commentBeforeFunction);
     try {
       _overrideManager.enterScope();
       super.visitBlockFunctionBody(node);
@@ -8143,6 +9425,9 @@
   }
 
   Object visitBreakStatement(BreakStatement node) {
+    //
+    // We do not visit the label because it needs to be visited in the context of the statement.
+    //
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
@@ -8161,13 +9446,36 @@
     return null;
   }
 
+  Object visitComment(Comment node) {
+    if (node.parent is FunctionDeclaration || node.parent is ConstructorDeclaration || node.parent is MethodDeclaration) {
+      if (node != _commentBeforeFunction) {
+        _commentBeforeFunction = node;
+        return null;
+      }
+    }
+    super.visitComment(node);
+    _commentBeforeFunction = null;
+    return null;
+  }
+
   Object visitCommentReference(CommentReference node) {
+    //
+    // We do not visit the identifier because it needs to be visited in the context of the reference.
+    //
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
   }
 
   Object visitCompilationUnit(CompilationUnit node) {
+    //
+    // TODO(brianwilkerson) The goal of the code below is to visit the declarations in such an
+    // order that we can infer type information for top-level variables before we visit references
+    // to them. This is better than making no effort, but still doesn't completely satisfy that
+    // goal (consider for example "final var a = b; final var b = 0;"; we'll infer a type of 'int'
+    // for 'b', but not for 'a' because of the order of the visits). Ideally we would create a
+    // dependency graph, but that would require references to be resolved, which they are not.
+    //
     try {
       _overrideManager.enterScope();
       NodeList<Directive> directives = node.directives;
@@ -8206,9 +9514,11 @@
         _overrideManager.enterScope();
         _promoteManager.enterScope();
         propagateTrueState(condition);
+        // Type promotion.
         promoteTypes(condition);
         clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
         clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenExpression);
+        // Visit "then" expression.
         thenExpression.accept(this);
       } finally {
         _overrideManager.exitScope();
@@ -8251,6 +9561,10 @@
   }
 
   Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    //
+    // We visit the expression, but do not visit the field name because it needs to be visited in
+    // the context of the constructor field initializer node.
+    //
     safelyVisit(node.expression);
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
@@ -8258,12 +9572,19 @@
   }
 
   Object visitConstructorName(ConstructorName node) {
+    //
+    // We do not visit either the type name, because it won't be visited anyway, or the name,
+    // because it needs to be visited in the context of the constructor name.
+    //
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
   }
 
   Object visitContinueStatement(ContinueStatement node) {
+    //
+    // We do not visit the label because it needs to be visited in the context of the statement.
+    //
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
@@ -8276,10 +9597,18 @@
     } finally {
       _overrideManager.exitScope();
     }
+    // TODO(brianwilkerson) If the loop can only be exited because the condition is false, then
+    // propagateFalseState(node.getCondition());
     return null;
   }
 
+  Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+    safelyVisit(_commentBeforeFunction);
+    return super.visitEmptyFunctionBody(node);
+  }
+
   Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    safelyVisit(_commentBeforeFunction);
     try {
       _overrideManager.enterScope();
       super.visitExpressionFunctionBody(node);
@@ -8367,9 +9696,11 @@
         _overrideManager.enterScope();
         _promoteManager.enterScope();
         propagateTrueState(condition);
+        // Type promotion.
         promoteTypes(condition);
         clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
         clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStatement);
+        // Visit "then".
         visitStatementInScope(thenStatement);
       } finally {
         thenOverrides = _overrideManager.captureLocalOverrides();
@@ -8423,6 +9754,10 @@
   }
 
   Object visitMethodInvocation(MethodInvocation node) {
+    //
+    // We visit the target and argument list, but do not visit the method name because it needs to
+    // be visited in the context of the invocation.
+    //
     safelyVisit(node.target);
     node.accept(_elementResolver);
     inferFunctionExpressionsParametersTypes(node.argumentList);
@@ -8439,6 +9774,10 @@
   }
 
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    //
+    // We visit the prefix, but do not visit the identifier because it needs to be visited in the
+    // context of the prefix.
+    //
     safelyVisit(node.prefix);
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
@@ -8446,6 +9785,10 @@
   }
 
   Object visitPropertyAccess(PropertyAccess node) {
+    //
+    // We visit the target, but do not visit the property name because it needs to be visited in the
+    // context of the property access node.
+    //
     safelyVisit(node.target);
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
@@ -8453,6 +9796,10 @@
   }
 
   Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    //
+    // We visit the argument list, but do not visit the optional identifier because it needs to be
+    // visited in the context of the constructor invocation.
+    //
     safelyVisit(node.argumentList);
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
@@ -8462,6 +9809,10 @@
   Object visitShowCombinator(ShowCombinator node) => null;
 
   Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    //
+    // We visit the argument list, but do not visit the optional identifier because it needs to be
+    // visited in the context of the constructor invocation.
+    //
     safelyVisit(node.argumentList);
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
@@ -8515,6 +9866,8 @@
         _overrideManager.exitScope();
       }
     }
+    // TODO(brianwilkerson) If the loop can only be exited because the condition is false, then
+    // propagateFalseState(condition);
     node.accept(_elementResolver);
     node.accept(_typeAnalyzer);
     return null;
@@ -8546,11 +9899,11 @@
   VariableElement getOverridablePropagatedElement(Expression expression) {
     Element element = null;
     if (expression is SimpleIdentifier) {
-      element = (expression as SimpleIdentifier).propagatedElement;
+      element = expression.propagatedElement;
     } else if (expression is PrefixedIdentifier) {
-      element = (expression as PrefixedIdentifier).propagatedElement;
+      element = expression.propagatedElement;
     } else if (expression is PropertyAccess) {
-      element = (expression as PropertyAccess).propertyName.propagatedElement;
+      element = expression.propertyName.propagatedElement;
     }
     if (element is VariableElement) {
       return element as VariableElement;
@@ -8568,11 +9921,11 @@
   VariableElement getOverridableStaticElement(Expression expression) {
     Element element = null;
     if (expression is SimpleIdentifier) {
-      element = (expression as SimpleIdentifier).staticElement;
+      element = expression.staticElement;
     } else if (expression is PrefixedIdentifier) {
-      element = (expression as PrefixedIdentifier).staticElement;
+      element = expression.staticElement;
     } else if (expression is PropertyAccess) {
-      element = (expression as PropertyAccess).propertyName.staticElement;
+      element = expression.propertyName.staticElement;
     }
     if (element is VariableElement) {
       return element as VariableElement;
@@ -8642,7 +9995,7 @@
       return;
     }
     if (element is PropertyInducingElement) {
-      PropertyInducingElement variable = element as PropertyInducingElement;
+      PropertyInducingElement variable = element;
       if (!variable.isConst && !variable.isFinal) {
         return;
       }
@@ -8691,6 +10044,10 @@
   }
 
   void visitForEachStatementInScope(ForEachStatement node) {
+    //
+    // We visit the iterator before the loop variable because the loop variable cannot be in scope
+    // while visiting the iterator.
+    //
     Expression iterator = node.iterator;
     safelyVisit(iterator);
     DeclaredIdentifier loopVariable = node.loopVariable;
@@ -8712,7 +10069,7 @@
           Element identifierElement = identifier.staticElement;
           if (identifierElement is VariableElement) {
             Type2 iteratorElementType = getIteratorElementType(iterator);
-            override2(identifierElement as VariableElement, iteratorElementType);
+            override2(identifierElement, iteratorElementType);
             recordPropagatedType(identifier, iteratorElementType);
           }
         }
@@ -8781,9 +10138,9 @@
     Type2 bestType = _overrideManager.getType(element);
     if (bestType == null) {
       if (element is LocalVariableElement) {
-        bestType = (element as LocalVariableElement).type;
+        bestType = element.type;
       } else if (element is ParameterElement) {
-        bestType = (element as ParameterElement).type;
+        bestType = element.type;
       }
     }
     return bestType;
@@ -8800,16 +10157,18 @@
   Type2 getIteratorElementType(Expression iteratorExpression) {
     Type2 expressionType = iteratorExpression.staticType;
     if (expressionType is InterfaceType) {
-      InterfaceType interfaceType = expressionType as InterfaceType;
+      InterfaceType interfaceType = expressionType;
       FunctionType iteratorFunction = _inheritanceManager.lookupMemberType(interfaceType, "iterator");
       if (iteratorFunction == null) {
+        // TODO(brianwilkerson) Should we report this error?
         return null;
       }
       Type2 iteratorType = iteratorFunction.returnType;
       if (iteratorType is InterfaceType) {
-        InterfaceType iteratorInterfaceType = iteratorType as InterfaceType;
+        InterfaceType iteratorInterfaceType = iteratorType;
         FunctionType currentFunction = _inheritanceManager.lookupMemberType(iteratorInterfaceType, "current");
         if (currentFunction == null) {
+          // TODO(brianwilkerson) Should we report this error?
           return null;
         }
         return currentFunction.returnType;
@@ -8823,21 +10182,26 @@
    * required type is [FunctionType], then infer parameters types from [FunctionType].
    */
   void inferFunctionExpressionParametersTypes(Expression mayBeClosure, Type2 mayByFunctionType) {
+    // prepare closure
     if (mayBeClosure is! FunctionExpression) {
       return;
     }
     FunctionExpression closure = mayBeClosure as FunctionExpression;
+    // prepare expected closure type
     if (mayByFunctionType is! FunctionType) {
       return;
     }
     FunctionType expectedClosureType = mayByFunctionType as FunctionType;
+    // set propagated type for the closure
     closure.propagatedType = expectedClosureType;
+    // set inferred types for parameters
     NodeList<FormalParameter> parameters = closure.parameters.parameters;
     List<ParameterElement> expectedParameters = expectedClosureType.parameters;
     for (int i = 0; i < parameters.length && i < expectedParameters.length; i++) {
       FormalParameter parameter = parameters[i];
       ParameterElement element = parameter.element;
       Type2 currentType = getBestType(element);
+      // may be override the type
       Type2 expectedType = expectedParameters[i].type;
       if (currentType == null || expectedType.isMoreSpecificThan(currentType)) {
         _overrideManager.setType(element, expectedType);
@@ -8868,6 +10232,9 @@
    * @return `true` if the given expression terminates abruptly
    */
   bool isAbruptTermination(Expression expression) {
+    // TODO(brianwilkerson) This needs to be significantly improved. Ideally we would eventually
+    // turn this into a method on Expression that returns a termination indication (normal, abrupt
+    // with no exception, abrupt with an exception).
     while (expression is ParenthesizedExpression) {
       expression = (expression as ParenthesizedExpression).expression;
     }
@@ -8882,12 +10249,15 @@
    * @return `true` if the given statement terminates abruptly
    */
   bool isAbruptTermination2(Statement statement) {
+    // TODO(brianwilkerson) This needs to be significantly improved. Ideally we would eventually
+    // turn this into a method on Statement that returns a termination indication (normal, abrupt
+    // with no exception, abrupt with an exception).
     if (statement is ReturnStatement || statement is BreakStatement || statement is ContinueStatement) {
       return true;
     } else if (statement is ExpressionStatement) {
-      return isAbruptTermination((statement as ExpressionStatement).expression);
+      return isAbruptTermination(statement.expression);
     } else if (statement is Block) {
-      NodeList<Statement> statements = (statement as Block).statements;
+      NodeList<Statement> statements = statement.statements;
       int size = statements.length;
       if (size == 0) {
         return false;
@@ -8908,7 +10278,7 @@
    */
   bool isVariableAccessedInClosure(Element variable, ASTNode target) {
     List<bool> result = [false];
-    target.accept(new RecursiveASTVisitor_8(result, variable));
+    target.accept(new RecursiveASTVisitor_ResolverVisitor_isVariableAccessedInClosure(result, variable));
     return result[0];
   }
 
@@ -8922,7 +10292,7 @@
    */
   bool isVariablePotentiallyMutatedIn(Element variable, ASTNode target) {
     List<bool> result = [false];
-    target.accept(new RecursiveASTVisitor_9(result, variable));
+    target.accept(new RecursiveASTVisitor_ResolverVisitor_isVariablePotentiallyMutatedIn(result, variable));
     return result[0];
   }
 
@@ -8938,22 +10308,28 @@
   void promote(Expression expression, Type2 potentialType) {
     VariableElement element = getPromotionStaticElement(expression);
     if (element != null) {
+      // may be mutated somewhere in closure
       if ((element as VariableElementImpl).isPotentiallyMutatedInClosure) {
         return;
       }
+      // prepare current variable type
       Type2 type = _promoteManager.getType(element);
       if (type == null) {
         type = expression.staticType;
       }
+      // Declared type should not be "dynamic".
       if (type == null || type.isDynamic) {
         return;
       }
+      // Promoted type should not be "dynamic".
       if (potentialType == null || potentialType.isDynamic) {
         return;
       }
+      // Promoted type should be more specific than declared.
       if (!potentialType.isMoreSpecificThan(type)) {
         return;
       }
+      // Do promote type of variable.
       _promoteManager.setType(element, potentialType);
     }
   }
@@ -8963,7 +10339,7 @@
    */
   void promoteTypes(Expression condition) {
     if (condition is BinaryExpression) {
-      BinaryExpression binary = condition as BinaryExpression;
+      BinaryExpression binary = condition;
       if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) {
         Expression left = binary.leftOperand;
         Expression right = binary.rightOperand;
@@ -8972,12 +10348,12 @@
         clearTypePromotionsIfPotentiallyMutatedIn(right);
       }
     } else if (condition is IsExpression) {
-      IsExpression is2 = condition as IsExpression;
+      IsExpression is2 = condition;
       if (is2.notOperator == null) {
         promote(is2.expression, is2.type.type);
       }
     } else if (condition is ParenthesizedExpression) {
-      promoteTypes((condition as ParenthesizedExpression).expression);
+      promoteTypes(condition.expression);
     }
   }
 
@@ -8989,23 +10365,23 @@
    */
   void propagateFalseState(Expression condition) {
     if (condition is BinaryExpression) {
-      BinaryExpression binary = condition as BinaryExpression;
+      BinaryExpression binary = condition;
       if (identical(binary.operator.type, sc.TokenType.BAR_BAR)) {
         propagateFalseState(binary.leftOperand);
         propagateFalseState(binary.rightOperand);
       }
     } else if (condition is IsExpression) {
-      IsExpression is2 = condition as IsExpression;
+      IsExpression is2 = condition;
       if (is2.notOperator != null) {
         override(is2.expression, is2.type.type);
       }
     } else if (condition is PrefixExpression) {
-      PrefixExpression prefix = condition as PrefixExpression;
+      PrefixExpression prefix = condition;
       if (identical(prefix.operator.type, sc.TokenType.BANG)) {
         propagateTrueState(prefix.operand);
       }
     } else if (condition is ParenthesizedExpression) {
-      propagateFalseState((condition as ParenthesizedExpression).expression);
+      propagateFalseState(condition.expression);
     }
   }
 
@@ -9026,23 +10402,23 @@
    */
   void propagateTrueState(Expression condition) {
     if (condition is BinaryExpression) {
-      BinaryExpression binary = condition as BinaryExpression;
+      BinaryExpression binary = condition;
       if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) {
         propagateTrueState(binary.leftOperand);
         propagateTrueState(binary.rightOperand);
       }
     } else if (condition is IsExpression) {
-      IsExpression is2 = condition as IsExpression;
+      IsExpression is2 = condition;
       if (is2.notOperator == null) {
         override(is2.expression, is2.type.type);
       }
     } else if (condition is PrefixExpression) {
-      PrefixExpression prefix = condition as PrefixExpression;
+      PrefixExpression prefix = condition;
       if (identical(prefix.operator.type, sc.TokenType.BANG)) {
         propagateFalseState(prefix.operand);
       }
     } else if (condition is ParenthesizedExpression) {
-      propagateTrueState((condition as ParenthesizedExpression).expression);
+      propagateTrueState(condition.expression);
     }
   }
 
@@ -9079,12 +10455,12 @@
   set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v;
 }
 
-class RecursiveASTVisitor_8 extends RecursiveASTVisitor<Object> {
+class RecursiveASTVisitor_ResolverVisitor_isVariableAccessedInClosure extends RecursiveASTVisitor<Object> {
   List<bool> result;
 
   Element variable;
 
-  RecursiveASTVisitor_8(this.result, this.variable) : super();
+  RecursiveASTVisitor_ResolverVisitor_isVariableAccessedInClosure(this.result, this.variable) : super();
 
   bool _inClosure = false;
 
@@ -9109,12 +10485,12 @@
   }
 }
 
-class RecursiveASTVisitor_9 extends RecursiveASTVisitor<Object> {
+class RecursiveASTVisitor_ResolverVisitor_isVariablePotentiallyMutatedIn extends RecursiveASTVisitor<Object> {
   List<bool> result;
 
   Element variable;
 
-  RecursiveASTVisitor_9(this.result, this.variable) : super();
+  RecursiveASTVisitor_ResolverVisitor_isVariablePotentiallyMutatedIn(this.result, this.variable) : super();
 
   Object visitSimpleIdentifier(SimpleIdentifier node) {
     if (result[0]) {
@@ -9222,6 +10598,24 @@
   LibraryElement get definingLibrary => _definingLibrary;
 
   /**
+   * Replaces the current [Scope] with the enclosing [Scope].
+   */
+  void popNameScope() {
+    _nameScope = _nameScope.enclosingScope;
+  }
+
+  /**
+   * Pushes a new [Scope] into the visitor.
+   *
+   * @return the new [Scope].
+   */
+  Scope pushNameScope() {
+    Scope newScope = new EnclosedScope(_nameScope);
+    _nameScope = newScope;
+    return newScope;
+  }
+
+  /**
    * Report an error with the given analysis error.
    *
    * @param errorCode analysis error
@@ -9334,6 +10728,7 @@
 
   Object visitFormalParameterList(FormalParameterList node) {
     super.visitFormalParameterList(node);
+    // We finished resolving function signature, now include formal parameters scope.
     if (_nameScope is FunctionScope) {
       (_nameScope as FunctionScope).defineParameters();
     }
@@ -9374,6 +10769,7 @@
 
   Object visitFunctionExpression(FunctionExpression node) {
     if (node.parent is FunctionDeclaration) {
+      // We have already created a function scope and don't need to do so again.
       super.visitFunctionExpression(node);
     } else {
       Scope outerScope = _nameScope;
@@ -9515,7 +10911,7 @@
    * @param node the node specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError6(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
+  void reportError7(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(source, node.offset, node.length, errorCode, arguments));
   }
 
@@ -9527,7 +10923,7 @@
    * @param length the length of the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError7(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
+  void reportError8(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(source, offset, length, errorCode, arguments));
   }
 
@@ -9538,7 +10934,7 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportError8(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
+  void reportError9(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
     _errorListener.onError(new AnalysisError.con2(source, token.offset, token.length, errorCode, arguments));
   }
 
@@ -9561,6 +10957,10 @@
    * @param node the statement to be visited
    */
   void visitForEachStatementInScope(ForEachStatement node) {
+    //
+    // We visit the iterator before the loop variable because the loop variable cannot be in scope
+    // while visiting the iterator.
+    //
     safelyVisit(node.identifier);
     safelyVisit(node.iterator);
     safelyVisit(node.loopVariable);
@@ -9590,7 +10990,8 @@
    */
   void visitStatementInScope(Statement node) {
     if (node is Block) {
-      visitBlock(node as Block);
+      // Don't create a scope around a block because the block will create it's own scope.
+      visitBlock(node);
     } else if (node != null) {
       Scope outerNameScope = _nameScope;
       try {
@@ -9630,14 +11031,14 @@
     for (int i = 0; i < statementCount; i++) {
       Statement statement = statements[i];
       if (statement is VariableDeclarationStatement) {
-        VariableDeclarationStatement vds = statement as VariableDeclarationStatement;
+        VariableDeclarationStatement vds = statement;
         NodeList<VariableDeclaration> variables = vds.variables.variables;
         int variableCount = variables.length;
         for (int j = 0; j < variableCount; j++) {
           scope.hide(variables[j].element);
         }
       } else if (statement is FunctionDeclarationStatement) {
-        FunctionDeclarationStatement fds = statement as FunctionDeclarationStatement;
+        FunctionDeclarationStatement fds = statement;
         scope.hide(fds.functionDeclaration.element);
       }
     }
@@ -9974,9 +11375,11 @@
     Type2 staticThenType = getStaticType(node.thenExpression);
     Type2 staticElseType = getStaticType(node.elseExpression);
     if (staticThenType == null) {
+      // TODO(brianwilkerson) Determine whether this can still happen.
       staticThenType = _dynamicType;
     }
     if (staticElseType == null) {
+      // TODO(brianwilkerson) Determine whether this can still happen.
       staticElseType = _dynamicType;
     }
     Type2 staticType = staticThenType.getLeastUpperBound(staticElseType);
@@ -10051,6 +11454,7 @@
    */
   Object visitFunctionExpression(FunctionExpression node) {
     if (node.parent is FunctionDeclaration) {
+      // The function type will be resolved and set when we visit the parent node.
       return null;
     }
     ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
@@ -10074,18 +11478,22 @@
    */
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     ExecutableElement staticMethodElement = node.staticElement;
+    // Record static return type of the static element.
     Type2 staticStaticType = computeStaticReturnType(staticMethodElement);
     recordStaticType(node, staticStaticType);
+    // Record propagated return type of the static element.
     Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement);
     if (staticPropagatedType != null && (staticStaticType == null || staticPropagatedType.isMoreSpecificThan(staticStaticType))) {
       recordPropagatedType2(node, staticPropagatedType);
     }
     ExecutableElement propagatedMethodElement = node.propagatedElement;
     if (propagatedMethodElement != staticMethodElement) {
+      // Record static return type of the propagated element.
       Type2 propagatedStaticType = computeStaticReturnType(propagatedMethodElement);
       if (propagatedStaticType != null && (staticStaticType == null || propagatedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) {
         recordPropagatedType2(node, propagatedStaticType);
       }
+      // Record propagated return type of the propagated element.
       Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedMethodElement);
       if (propagatedPropagatedType != null && (staticStaticType == null || propagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan(propagatedStaticType))) {
         recordPropagatedType2(node, propagatedPropagatedType);
@@ -10335,8 +11743,9 @@
   Object visitMethodInvocation(MethodInvocation node) {
     SimpleIdentifier methodNameNode = node.methodName;
     Element staticMethodElement = methodNameNode.staticElement;
+    // Record types of the local variable invoked as a function.
     if (staticMethodElement is LocalVariableElement) {
-      LocalVariableElement variable = staticMethodElement as LocalVariableElement;
+      LocalVariableElement variable = staticMethodElement;
       Type2 staticType = variable.type;
       recordStaticType(methodNameNode, staticType);
       Type2 propagatedType = _overrideManager.getType(variable);
@@ -10344,24 +11753,31 @@
         recordPropagatedType2(methodNameNode, propagatedType);
       }
     }
+    // Record static return type of the static element.
     Type2 staticStaticType = computeStaticReturnType(staticMethodElement);
     recordStaticType(node, staticStaticType);
+    // Record propagated return type of the static element.
     Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement);
     if (staticPropagatedType != null && (staticStaticType == null || staticPropagatedType.isMoreSpecificThan(staticStaticType))) {
       recordPropagatedType2(node, staticPropagatedType);
     }
     String methodName = methodNameNode.name;
+    // Future.then(closure) return type is:
+    // 1) the returned Future type, if the closure returns a Future;
+    // 2) Future<valueType>, if the closure returns a value.
     if (methodName == "then") {
       Expression target = node.realTarget;
       Type2 targetType = target == null ? null : target.bestType;
       if (isAsyncFutureType(targetType)) {
         NodeList<Expression> arguments = node.argumentList.arguments;
         if (arguments.length == 1) {
+          // TODO(brianwilkerson) Handle the case where both arguments are provided.
           Expression closureArg = arguments[0];
           if (closureArg is FunctionExpression) {
-            FunctionExpression closureExpr = closureArg as FunctionExpression;
+            FunctionExpression closureExpr = closureArg;
             Type2 returnType = computePropagatedReturnType(closureExpr.element);
             if (returnType != null) {
+              // prepare the type of the returned Future
               InterfaceTypeImpl newFutureType;
               if (isAsyncFutureType(returnType)) {
                 newFutureType = returnType as InterfaceTypeImpl;
@@ -10370,6 +11786,7 @@
                 newFutureType = new InterfaceTypeImpl.con1(futureType.element);
                 newFutureType.typeArguments = <Type2> [returnType];
               }
+              // set the 'then' invocation type
               recordPropagatedType2(node, newFutureType);
               return null;
             }
@@ -10436,10 +11853,12 @@
     } else {
       Element propagatedElement = methodNameNode.propagatedElement;
       if (propagatedElement != staticMethodElement) {
+        // Record static return type of the propagated element.
         Type2 propagatedStaticType = computeStaticReturnType(propagatedElement);
         if (propagatedStaticType != null && (staticStaticType == null || propagatedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) {
           recordPropagatedType2(node, propagatedStaticType);
         }
+        // Record propagated return type of the propagated element.
         Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedElement);
         if (propagatedPropagatedType != null && (staticStaticType == null || propagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan(propagatedStaticType))) {
           recordPropagatedType2(node, propagatedPropagatedType);
@@ -10522,26 +11941,26 @@
     Type2 staticType = _dynamicType;
     if (staticElement is ClassElement) {
       if (isNotTypeLiteral(node)) {
-        staticType = (staticElement as ClassElement).type;
+        staticType = staticElement.type;
       } else {
         staticType = _typeProvider.typeType;
       }
     } else if (staticElement is FunctionTypeAliasElement) {
       if (isNotTypeLiteral(node)) {
-        staticType = (staticElement as FunctionTypeAliasElement).type;
+        staticType = staticElement.type;
       } else {
         staticType = _typeProvider.typeType;
       }
     } else if (staticElement is MethodElement) {
-      staticType = (staticElement as MethodElement).type;
+      staticType = staticElement.type;
     } else if (staticElement is PropertyAccessorElement) {
-      staticType = getType(staticElement as PropertyAccessorElement, node.prefix.staticType);
+      staticType = getType(staticElement, node.prefix.staticType);
     } else if (staticElement is ExecutableElement) {
-      staticType = (staticElement as ExecutableElement).type;
+      staticType = staticElement.type;
     } else if (staticElement is TypeParameterElement) {
-      staticType = (staticElement as TypeParameterElement).type;
+      staticType = staticElement.type;
     } else if (staticElement is VariableElement) {
-      staticType = (staticElement as VariableElement).type;
+      staticType = staticElement.type;
     }
     recordStaticType(prefixedIdentifier, staticType);
     recordStaticType(node, staticType);
@@ -10549,22 +11968,22 @@
     Type2 propagatedType = null;
     if (propagatedElement is ClassElement) {
       if (isNotTypeLiteral(node)) {
-        propagatedType = (propagatedElement as ClassElement).type;
+        propagatedType = propagatedElement.type;
       } else {
         propagatedType = _typeProvider.typeType;
       }
     } else if (propagatedElement is FunctionTypeAliasElement) {
-      propagatedType = (propagatedElement as FunctionTypeAliasElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is MethodElement) {
-      propagatedType = (propagatedElement as MethodElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is PropertyAccessorElement) {
-      propagatedType = getType(propagatedElement as PropertyAccessorElement, node.prefix.staticType);
+      propagatedType = getType(propagatedElement, node.prefix.staticType);
     } else if (propagatedElement is ExecutableElement) {
-      propagatedType = (propagatedElement as ExecutableElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is TypeParameterElement) {
-      propagatedType = (propagatedElement as TypeParameterElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is VariableElement) {
-      propagatedType = (propagatedElement as VariableElement).type;
+      propagatedType = propagatedElement.type;
     }
     Type2 overriddenType = _overrideManager.getType(propagatedElement);
     if (propagatedType == null || (overriddenType != null && overriddenType.isMoreSpecificThan(propagatedType))) {
@@ -10587,6 +12006,7 @@
     if (identical(operator, sc.TokenType.BANG)) {
       recordStaticType(node, _typeProvider.boolType);
     } else {
+      // The other cases are equivalent to invoking a method.
       ExecutableElement staticMethodElement = node.staticElement;
       Type2 staticType = computeStaticReturnType(staticMethodElement);
       if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, sc.TokenType.PLUS_PLUS)) {
@@ -10655,13 +12075,15 @@
     Element element = propertyName.staticElement;
     Type2 staticType = _dynamicType;
     if (element is MethodElement) {
-      staticType = (element as MethodElement).type;
+      staticType = element.type;
     } else if (element is PropertyAccessorElement) {
-      staticType = getType(element as PropertyAccessorElement, node.target != null ? getStaticType(node.target) : null);
+      staticType = getType(element, node.target != null ? getStaticType(node.target) : null);
     } else {
     }
     recordStaticType(propertyName, staticType);
     recordStaticType(node, staticType);
+    // TODO(brianwilkerson) I think we want to repeat the logic above using the propagated element
+    // to get another candidate for the propagated type.
     Type2 propagatedType = _overrideManager.getType(element);
     if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
       recordPropagatedType2(node, propagatedType);
@@ -10725,26 +12147,27 @@
     Type2 staticType = _dynamicType;
     if (element is ClassElement) {
       if (isNotTypeLiteral(node)) {
-        staticType = (element as ClassElement).type;
+        staticType = element.type;
       } else {
         staticType = _typeProvider.typeType;
       }
     } else if (element is FunctionTypeAliasElement) {
       if (isNotTypeLiteral(node)) {
-        staticType = (element as FunctionTypeAliasElement).type;
+        staticType = element.type;
       } else {
         staticType = _typeProvider.typeType;
       }
     } else if (element is MethodElement) {
-      staticType = (element as MethodElement).type;
+      staticType = element.type;
     } else if (element is PropertyAccessorElement) {
-      staticType = getType(element as PropertyAccessorElement, null);
+      staticType = getType(element, null);
     } else if (element is ExecutableElement) {
-      staticType = (element as ExecutableElement).type;
+      staticType = element.type;
     } else if (element is TypeParameterElement) {
-      staticType = (element as TypeParameterElement).type;
+      //      if (isTypeName(node)) {
+      staticType = element.type;
     } else if (element is VariableElement) {
-      VariableElement variable = element as VariableElement;
+      VariableElement variable = element;
       staticType = _promoteManager.getStaticType(variable);
     } else if (element is PrefixElement) {
       return null;
@@ -10752,6 +12175,8 @@
       staticType = _dynamicType;
     }
     recordStaticType(node, staticType);
+    // TODO(brianwilkerson) I think we want to repeat the logic above using the propagated element
+    // to get another candidate for the propagated type.
     Type2 propagatedType = _overrideManager.getType(element);
     if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
       recordPropagatedType2(node, propagatedType);
@@ -10779,6 +12204,7 @@
 
   Object visitSuperExpression(SuperExpression node) {
     if (_thisType == null) {
+      // TODO(brianwilkerson) Report this error if it hasn't already been reported
       recordStaticType(node, _dynamicType);
     } else {
       recordStaticType(node, _thisType);
@@ -10797,6 +12223,7 @@
    */
   Object visitThisExpression(ThisExpression node) {
     if (_thisType == null) {
+      // TODO(brianwilkerson) Report this error if it hasn't already been reported
       recordStaticType(node, _dynamicType);
     } else {
       recordStaticType(node, _thisType);
@@ -10866,12 +12293,12 @@
    */
   Type2 computePropagatedReturnType2(FunctionBody body) {
     if (body is ExpressionFunctionBody) {
-      ExpressionFunctionBody expressionBody = body as ExpressionFunctionBody;
+      ExpressionFunctionBody expressionBody = body;
       return expressionBody.expression.bestType;
     }
     if (body is BlockFunctionBody) {
       List<Type2> result = [null];
-      body.accept(new GeneralizingASTVisitor_10(result));
+      body.accept(new GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2(result));
       return result[0];
     }
     return null;
@@ -10885,18 +12312,22 @@
    */
   Type2 computeStaticReturnType(Element element) {
     if (element is PropertyAccessorElement) {
-      FunctionType propertyType = (element as PropertyAccessorElement).type;
+      //
+      // This is a function invocation expression disguised as something else. We are invoking a
+      // getter and then invoking the returned function.
+      //
+      FunctionType propertyType = element.type;
       if (propertyType != null) {
         Type2 returnType = propertyType.returnType;
         if (returnType.isDartCoreFunction) {
           return _dynamicType;
         } else if (returnType is InterfaceType) {
-          MethodElement callMethod = (returnType as InterfaceType).lookUpMethod(ElementResolver.CALL_METHOD_NAME, _resolver.definingLibrary);
+          MethodElement callMethod = returnType.lookUpMethod(ElementResolver.CALL_METHOD_NAME, _resolver.definingLibrary);
           if (callMethod != null) {
             return callMethod.type.returnType;
           }
         } else if (returnType is FunctionType) {
-          Type2 innerReturnType = (returnType as FunctionType).returnType;
+          Type2 innerReturnType = returnType.returnType;
           if (innerReturnType != null) {
             return innerReturnType;
           }
@@ -10906,15 +12337,16 @@
         }
       }
     } else if (element is ExecutableElement) {
-      FunctionType type = (element as ExecutableElement).type;
+      FunctionType type = element.type;
       if (type != null) {
+        // TODO(brianwilkerson) Figure out the conditions under which the type is null.
         return type.returnType;
       }
     } else if (element is VariableElement) {
-      VariableElement variable = element as VariableElement;
+      VariableElement variable = element;
       Type2 variableType = _promoteManager.getStaticType(variable);
       if (variableType is FunctionType) {
-        return (variableType as FunctionType).returnType;
+        return variableType.returnType;
       }
     }
     return _dynamicType;
@@ -10947,7 +12379,7 @@
   Type2 computeStaticReturnType3(FunctionExpression node) {
     FunctionBody body = node.body;
     if (body is ExpressionFunctionBody) {
-      return getStaticType((body as ExpressionFunctionBody).expression);
+      return getStaticType(body.expression);
     }
     return _dynamicType;
   }
@@ -10986,9 +12418,16 @@
   Type2 getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentList) {
     String argumentValue = getFirstArgumentAsString(argumentList);
     if (argumentValue != null) {
+      //
+      // If the query has spaces, full parsing is required because it might be:
+      //   E[text='warning text']
+      //
       if (argumentValue.contains(" ")) {
         return null;
       }
+      //
+      // Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/selector.html.
+      //
       String tag = argumentValue;
       tag = StringUtilities.substringBefore(tag, ":");
       tag = StringUtilities.substringBefore(tag, "[");
@@ -11015,7 +12454,7 @@
     if (arguments.length > 0) {
       Expression argument = arguments[0];
       if (argument is SimpleStringLiteral) {
-        return (argument as SimpleStringLiteral).value;
+        return argument.value;
       }
     }
     return null;
@@ -11053,6 +12492,7 @@
   Type2 getStaticType(Expression expression) {
     Type2 type = expression.staticType;
     if (type == null) {
+      // TODO(brianwilkerson) Determine the conditions for which the static type is null.
       return _dynamicType;
     }
     return type;
@@ -11071,6 +12511,9 @@
   Type2 getType(PropertyAccessorElement accessor, Type2 context) {
     FunctionType functionType = accessor.type;
     if (functionType == null) {
+      // TODO(brianwilkerson) Report this internal error. This happens when we are analyzing a
+      // reference to a property before we have analyzed the declaration of the property or when
+      // the property does not have a defined type.
       return _dynamicType;
     }
     if (accessor.isSetter) {
@@ -11089,7 +12532,10 @@
     }
     Type2 returnType = functionType.returnType;
     if (returnType is TypeParameterType && context is InterfaceType) {
-      InterfaceType interfaceTypeContext = context as InterfaceType;
+      // if the return type is a TypeParameter, we try to use the context [that the function is being
+      // called on] to get a more accurate returnType type
+      InterfaceType interfaceTypeContext = context;
+      //      Type[] argumentTypes = interfaceTypeContext.getTypeArguments();
       List<TypeParameterElement> typeParameterElements = interfaceTypeContext.element != null ? interfaceTypeContext.element.typeParameters : null;
       if (typeParameterElements != null) {
         for (int i = 0; i < typeParameterElements.length; i++) {
@@ -11112,6 +12558,7 @@
   Type2 getType2(TypeName typeName) {
     Type2 type = typeName.type;
     if (type == null) {
+      //TODO(brianwilkerson) Determine the conditions for which the type is null.
       return _dynamicType;
     }
     return type;
@@ -11147,7 +12594,7 @@
    */
   bool isNotTypeLiteral(Identifier node) {
     ASTNode parent = node.parent;
-    return parent is TypeName || (parent is PrefixedIdentifier && (parent.parent is TypeName || identical((parent as PrefixedIdentifier).prefix, node))) || (parent is PropertyAccess && identical((parent as PropertyAccess).target, node)) || (parent is MethodInvocation && identical(node, (parent as MethodInvocation).target));
+    return parent is TypeName || (parent is PrefixedIdentifier && (parent.parent is TypeName || identical(parent.prefix, node))) || (parent is PropertyAccess && identical(parent.target, node)) || (parent is MethodInvocation && identical(node, parent.target));
   }
 
   /**
@@ -11164,13 +12611,16 @@
     if (propagatedReturnType == null) {
       return;
     }
+    // Ignore 'bottom' type.
     if (propagatedReturnType.isBottom) {
       return;
     }
+    // Record only if we inferred more specific type.
     Type2 staticReturnType = functionElement.returnType;
     if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) {
       return;
     }
+    // OK, do record.
     _propagatedReturnTypes[functionElement] = propagatedReturnType;
   }
 
@@ -11209,23 +12659,27 @@
    */
   Type2 refineBinaryExpressionType(BinaryExpression node, Type2 staticType) {
     sc.TokenType operator = node.operator.type;
+    // bool
     if (identical(operator, sc.TokenType.AMPERSAND_AMPERSAND) || identical(operator, sc.TokenType.BAR_BAR) || identical(operator, sc.TokenType.EQ_EQ) || identical(operator, sc.TokenType.BANG_EQ)) {
       return _typeProvider.boolType;
     }
     Type2 intType = _typeProvider.intType;
     if (getStaticType(node.leftOperand) == intType) {
+      // int op double
       if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.TokenType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator, sc.TokenType.STAR)) {
         Type2 doubleType = _typeProvider.doubleType;
         if (getStaticType(node.rightOperand) == doubleType) {
           return doubleType;
         }
       }
+      // int op int
       if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.TokenType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator, sc.TokenType.STAR) || identical(operator, sc.TokenType.TILDE_SLASH)) {
         if (getStaticType(node.rightOperand) == intType) {
           staticType = intType;
         }
       }
     }
+    // default
     return staticType;
   }
 
@@ -11234,14 +12688,15 @@
   set thisType_J2DAccessor(__v) => _thisType = __v;
 }
 
-class GeneralizingASTVisitor_10 extends GeneralizingASTVisitor<Object> {
+class GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2 extends GeneralizingASTVisitor<Object> {
   List<Type2> result;
 
-  GeneralizingASTVisitor_10(this.result) : super();
+  GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2(this.result) : super();
 
   Object visitExpression(Expression node) => null;
 
   Object visitReturnStatement(ReturnStatement node) {
+    // prepare this 'return' type
     Type2 type;
     Expression expression = node.expression;
     if (expression != null) {
@@ -11249,6 +12704,7 @@
     } else {
       type = BottomTypeImpl.instance;
     }
+    // merge types
     if (result[0] == null) {
       result[0] = type;
     } else {
@@ -11281,7 +12737,9 @@
    * @param classElement the class to recursively return the set of subtypes of
    */
   Set<ClassElement> computeAllSubtypes(ClassElement classElement) {
+    // Ensure that we have generated the subtype map for the library
     computeSubtypesInLibrary(classElement.library);
+    // use the subtypeMap to compute the set of all subtypes and subtype's subtypes
     Set<ClassElement> allSubtypes = new Set<ClassElement>();
     computeAllSubtypes2(classElement, new Set<ClassElement>(), allSubtypes);
     return allSubtypes;
@@ -11307,6 +12765,7 @@
    */
   void computeAllSubtypes2(ClassElement classElement, Set<ClassElement> visitedClasses, Set<ClassElement> allSubtypes) {
     if (!visitedClasses.add(classElement)) {
+      // if this class has already been called on this class element
       return;
     }
     Set<ClassElement> subtypes = _subtypeMap[classElement];
@@ -11577,7 +13036,7 @@
   Type2 getType(Element element) {
     Type2 type = _overridenTypes[element];
     if (type == null && element is PropertyAccessorElement) {
-      type = _overridenTypes[(element as PropertyAccessorElement).variable];
+      type = _overridenTypes[element.variable];
     }
     if (type != null) {
       return type;
@@ -11710,7 +13169,7 @@
   Type2 getType(Element element) {
     Type2 type = _promotedTypes[element];
     if (type == null && element is PropertyAccessorElement) {
-      type = _promotedTypes[(element as PropertyAccessorElement).variable];
+      type = _promotedTypes[element.variable];
     }
     if (type != null) {
       return type;
@@ -12045,13 +13504,13 @@
   static bool isTypeAnnotation(TypeName node) {
     ASTNode parent = node.parent;
     if (parent is VariableDeclarationList) {
-      return identical((parent as VariableDeclarationList).type, node);
+      return identical(parent.type, node);
     }
     if (parent is FieldFormalParameter) {
-      return identical((parent as FieldFormalParameter).type, node);
+      return identical(parent.type, node);
     }
     if (parent is SimpleFormalParameter) {
-      return identical((parent as SimpleFormalParameter).type, node);
+      return identical(parent.type, node);
     }
     return false;
   }
@@ -12109,6 +13568,8 @@
     super.visitCatchClause(node);
     SimpleIdentifier exception = node.exceptionParameter;
     if (exception != null) {
+      // If an 'on' clause is provided the type of the exception parameter is the type in the 'on'
+      // clause. Otherwise, the type of the exception parameter is 'Object'.
       TypeName exceptionTypeName = node.exceptionType;
       Type2 exceptionType;
       if (exceptionTypeName == null) {
@@ -12119,7 +13580,7 @@
       recordType(exception, exceptionType);
       Element element = exception.staticElement;
       if (element is VariableElementImpl) {
-        (element as VariableElementImpl).type = exceptionType;
+        element.type = exceptionType;
       } else {
       }
     }
@@ -12137,7 +13598,7 @@
     InterfaceType superclassType = null;
     ExtendsClause extendsClause = node.extendsClause;
     if (extendsClause != null) {
-      ErrorCode errorCode = (node.withClause == null ? CompileTimeErrorCode.EXTENDS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS) as ErrorCode;
+      ErrorCode errorCode = (node.withClause == null ? CompileTimeErrorCode.EXTENDS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS);
       superclassType = resolveType(extendsClause.superclass, errorCode, errorCode);
       if (superclassType != typeProvider.objectType) {
         classElement.validMixin = false;
@@ -12199,6 +13660,17 @@
 
   Object visitDefaultFormalParameter(DefaultFormalParameter node) {
     super.visitDefaultFormalParameter(node);
+    //    Expression defaultValue = node.getDefaultValue();
+    //    if (defaultValue != null) {
+    //      Type valueType = getType(defaultValue);
+    //      Type parameterType = getType(node.getParameter());
+    //      if (!valueType.isAssignableTo(parameterType)) {
+    // TODO(brianwilkerson) Determine whether this is really an error. I can't find in the spec
+    // anything that says it is, but a side comment from Gilad states that it should be a static
+    // warning.
+    //        resolver.reportError(ResolverErrorCode.?, defaultValue);
+    //      }
+    //    }
     return null;
   }
 
@@ -12206,12 +13678,13 @@
     super.visitFieldFormalParameter(node);
     Element element = node.identifier.staticElement;
     if (element is ParameterElementImpl) {
-      ParameterElementImpl parameter = element as ParameterElementImpl;
+      ParameterElementImpl parameter = element;
       FormalParameterList parameterList = node.parameters;
       if (parameterList == null) {
         Type2 type;
         TypeName typeName = node.type;
         if (typeName == null) {
+          // TODO(brianwilkerson) Find the field's declaration and use it's type.
           type = _dynamicType;
         } else {
           type = getType3(typeName);
@@ -12249,7 +13722,7 @@
     super.visitFunctionTypedFormalParameter(node);
     Element element = node.identifier.staticElement;
     if (element is ParameterElementImpl) {
-      setFunctionTypedParameterType(element as ParameterElementImpl, node.returnType, node.parameters);
+      setFunctionTypedParameterType(element, node.returnType, node.parameters);
     } else {
     }
     return null;
@@ -12308,6 +13781,10 @@
     TypeArgumentList argumentList = node.typeArguments;
     Element element = nameScope.lookup(typeName, definingLibrary);
     if (element == null) {
+      //
+      // Check to see whether the type name is either 'dynamic' or 'void', neither of which are in
+      // the name scope and hence will not be found by normal means.
+      //
       if (typeName.name == this._dynamicType.name) {
         setElement(typeName, this._dynamicType.element);
         if (argumentList != null) {
@@ -12318,28 +13795,42 @@
       }
       VoidTypeImpl voidType = VoidTypeImpl.instance;
       if (typeName.name == voidType.name) {
+        // There is no element for 'void'.
         if (argumentList != null) {
         }
         typeName.staticType = voidType;
         node.type = voidType;
         return null;
       }
+      //
+      // If not, the look to see whether we might have created the wrong AST structure for a
+      // constructor name. If so, fix the AST structure and then proceed.
+      //
       ASTNode parent = node.parent;
       if (typeName is PrefixedIdentifier && parent is ConstructorName && argumentList == null) {
-        ConstructorName name = parent as ConstructorName;
+        ConstructorName name = parent;
         if (name.name == null) {
           PrefixedIdentifier prefixedIdentifier = typeName as PrefixedIdentifier;
           SimpleIdentifier prefix = prefixedIdentifier.prefix;
           element = nameScope.lookup(prefix, definingLibrary);
           if (element is PrefixElement) {
             if (parent.parent is InstanceCreationExpression && (parent.parent as InstanceCreationExpression).isConst) {
-              reportError6(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
+              // If, if this is a const expression, then generate a
+              // CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
+              reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
             } else {
-              reportError6(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
+              // Else, if this expression is a new expression, report a NEW_WITH_NON_TYPE warning.
+              reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifier.identifier, [prefixedIdentifier.identifier.name]);
             }
             setElement(prefix, element);
             return null;
           } else if (element != null) {
+            //
+            // Rewrite the constructor name. The parser, when it sees a constructor named "a.b",
+            // cannot tell whether "a" is a prefix and "b" is a class name, or whether "a" is a
+            // class name and "b" is a constructor name. It arbitrarily chooses the former, but
+            // in this case was wrong.
+            //
             name.name = prefixedIdentifier.identifier;
             name.period = prefixedIdentifier.period;
             node.name = prefix;
@@ -12348,44 +13839,49 @@
         }
       }
     }
+    // check element
     bool elementValid = element is! MultiplyDefinedElement;
     if (elementValid && element is! ClassElement && isTypeNameInInstanceCreationExpression(node)) {
       SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
       InstanceCreationExpression creation = node.parent.parent as InstanceCreationExpression;
       if (creation.isConst) {
         if (element == null) {
-          reportError6(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
+          reportError7(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
         } else {
-          reportError6(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple, [typeName]);
+          reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple, [typeName]);
         }
         elementValid = false;
       } else {
         if (element != null) {
-          reportError6(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
+          reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
           elementValid = false;
         }
       }
     }
     if (elementValid && element == null) {
+      // We couldn't resolve the type name.
+      // TODO(jwren) Consider moving the check for CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE
+      // from the ErrorVerifier, so that we don't have two errors on a built in identifier being
+      // used as a class name. See CompileTimeErrorCodeTest.test_builtInIdentifierAsType().
       SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
       RedirectingConstructorKind redirectingConstructorKind;
       if (isBuiltInIdentifier(node) && isTypeAnnotation(node)) {
-        reportError6(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typeName, [typeName.name]);
+        reportError7(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typeName, [typeName.name]);
       } else if (typeNameSimple.name == "boolean") {
-        reportError6(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
+        reportError7(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
       } else if (isTypeNameInCatchClause(node)) {
-        reportError6(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
       } else if (isTypeNameInAsExpression(node)) {
-        reportError6(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
       } else if (isTypeNameInIsExpression(node)) {
-        reportError6(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
       } else if ((redirectingConstructorKind = getRedirectingConstructorKind(node)) != null) {
         ErrorCode errorCode = (identical(redirectingConstructorKind, RedirectingConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarningCode.REDIRECT_TO_NON_CLASS) as ErrorCode;
-        reportError6(errorCode, typeName, [typeName.name]);
+        reportError7(errorCode, typeName, [typeName.name]);
       } else if (isTypeNameInTypeArgumentList(node)) {
-        reportError6(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
+        reportError7(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
       } else {
-        reportError6(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
       }
       elementValid = false;
     }
@@ -12418,18 +13914,19 @@
         node.type = type;
       }
     } else {
+      // The name does not represent a type.
       RedirectingConstructorKind redirectingConstructorKind;
       if (isTypeNameInCatchClause(node)) {
-        reportError6(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
       } else if (isTypeNameInAsExpression(node)) {
-        reportError6(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
       } else if (isTypeNameInIsExpression(node)) {
-        reportError6(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
+        reportError7(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
       } else if ((redirectingConstructorKind = getRedirectingConstructorKind(node)) != null) {
         ErrorCode errorCode = (identical(redirectingConstructorKind, RedirectingConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarningCode.REDIRECT_TO_NON_CLASS) as ErrorCode;
-        reportError6(errorCode, typeName, [typeName.name]);
+        reportError7(errorCode, typeName, [typeName.name]);
       } else if (isTypeNameInTypeArgumentList(node)) {
-        reportError6(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
+        reportError7(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [typeName.name]);
       } else {
         ASTNode parent = typeName.parent;
         while (parent is TypeName) {
@@ -12437,7 +13934,7 @@
         }
         if (parent is ExtendsClause || parent is ImplementsClause || parent is WithClause || parent is ClassTypeAlias) {
         } else {
-          reportError6(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
+          reportError7(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
         }
       }
       setElement(typeName, this._dynamicType.element);
@@ -12459,10 +13956,15 @@
         }
       }
       if (argumentCount != parameterCount) {
-        reportError6(getInvalidTypeParametersErrorCode(node), node, [typeName.name, parameterCount, argumentCount]);
+        reportError7(getInvalidTypeParametersErrorCode(node), node, [typeName.name, parameterCount, argumentCount]);
       }
       argumentCount = typeArguments.length;
       if (argumentCount < parameterCount) {
+        //
+        // If there were too many arguments, we already handled it by not adding the values of the
+        // extra arguments to the list. If there are too few, we handle it by adding 'dynamic'
+        // enough times to make the count equal.
+        //
         for (int i = argumentCount; i < parameterCount; i++) {
           typeArguments.add(this._dynamicType);
         }
@@ -12476,6 +13978,9 @@
       } else {
       }
     } else {
+      //
+      // Check for the case where there are no type arguments given for a parameterized type.
+      //
       List<Type2> parameters = getTypeArguments(type);
       int parameterCount = parameters.length;
       if (parameterCount > 0) {
@@ -12505,7 +14010,7 @@
     if (element is VariableElement) {
       (element as VariableElementImpl).type = declaredType;
       if (element is PropertyInducingElement) {
-        PropertyInducingElement variableElement = element as PropertyInducingElement;
+        PropertyInducingElement variableElement = element;
         PropertyAccessorElementImpl getter = variableElement.getter as PropertyAccessorElementImpl;
         getter.returnType = declaredType;
         FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
@@ -12555,11 +14060,16 @@
    * @return the class element that represents the class
    */
   ClassElementImpl getClassElement(SimpleIdentifier identifier) {
+    // TODO(brianwilkerson) Seems like we should be using ClassDeclaration.getElement().
     if (identifier == null) {
+      // TODO(brianwilkerson) Report this
+      // Internal error: We should never build a class declaration without a name.
       return null;
     }
     Element element = identifier.staticElement;
     if (element is! ClassElementImpl) {
+      // TODO(brianwilkerson) Report this
+      // Internal error: Failed to create an element for a class declaration.
       return null;
     }
     return element as ClassElementImpl;
@@ -12576,6 +14086,7 @@
     List<ParameterElement> elements = new List<ParameterElement>();
     for (FormalParameter parameter in parameterList.parameters) {
       ParameterElement element = parameter.identifier.staticElement as ParameterElement;
+      // TODO(brianwilkerson) Understand why the element would be null.
       if (element != null) {
         elements.add(element);
       }
@@ -12646,7 +14157,7 @@
         if (type != null) {
           return null;
         }
-        type = (element as ClassElement).type;
+        type = element.type;
       }
     }
     return type;
@@ -12674,9 +14185,9 @@
    */
   List<Type2> getTypeArguments(Type2 type) {
     if (type is InterfaceType) {
-      return (type as InterfaceType).typeArguments;
+      return type.typeArguments;
     } else if (type is FunctionType) {
-      return (type as FunctionType).typeArguments;
+      return type.typeArguments;
     }
     return TypeImpl.EMPTY_ARRAY;
   }
@@ -12689,7 +14200,7 @@
    */
   SimpleIdentifier getTypeSimpleIdentifier(Identifier typeName) {
     if (typeName is SimpleIdentifier) {
-      return typeName as SimpleIdentifier;
+      return typeName;
     } else {
       return (typeName as PrefixedIdentifier).identifier;
     }
@@ -12704,7 +14215,7 @@
   bool isTypeNameInAsExpression(TypeName typeName) {
     ASTNode parent = typeName.parent;
     if (parent is AsExpression) {
-      AsExpression asExpression = parent as AsExpression;
+      AsExpression asExpression = parent;
       return identical(asExpression.type, typeName);
     }
     return false;
@@ -12719,7 +14230,7 @@
   bool isTypeNameInCatchClause(TypeName typeName) {
     ASTNode parent = typeName.parent;
     if (parent is CatchClause) {
-      CatchClause catchClause = parent as CatchClause;
+      CatchClause catchClause = parent;
       return identical(catchClause.exceptionType, typeName);
     }
     return false;
@@ -12735,7 +14246,7 @@
   bool isTypeNameInInstanceCreationExpression(TypeName typeName) {
     ASTNode parent = typeName.parent;
     if (parent is ConstructorName && parent.parent is InstanceCreationExpression) {
-      ConstructorName constructorName = parent as ConstructorName;
+      ConstructorName constructorName = parent;
       return constructorName != null && identical(constructorName.type, typeName);
     }
     return false;
@@ -12750,7 +14261,7 @@
   bool isTypeNameInIsExpression(TypeName typeName) {
     ASTNode parent = typeName.parent;
     if (parent is IsExpression) {
-      IsExpression isExpression = parent as IsExpression;
+      IsExpression isExpression = parent;
       return identical(isExpression.type, typeName);
     }
     return false;
@@ -12801,6 +14312,7 @@
       if (classElement != null) {
         classElement.interfaces = interfaceTypes;
       }
+      // TODO(brianwilkerson) Move the following checks to ErrorVerifier.
       List<TypeName> typeNames = new List.from(interfaces);
       List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length, false);
       for (int i = 0; i < detectedRepeatOnIndex.length; i++) {
@@ -12817,7 +14329,7 @@
             Element element2 = identifier2.staticElement;
             if (element != null && element == element2) {
               detectedRepeatOnIndex[j] = true;
-              reportError6(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
+              reportError7(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
             }
           }
         }
@@ -12837,13 +14349,14 @@
   InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCode dynamicTypeError) {
     Type2 type = typeName.type;
     if (type is InterfaceType) {
-      return type as InterfaceType;
+      return type;
     }
+    // If the type is not an InterfaceType, then visitTypeName() sets the type to be a DynamicTypeImpl
     Identifier name = typeName.name;
     if (name.name == sc.Keyword.DYNAMIC.syntax) {
-      reportError6(dynamicTypeError, name, [name.name]);
+      reportError7(dynamicTypeError, name, [name.name]);
     } else {
-      reportError6(nonTypeError, name, [name.name]);
+      reportError7(nonTypeError, name, [name.name]);
     }
     return null;
   }
@@ -12871,9 +14384,9 @@
   void setElement(Identifier typeName, Element element) {
     if (element != null) {
       if (typeName is SimpleIdentifier) {
-        (typeName as SimpleIdentifier).staticElement = element;
+        typeName.staticElement = element;
       } else if (typeName is PrefixedIdentifier) {
-        PrefixedIdentifier identifier = typeName as PrefixedIdentifier;
+        PrefixedIdentifier identifier = typeName;
         identifier.identifier.staticElement = element;
         SimpleIdentifier prefix = identifier.prefix;
         Element prefixElement = nameScope.lookup(prefix, definingLibrary);
@@ -12991,17 +14504,19 @@
   }
 
   Object visitSimpleIdentifier(SimpleIdentifier node) {
+    // Ignore if already resolved - declaration or type.
     if (node.staticElement != null) {
       return null;
     }
+    // Ignore if qualified.
     ASTNode parent = node.parent;
-    if (parent is PrefixedIdentifier && identical((parent as PrefixedIdentifier).identifier, node)) {
+    if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
       return null;
     }
-    if (parent is PropertyAccess && identical((parent as PropertyAccess).propertyName, node)) {
+    if (parent is PropertyAccess && identical(parent.propertyName, node)) {
       return null;
     }
-    if (parent is MethodInvocation && identical((parent as MethodInvocation).methodName, node)) {
+    if (parent is MethodInvocation && identical(parent.methodName, node)) {
       return null;
     }
     if (parent is ConstructorName) {
@@ -13010,10 +14525,12 @@
     if (parent is Label) {
       return null;
     }
+    // Prepare VariableElement.
     Element element = nameScope.lookup(node, definingLibrary);
     if (element is! VariableElement) {
       return null;
     }
+    // Must be local or parameter.
     ElementKind kind = element.kind;
     if (identical(kind, ElementKind.LOCAL_VARIABLE)) {
       node.staticElement = element;
@@ -13029,6 +14546,7 @@
       if (node.inSetterContext()) {
         ParameterElementImpl parameterImpl = element as ParameterElementImpl;
         parameterImpl.markPotentiallyMutatedInScope();
+        // If we are in some closure, check if it is not the same as where variable is declared.
         if (_enclosingFunction != null && (element.enclosingElement != _enclosingFunction)) {
           parameterImpl.markPotentiallyMutatedInClosure();
         }
@@ -13148,6 +14666,7 @@
     if (element != null) {
       return element;
     }
+    // May be there is a hidden Element.
     if (_hasHiddenName) {
       Element hiddenElement = _hiddenElements[name];
       if (hiddenElement != null) {
@@ -13155,6 +14674,7 @@
         return hiddenElement;
       }
     }
+    // Check enclosing scope.
     return enclosingScope.lookup3(identifier, name, referencingLibrary);
   }
 }
@@ -13399,6 +14919,8 @@
       List<Element> conflictingMembers = (foundElement as MultiplyDefinedElementImpl).conflictingElements;
       String libName1 = getLibraryName(conflictingMembers[0], "");
       String libName2 = getLibraryName(conflictingMembers[1], "");
+      // TODO (jwren) Change the error message to include a list of all library names instead of
+      // just the first two
       errorListener.onError(new AnalysisError.con2(getSource(identifier), identifier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltName, libName1, libName2]));
       return foundElement;
     }
@@ -13471,10 +14993,13 @@
       errorListener.onError(new AnalysisError.con2(getSource(identifier), identifier.offset, identifier.length, StaticWarningCode.CONFLICTING_DART_IMPORT, [name, sdkLibName, otherLibName]));
     }
     if (to == length) {
+      // None of the members were removed
       return foundElement;
     } else if (to == 1) {
+      // All but one member was removed
       return conflictingMembers[0];
     } else if (to == 0) {
+      // All members were removed
       AnalysisEngine.instance.logger.logInformation("Multiply defined SDK element: ${foundElement}");
       return foundElement;
     }
@@ -13503,9 +15028,10 @@
 
   AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
     if (existing is PrefixElement) {
+      // TODO(scheglov) consider providing actual 'nameOffset' from the synthetic accessor
       int offset = duplicate.nameOffset;
       if (duplicate is PropertyAccessorElement) {
-        PropertyAccessorElement accessor = duplicate as PropertyAccessorElement;
+        PropertyAccessorElement accessor = duplicate;
         if (accessor.isSynthetic) {
           offset = accessor.variable.nameOffset;
         }
@@ -13615,6 +15141,9 @@
   Namespace createExportNamespace(ExportElement element) {
     LibraryElement exportedLibrary = element.exportedLibrary;
     if (exportedLibrary == null) {
+      //
+      // The exported library will be null if the URI does not reference a valid library.
+      //
       return Namespace.EMPTY;
     }
     Map<String, Element> definedNames = createExportMapping(exportedLibrary, new Set<LibraryElement>());
@@ -13639,6 +15168,9 @@
   Namespace createImportNamespace(ImportElement element) {
     LibraryElement importedLibrary = element.importedLibrary;
     if (importedLibrary == null) {
+      //
+      // The imported library will be null if the URI does not reference a valid library.
+      //
       return Namespace.EMPTY;
     }
     Map<String, Element> definedNames = createExportMapping(importedLibrary, new Set<LibraryElement>());
@@ -13731,10 +15263,11 @@
   Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCombinator> combinators) {
     for (NamespaceCombinator combinator in combinators) {
       if (combinator is HideElementCombinator) {
-        hide(definedNames, (combinator as HideElementCombinator).hiddenNames);
+        hide(definedNames, combinator.hiddenNames);
       } else if (combinator is ShowElementCombinator) {
-        definedNames = show(definedNames, (combinator as ShowElementCombinator).shownNames);
+        definedNames = show(definedNames, combinator.shownNames);
       } else {
+        // Internal error.
         AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${combinator.runtimeType.toString()}");
       }
     }
@@ -13776,6 +15309,9 @@
       for (ExportElement element in library.exports) {
         LibraryElement exportedLibrary = element.exportedLibrary;
         if (exportedLibrary != null && !visitedElements.contains(exportedLibrary)) {
+          //
+          // The exported library will be null if the URI does not reference a valid library.
+          //
           Map<String, Element> exportedNames = createExportMapping(exportedLibrary, visitedElements);
           exportedNames = apply(exportedNames, element.combinators);
           addAll(definedNames, exportedNames);
@@ -13936,6 +15472,9 @@
    * @return the error code used to report duplicate names within a scope
    */
   AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
+    // TODO(brianwilkerson) Customize the error message based on the types of elements that share
+    // the same name.
+    // TODO(jwren) There are 4 error codes for duplicate, but only 1 is being generated.
     Source source = duplicate.source;
     return new AnalysisError.con2(source, duplicate.nameOffset, duplicate.displayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName]);
   }
@@ -14003,7 +15542,7 @@
    */
   String getName(Element element) {
     if (element is MethodElement) {
-      MethodElement method = element as MethodElement;
+      MethodElement method = element;
       if (method.name == "-" && method.parameters.length == 0) {
         return UNARY_MINUS;
       }
@@ -14069,7 +15608,7 @@
    */
   Scope scopeForAstNode(ASTNode node) {
     if (node is CompilationUnit) {
-      return scopeForCompilationUnit(node as CompilationUnit);
+      return scopeForCompilationUnit(node);
     }
     ASTNode parent = node.parent;
     if (parent == null) {
@@ -14077,21 +15616,21 @@
     }
     Scope scope = scopeForAstNode(parent);
     if (node is ClassDeclaration) {
-      scope = new ClassScope(scope, (node as ClassDeclaration).element);
+      scope = new ClassScope(scope, node.element);
     } else if (node is ClassTypeAlias) {
-      scope = new ClassScope(scope, (node as ClassTypeAlias).element);
+      scope = new ClassScope(scope, node.element);
     } else if (node is ConstructorDeclaration) {
-      FunctionScope functionScope = new FunctionScope(scope, (node as ConstructorDeclaration).element);
+      FunctionScope functionScope = new FunctionScope(scope, node.element);
       functionScope.defineParameters();
       scope = functionScope;
     } else if (node is FunctionDeclaration) {
-      FunctionScope functionScope = new FunctionScope(scope, (node as FunctionDeclaration).element);
+      FunctionScope functionScope = new FunctionScope(scope, node.element);
       functionScope.defineParameters();
       scope = functionScope;
     } else if (node is FunctionTypeAlias) {
-      scope = new FunctionTypeScope(scope, (node as FunctionTypeAlias).element);
+      scope = new FunctionTypeScope(scope, node.element);
     } else if (node is MethodDeclaration) {
-      FunctionScope functionScope = new FunctionScope(scope, (node as MethodDeclaration).element);
+      FunctionScope functionScope = new FunctionScope(scope, node.element);
       functionScope.defineParameters();
       scope = functionScope;
     }
@@ -14125,6 +15664,11 @@
   ErrorReporter _errorReporter;
 
   /**
+   * The type provider used to access the known types.
+   */
+  TypeProvider _typeProvider;
+
+  /**
    * The type representing the type 'bool'.
    */
   InterfaceType _boolType;
@@ -14151,6 +15695,7 @@
    */
   ConstantVerifier(ErrorReporter errorReporter, TypeProvider typeProvider) {
     this._errorReporter = errorReporter;
+    this._typeProvider = typeProvider;
     this._boolType = typeProvider.boolType;
     this._intType = typeProvider.intType;
     this._numType = typeProvider.numType;
@@ -14159,18 +15704,22 @@
 
   Object visitAnnotation(Annotation node) {
     super.visitAnnotation(node);
+    // check annotation creation
     Element element = node.element;
     if (element is ConstructorElement) {
-      ConstructorElement constructorElement = element as ConstructorElement;
+      ConstructorElement constructorElement = element;
+      // should 'const' constructor
       if (!constructorElement.isConst) {
-        _errorReporter.reportError2(CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR, node, []);
+        _errorReporter.reportError3(CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR, node, []);
         return null;
       }
+      // should have arguments
       ArgumentList argumentList = node.arguments;
       if (argumentList == null) {
-        _errorReporter.reportError2(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, node, []);
+        _errorReporter.reportError3(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, node, []);
         return null;
       }
+      // arguments should be constants
       validateConstantArguments(argumentList);
     }
     return null;
@@ -14209,7 +15758,7 @@
     super.visitMapLiteral(node);
     bool isConst = node.constKeyword != null;
     bool reportEqualKeys = true;
-    Set<Object> keys = new Set<Object>();
+    Set<DartObject> keys = new Set<DartObject>();
     List<Expression> invalidKeys = new List<Expression>();
     for (MapLiteralEntry entry in node.entries) {
       Expression key = entry.key;
@@ -14217,7 +15766,7 @@
         EvaluationResultImpl result = validate(key, CompileTimeErrorCode.NON_CONSTANT_MAP_KEY);
         validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE);
         if (result is ValidResult) {
-          Object value = (result as ValidResult).value;
+          DartObject value = result.value;
           if (keys.contains(value)) {
             invalidKeys.add(key);
           } else {
@@ -14225,9 +15774,9 @@
           }
         }
       } else {
-        EvaluationResultImpl result = key.accept(new ConstantVisitor());
+        EvaluationResultImpl result = key.accept(new ConstantVisitor(_typeProvider));
         if (result is ValidResult) {
-          Object value = (result as ValidResult).value;
+          DartObject value = result.value;
           if (keys.contains(value)) {
             invalidKeys.add(key);
           } else {
@@ -14240,7 +15789,7 @@
     }
     if (reportEqualKeys) {
       for (Expression key in invalidKeys) {
-        _errorReporter.reportError2(StaticWarningCode.EQUAL_KEYS_IN_MAP, key, []);
+        _errorReporter.reportError3(StaticWarningCode.EQUAL_KEYS_IN_MAP, key, []);
       }
     }
     return null;
@@ -14265,6 +15814,11 @@
       VariableElementImpl element = node.element as VariableElementImpl;
       EvaluationResultImpl result = element.evaluationResult;
       if (result == null) {
+        //
+        // Normally we don't need to visit const variable declarations because we have already
+        // computed their values. But if we missed it for some reason, this gives us a second
+        // chance.
+        //
         result = validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
         element.evaluationResult = result;
       } else if (result is ErrorResult) {
@@ -14283,17 +15837,19 @@
    */
   void reportErrors(EvaluationResultImpl result, ErrorCode errorCode) {
     if (result is ErrorResult) {
-      for (ErrorResult_ErrorData data in (result as ErrorResult).errorData) {
+      for (ErrorResult_ErrorData data in result.errorData) {
         ErrorCode dataErrorCode = data.errorCode;
         if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) {
-          _errorReporter.reportError2(dataErrorCode, data.node, []);
+          _errorReporter.reportError3(dataErrorCode, data.node, []);
         } else {
-          _errorReporter.reportError2(errorCode, data.node, []);
+          _errorReporter.reportError3(errorCode, data.node, []);
         }
       }
     }
   }
 
+  ValidResult valid(InterfaceType type, InstanceState state) => new ValidResult(new DartObjectImpl(type, state));
+
   /**
    * Validate that the given expression is a compile time constant. Return the value of the compile
    * time constant, or `null` if the expression is not a compile time constant.
@@ -14303,7 +15859,7 @@
    * @return the value of the compile time constant
    */
   EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) {
-    EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+    EvaluationResultImpl result = expression.accept(new ConstantVisitor(_typeProvider));
     reportErrors(result, errorCode);
     return result;
   }
@@ -14351,7 +15907,7 @@
     }
     for (FormalParameter parameter in parameters.parameters) {
       if (parameter is DefaultFormalParameter) {
-        DefaultFormalParameter defaultParameter = parameter as DefaultFormalParameter;
+        DefaultFormalParameter defaultParameter = parameter;
         Expression defaultValue = defaultParameter.defaultValue;
         if (defaultValue != null) {
           EvaluationResultImpl result = validate(defaultValue, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
@@ -14370,7 +15926,7 @@
    * @param expression the expression to validate
    */
   void validateInitializerExpression(List<ParameterElement> parameterElements, Expression expression) {
-    EvaluationResultImpl result = expression.accept(new ConstantVisitor_13(this, parameterElements));
+    EvaluationResultImpl result = expression.accept(new ConstantVisitor_ConstantVerifier_validateInitializerExpression(_typeProvider, this, parameterElements));
     reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
   }
 
@@ -14401,27 +15957,27 @@
     NodeList<ConstructorInitializer> initializers = constructor.initializers;
     for (ConstructorInitializer initializer in initializers) {
       if (initializer is ConstructorFieldInitializer) {
-        ConstructorFieldInitializer fieldInitializer = initializer as ConstructorFieldInitializer;
+        ConstructorFieldInitializer fieldInitializer = initializer;
         validateInitializerExpression(parameterElements, fieldInitializer.expression);
       }
       if (initializer is RedirectingConstructorInvocation) {
-        RedirectingConstructorInvocation invocation = initializer as RedirectingConstructorInvocation;
+        RedirectingConstructorInvocation invocation = initializer;
         validateInitializerInvocationArguments(parameterElements, invocation.argumentList);
       }
       if (initializer is SuperConstructorInvocation) {
-        SuperConstructorInvocation invocation = initializer as SuperConstructorInvocation;
+        SuperConstructorInvocation invocation = initializer;
         validateInitializerInvocationArguments(parameterElements, invocation.argumentList);
       }
     }
   }
 }
 
-class ConstantVisitor_13 extends ConstantVisitor {
+class ConstantVisitor_ConstantVerifier_validateInitializerExpression extends ConstantVisitor {
   final ConstantVerifier ConstantVerifier_this;
 
   List<ParameterElement> parameterElements;
 
-  ConstantVisitor_13(this.ConstantVerifier_this, this.parameterElements) : super();
+  ConstantVisitor_ConstantVerifier_validateInitializerExpression(TypeProvider arg0, this.ConstantVerifier_this, this.parameterElements) : super(arg0);
 
   EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) {
     Element element = node.staticElement;
@@ -14430,22 +15986,20 @@
         Type2 type = parameterElement.type;
         if (type != null) {
           if (type.isDynamic) {
-            return ValidResult.RESULT_DYNAMIC;
-          }
-          if (type.isSubtypeOf(ConstantVerifier_this._boolType)) {
-            return ValidResult.RESULT_BOOL;
-          }
-          if (type.isSubtypeOf(ConstantVerifier_this._intType)) {
-            return ValidResult.RESULT_INT;
-          }
-          if (type.isSubtypeOf(ConstantVerifier_this._numType)) {
-            return ValidResult.RESULT_NUM;
-          }
-          if (type.isSubtypeOf(ConstantVerifier_this._stringType)) {
-            return ValidResult.RESULT_STRING;
+            return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvider.objectType, DynamicState.DYNAMIC_STATE);
+          } else if (type.isSubtypeOf(ConstantVerifier_this._boolType)) {
+            return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvider.boolType, BoolState.UNKNOWN_VALUE);
+          } else if (type.isSubtypeOf(ConstantVerifier_this._typeProvider.doubleType)) {
+            return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
+          } else if (type.isSubtypeOf(ConstantVerifier_this._intType)) {
+            return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvider.intType, IntState.UNKNOWN_VALUE);
+          } else if (type.isSubtypeOf(ConstantVerifier_this._numType)) {
+            return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvider.numType, NumState.UNKNOWN_VALUE);
+          } else if (type.isSubtypeOf(ConstantVerifier_this._stringType)) {
+            return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvider.stringType, StringState.UNKNOWN_VALUE);
           }
         }
-        return ValidResult.RESULT_OBJECT;
+        return ConstantVerifier_this.valid(type is InterfaceType ? type : ConstantVerifier_this._typeProvider.objectType, GenericState.UNKNOWN_VALUE);
       }
     }
     return super.visitSimpleIdentifier(node);
@@ -14733,6 +16287,7 @@
           checkForRecursiveInterfaceInheritance(_enclosingClass);
         }
       }
+      // initialize initialFieldElementsMap
       ClassElement classElement = node.element;
       if (classElement != null) {
         List<FieldElement> fieldElements = classElement.fields;
@@ -14849,7 +16404,7 @@
     if (!node.isStatic) {
       VariableDeclarationList variables = node.fields;
       if (variables.isConst) {
-        _errorReporter.reportError5(CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword, []);
+        _errorReporter.reportError6(CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword, []);
       }
     }
     _isInStaticVariableDeclaration = node.isStatic;
@@ -14897,6 +16452,8 @@
   }
 
   Object visitFunctionExpression(FunctionExpression node) {
+    // If this function expression is wrapped in a function declaration, don't change the
+    // enclosingFunction field.
     if (node.parent is! FunctionDeclaration) {
       ExecutableElement outerFunction = _enclosingFunction;
       try {
@@ -14914,7 +16471,7 @@
     Expression functionExpression = node.function;
     Type2 expressionType = functionExpression.staticType;
     if (!isFunctionType(expressionType)) {
-      _errorReporter.reportError2(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, functionExpression, []);
+      _errorReporter.reportError3(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, functionExpression, []);
     }
     return super.visitFunctionExpressionInvocation(node);
   }
@@ -14959,7 +16516,7 @@
       TypeName typeName = constructorName.type;
       Type2 type = typeName.type;
       if (type is InterfaceType) {
-        InterfaceType interfaceType = type as InterfaceType;
+        InterfaceType interfaceType = type;
         checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
         if (_isInConstInstanceCreation) {
           checkForConstWithNonConst(node);
@@ -15056,8 +16613,9 @@
   }
 
   Object visitNativeClause(NativeClause node) {
+    // TODO(brianwilkerson) Figure out the right rule for when 'native' is allowed.
     if (!_isInSystemLibrary) {
-      _errorReporter.reportError2(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node, []);
+      _errorReporter.reportError3(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node, []);
     }
     return super.visitNativeClause(node);
   }
@@ -15187,8 +16745,11 @@
   Object visitVariableDeclaration(VariableDeclaration node) {
     SimpleIdentifier nameNode = node.name;
     Expression initializerNode = node.initializer;
+    // do checks
     checkForInvalidAssignment2(nameNode, initializerNode);
+    // visit name
     nameNode.accept(this);
+    // visit initializer
     String name = nameNode.name;
     _namesForReferenceToDeclaredVariableInInitializer.add(name);
     _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration;
@@ -15200,6 +16761,7 @@
       _isInInstanceVariableInitializer = false;
       _namesForReferenceToDeclaredVariableInInitializer.remove(name);
     }
+    // done
     return null;
   }
 
@@ -15223,14 +16785,17 @@
    * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS
    */
   bool checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) {
+    // has type arguments
     if (typeArguments == null) {
       return false;
     }
+    // check number of type arguments
     int num = typeArguments.arguments.length;
     if (num == 2) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [num]);
+    // report problem
+    _errorReporter.reportError3(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [num]);
     return true;
   }
 
@@ -15248,11 +16813,13 @@
     if (node.factoryKeyword != null || node.redirectedConstructor != null || node.externalKeyword != null) {
       return false;
     }
+    // Ignore if native class.
     if (_isInNativeClass) {
       return false;
     }
     bool foundError = false;
     Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_STATE>.from(_initialFieldElementsMap);
+    // Visit all of the field formal parameters
     NodeList<FormalParameter> formalParameters = node.parameters.parameters;
     for (FormalParameter formalParameter in formalParameters) {
       FormalParameter parameter = formalParameter;
@@ -15266,54 +16833,56 @@
           fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
         } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
           if (fieldElement.isFinal || fieldElement.isConst) {
-            _errorReporter.reportError2(StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayName]);
+            _errorReporter.reportError3(StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayName]);
             foundError = true;
           }
         } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
           if (fieldElement.isFinal || fieldElement.isConst) {
-            _errorReporter.reportError2(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]);
+            _errorReporter.reportError3(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]);
             foundError = true;
           }
         }
       }
     }
+    // Visit all of the initializers
     NodeList<ConstructorInitializer> initializers = node.initializers;
     for (ConstructorInitializer constructorInitializer in initializers) {
       if (constructorInitializer is RedirectingConstructorInvocation) {
         return false;
       }
       if (constructorInitializer is ConstructorFieldInitializer) {
-        ConstructorFieldInitializer constructorFieldInitializer = constructorInitializer as ConstructorFieldInitializer;
+        ConstructorFieldInitializer constructorFieldInitializer = constructorInitializer;
         SimpleIdentifier fieldName = constructorFieldInitializer.fieldName;
         Element element = fieldName.staticElement;
         if (element is FieldElement) {
-          FieldElement fieldElement = element as FieldElement;
+          FieldElement fieldElement = element;
           INIT_STATE state = fieldElementsMap[fieldElement];
           if (identical(state, INIT_STATE.NOT_INIT)) {
             fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS;
           } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
             if (fieldElement.isFinal || fieldElement.isConst) {
-              _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, fieldName, []);
+              _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, fieldName, []);
               foundError = true;
             }
           } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
-            _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, fieldName, []);
+            _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, fieldName, []);
             foundError = true;
           } else if (identical(state, INIT_STATE.INIT_IN_INITIALIZERS)) {
-            _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, fieldName, [fieldElement.displayName]);
+            _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, fieldName, [fieldElement.displayName]);
             foundError = true;
           }
         }
       }
     }
+    // Visit all of the states in the map to ensure that none were never initialized.
     for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElementsMap)) {
       if (identical(entry.getValue(), INIT_STATE.NOT_INIT)) {
         FieldElement fieldElement = entry.getKey();
         if (fieldElement.isConst) {
-          _errorReporter.reportError2(CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
+          _errorReporter.reportError3(CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
           foundError = true;
         } else if (fieldElement.isFinal) {
-          _errorReporter.reportError2(StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
+          _errorReporter.reportError3(StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
           foundError = true;
         }
       }
@@ -15347,10 +16916,11 @@
     bool isGetter = false;
     bool isSetter = false;
     if (executableElement is PropertyAccessorElement) {
-      PropertyAccessorElement accessorElement = executableElement as PropertyAccessorElement;
+      PropertyAccessorElement accessorElement = executableElement;
       isGetter = accessorElement.isGetter;
       isSetter = accessorElement.isSetter;
     }
+    // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
     if (overriddenExecutable == null) {
       if (!isGetter && !isSetter && !executableElement.isOperator) {
         Set<ClassElement> visitedClasses = new Set<ClassElement>();
@@ -15359,31 +16929,39 @@
         while (superclassElement != null && !visitedClasses.contains(superclassElement)) {
           visitedClasses.add(superclassElement);
           LibraryElement superclassLibrary = superclassElement.library;
+          // Check fields.
           List<FieldElement> fieldElts = superclassElement.fields;
           for (FieldElement fieldElt in fieldElts) {
+            // We need the same name.
             if (fieldElt.name != executableElementName) {
               continue;
             }
+            // Ignore if private in a different library - cannot collide.
             if (executableElementPrivate && _currentLibrary != superclassLibrary) {
               continue;
             }
+            // instance vs. static
             if (fieldElt.isStatic) {
-              _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
+              _errorReporter.reportError3(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
                   executableElementName,
                   fieldElt.enclosingElement.displayName]);
               return true;
             }
           }
+          // Check methods.
           List<MethodElement> methodElements = superclassElement.methods;
           for (MethodElement methodElement in methodElements) {
+            // We need the same name.
             if (methodElement.name != executableElementName) {
               continue;
             }
+            // Ignore if private in a different library - cannot collide.
             if (executableElementPrivate && _currentLibrary != superclassLibrary) {
               continue;
             }
+            // instance vs. static
             if (methodElement.isStatic) {
-              _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
+              _errorReporter.reportError3(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
                   executableElementName,
                   methodElement.enclosingElement.displayName]);
               return true;
@@ -15410,43 +16988,50 @@
     List<Type2> overriddenPositionalPT = overriddenFT.optionalParameterTypes;
     Map<String, Type2> overridingNamedPT = overridingFT.namedParameterTypes;
     Map<String, Type2> overriddenNamedPT = overriddenFT.namedParameterTypes;
+    // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and CTEC.INVALID_OVERRIDE_NAMED
     if (overridingNormalPT.length > overriddenNormalPT.length) {
-      _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
+      _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
           overriddenNormalPT.length,
           overriddenExecutable.enclosingElement.displayName]);
       return true;
     }
     if (overridingNormalPT.length + overridingPositionalPT.length < overriddenPositionalPT.length + overriddenNormalPT.length) {
-      _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
+      _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
           overriddenPositionalPT.length + overriddenNormalPT.length,
           overriddenExecutable.enclosingElement.displayName]);
       return true;
     }
+    // For each named parameter in the overridden method, verify that there is the same name in
+    // the overriding method, and in the same order.
     Set<String> overridingParameterNameSet = overridingNamedPT.keys.toSet();
     JavaIterator<String> overriddenParameterNameIterator = new JavaIterator(overriddenNamedPT.keys.toSet());
     while (overriddenParameterNameIterator.hasNext) {
       String overriddenParamName = overriddenParameterNameIterator.next();
       if (!overridingParameterNameSet.contains(overriddenParamName)) {
-        _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
+        // The overridden method expected the overriding method to have overridingParamName,
+        // but it does not.
+        _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
             overriddenParamName,
             overriddenExecutable.enclosingElement.displayName]);
         return true;
       }
     }
+    // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE
     if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnType.isAssignableTo(overriddenFTReturnType)) {
-      _errorReporter.reportError2(!isGetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, errorNameTarget, [
+      _errorReporter.reportError3(!isGetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, errorNameTarget, [
           overridingFTReturnType.displayName,
           overriddenFTReturnType.displayName,
           overriddenExecutable.enclosingElement.displayName]);
       return true;
     }
+    // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
     if (parameterLocations == null) {
       return false;
     }
     int parameterIndex = 0;
     for (int i = 0; i < overridingNormalPT.length; i++) {
       if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) {
-        _errorReporter.reportError2(!isSetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, parameterLocations[parameterIndex], [
+        _errorReporter.reportError3(!isSetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, parameterLocations[parameterIndex], [
             overridingNormalPT[i].displayName,
             overriddenNormalPT[i].displayName,
             overriddenExecutable.enclosingElement.displayName]);
@@ -15454,9 +17039,10 @@
       }
       parameterIndex++;
     }
+    // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
     for (int i = 0; i < overriddenPositionalPT.length; i++) {
       if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i])) {
-        _errorReporter.reportError2(StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [
+        _errorReporter.reportError3(StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [
             overridingPositionalPT[i].displayName,
             overriddenPositionalPT[i].displayName,
             overriddenExecutable.enclosingElement.displayName]);
@@ -15464,14 +17050,18 @@
       }
       parameterIndex++;
     }
+    // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
     JavaIterator<MapEntry<String, Type2>> overriddenNamedPTIterator = new JavaIterator(getMapEntrySet(overriddenNamedPT));
     while (overriddenNamedPTIterator.hasNext) {
       MapEntry<String, Type2> overriddenNamedPTEntry = overriddenNamedPTIterator.next();
       Type2 overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()];
       if (overridingType == null) {
+        // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been created above if
+        // this could be reached.
         continue;
       }
       if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
+        // lookup the parameter for the error to select
         ParameterElement parameterToSelect = null;
         ASTNode parameterLocationToSelect = null;
         for (int i = 0; i < parameters.length; i++) {
@@ -15483,7 +17073,7 @@
           }
         }
         if (parameterToSelect != null) {
-          _errorReporter.reportError2(StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [
+          _errorReporter.reportError3(StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [
               overridingType.displayName,
               overriddenNamedPTEntry.getValue().displayName,
               overriddenExecutable.enclosingElement.displayName]);
@@ -15491,6 +17081,12 @@
         }
       }
     }
+    // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
+    //
+    // Create three arrays: an array of the optional parameter ASTs (FormalParameters), an array of
+    // the optional parameters elements from our method, and finally an array of the optional
+    // parameter elements from the method we are overriding.
+    //
     bool foundError = false;
     List<ASTNode> formalParameters = new List<ASTNode>();
     List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
@@ -15506,16 +17102,22 @@
     for (ParameterElement parameterElt in overriddenPEs) {
       if (parameterElt.parameterKind.isOptional) {
         if (parameterElt is ParameterElementImpl) {
-          overriddenParameterElts.add(parameterElt as ParameterElementImpl);
+          overriddenParameterElts.add(parameterElt);
         }
       }
     }
+    //
+    // Next compare the list of optional parameter elements to the list of overridden optional
+    // parameter elements.
+    //
     if (parameterElts.length > 0) {
       if (identical(parameterElts[0].parameterKind, ParameterKind.NAMED)) {
+        // Named parameters, consider the names when matching the parameterElts to the overriddenParameterElts
         for (int i = 0; i < parameterElts.length; i++) {
           ParameterElementImpl parameterElt = parameterElts[i];
           EvaluationResultImpl result = parameterElt.evaluationResult;
-          if (result == null || identical(result, ValidResult.RESULT_OBJECT)) {
+          // TODO (jwren) Ignore Object types, see Dart bug 11287
+          if (isUserDefinedObject(result)) {
             continue;
           }
           String parameterName = parameterElt.name;
@@ -15524,11 +17126,11 @@
             String overriddenParameterName = overriddenParameterElt.name;
             if (parameterName != null && parameterName == overriddenParameterName) {
               EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
-              if (overriddenResult == null || identical(result, ValidResult.RESULT_OBJECT)) {
+              if (isUserDefinedObject(overriddenResult)) {
                 break;
               }
-              if (!result.equalValues(overriddenResult)) {
-                _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [
+              if (!result.equalValues(_typeProvider, overriddenResult)) {
+                _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [
                     overriddenExecutable.enclosingElement.displayName,
                     overriddenExecutable.displayName,
                     parameterName]);
@@ -15538,19 +17140,21 @@
           }
         }
       } else {
+        // Positional parameters, consider the positions when matching the parameterElts to the overriddenParameterElts
         for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.length; i++) {
           ParameterElementImpl parameterElt = parameterElts[i];
           EvaluationResultImpl result = parameterElt.evaluationResult;
-          if (result == null || identical(result, ValidResult.RESULT_OBJECT)) {
+          // TODO (jwren) Ignore Object types, see Dart bug 11287
+          if (isUserDefinedObject(result)) {
             continue;
           }
           ParameterElementImpl overriddenParameterElt = overriddenParameterElts[i];
           EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
-          if (overriddenResult == null || identical(result, ValidResult.RESULT_OBJECT)) {
+          if (isUserDefinedObject(overriddenResult)) {
             continue;
           }
-          if (!result.equalValues(overriddenResult)) {
-            _errorReporter.reportError2(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [
+          if (!result.equalValues(_typeProvider, overriddenResult)) {
+            _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [
                 overriddenExecutable.enclosingElement.displayName,
                 overriddenExecutable.displayName]);
             foundError = true;
@@ -15658,35 +17262,53 @@
    * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR
    */
   bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) {
+    //
+    // Prepare redirected constructor node
+    //
     ConstructorName redirectedConstructor = node.redirectedConstructor;
     if (redirectedConstructor == null) {
       return false;
     }
+    //
+    // Prepare redirected constructor type
+    //
     ConstructorElement redirectedElement = redirectedConstructor.staticElement;
     if (redirectedElement == null) {
+      //
+      // If the element is null, we check for the REDIRECT_TO_MISSING_CONSTRUCTOR case
+      //
       TypeName constructorTypeName = redirectedConstructor.type;
       Type2 redirectedType = constructorTypeName.type;
       if (redirectedType != null && redirectedType.element != null && !redirectedType.isDynamic) {
+        //
+        // Prepare the constructor name
+        //
         String constructorStrName = constructorTypeName.name.name;
         if (redirectedConstructor.name != null) {
           constructorStrName += ".${redirectedConstructor.name.name}";
         }
         ErrorCode errorCode = (node.constKeyword != null ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR) as ErrorCode;
-        _errorReporter.reportError2(errorCode, redirectedConstructor, [constructorStrName, redirectedType.displayName]);
+        _errorReporter.reportError3(errorCode, redirectedConstructor, [constructorStrName, redirectedType.displayName]);
         return true;
       }
       return false;
     }
     FunctionType redirectedType = redirectedElement.type;
     Type2 redirectedReturnType = redirectedType.returnType;
+    //
+    // Report specific problem when return type is incompatible
+    //
     FunctionType constructorType = node.element.type;
     Type2 constructorReturnType = constructorType.returnType;
     if (!redirectedReturnType.isAssignableTo(constructorReturnType)) {
-      _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]);
+      _errorReporter.reportError3(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]);
       return true;
     }
+    //
+    // Check parameters
+    //
     if (!redirectedType.isSubtypeOf(constructorType)) {
-      _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, redirectedConstructor, [redirectedType, constructorType]);
+      _errorReporter.reportError3(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, redirectedConstructor, [redirectedType, constructorType]);
       return true;
     }
     return false;
@@ -15713,21 +17335,24 @@
     FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
     Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
     Expression returnExpression = node.expression;
+    // RETURN_IN_GENERATIVE_CONSTRUCTOR
     bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !(_enclosingFunction as ConstructorElement).isFactory;
     if (isGenerativeConstructor) {
       if (returnExpression == null) {
         return false;
       }
-      _errorReporter.reportError2(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, returnExpression, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, returnExpression, []);
       return true;
     }
+    // RETURN_WITHOUT_VALUE
     if (returnExpression == null) {
       if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) {
         return false;
       }
-      _errorReporter.reportError2(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
+      _errorReporter.reportError3(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
       return true;
     }
+    // RETURN_OF_INVALID_TYPE
     return checkForReturnOfInvalidType(returnExpression, expectedReturnType);
   }
 
@@ -15740,14 +17365,17 @@
    * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT
    */
   bool checkForAmbiguousExport(ExportDirective node) {
+    // prepare ExportElement
     if (node.element is! ExportElement) {
       return false;
     }
     ExportElement exportElement = node.element as ExportElement;
+    // prepare exported library
     LibraryElement exportedLibrary = exportElement.exportedLibrary;
     if (exportedLibrary == null) {
       return false;
     }
+    // check exported names
     Namespace namespace = new NamespaceBuilder().createExportNamespace(exportElement);
     Map<String, Element> definedNames = namespace.definedNames;
     for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames)) {
@@ -15755,7 +17383,7 @@
       Element element = definedEntry.getValue();
       Element prevElement = _exportedElements[name];
       if (element != null && prevElement != null && prevElement != element) {
-        _errorReporter.reportError2(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
+        _errorReporter.reportError3(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
             name,
             prevElement.library.definingCompilationUnit.displayName,
             element.library.definingCompilationUnit.displayName]);
@@ -15778,7 +17406,7 @@
     SimpleIdentifier identifier = node.identifier;
     Element element = identifier.staticElement;
     if (element != null && element is! ParameterElement) {
-      _errorReporter.reportError2(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER, identifier, [identifier.name]);
+      _errorReporter.reportError3(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER, identifier, [identifier.name]);
       return true;
     }
     return false;
@@ -15799,6 +17427,7 @@
     for (Expression argument in argumentList.arguments) {
       problemReported = javaBooleanOr(problemReported, checkForArgumentTypeNotAssignable2(argument));
     }
+    // done
     return problemReported;
   }
 
@@ -15844,13 +17473,16 @@
    * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
    */
   bool checkForArgumentTypeNotAssignable4(Expression expression, Type2 expectedStaticType, Type2 actualStaticType, Type2 expectedPropagatedType, Type2 actualPropagatedType, ErrorCode errorCode) {
+    //
+    // Test static type information
+    //
     if (actualStaticType == null || expectedStaticType == null) {
       return false;
     }
     if (actualStaticType.isAssignableTo(expectedStaticType)) {
       return false;
     }
-    _errorReporter.reportError2(errorCode, expression, [
+    _errorReporter.reportError3(errorCode, expression, [
         actualStaticType.displayName,
         expectedStaticType.displayName]);
     return true;
@@ -15878,13 +17510,15 @@
    * @see StaticWarningCode#ASSIGNMENT_TO_METHOD
    */
   bool checkForAssignmentToFinal2(Expression expression) {
+    // prepare element
     Element element = null;
     if (expression is Identifier) {
-      element = (expression as Identifier).staticElement;
+      element = expression.staticElement;
     }
     if (expression is PropertyAccess) {
-      element = (expression as PropertyAccess).propertyName.staticElement;
+      element = expression.propertyName.staticElement;
     }
+    // check if element is assignable
     if (element is PropertyAccessorElement) {
       PropertyAccessorElement accessor = element as PropertyAccessorElement;
       element = accessor.variable;
@@ -15892,17 +17526,17 @@
     if (element is VariableElement) {
       VariableElement variable = element as VariableElement;
       if (variable.isConst) {
-        _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_CONST, expression, []);
+        _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_CONST, expression, []);
         return true;
       }
       if (variable.isFinal) {
-        _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expression, []);
+        _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_FINAL, expression, []);
         return true;
       }
       return false;
     }
     if (element is MethodElement) {
-      _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_METHOD, expression, []);
+      _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_METHOD, expression, []);
       return true;
     }
     return false;
@@ -15926,7 +17560,7 @@
   bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode errorCode) {
     sc.Token token = identifier.token;
     if (identical(token.type, sc.TokenType.KEYWORD)) {
-      _errorReporter.reportError2(errorCode, identifier, [identifier.name]);
+      _errorReporter.reportError3(errorCode, identifier, [identifier.name]);
       return true;
     }
     return false;
@@ -15943,9 +17577,10 @@
   bool checkForCaseBlockNotTerminated(SwitchCase node) {
     NodeList<Statement> statements = node.statements;
     if (statements.isEmpty) {
+      // fall-through without statements at all
       ASTNode parent = node.parent;
       if (parent is SwitchStatement) {
-        SwitchStatement switchStatement = parent as SwitchStatement;
+        SwitchStatement switchStatement = parent;
         NodeList<SwitchMember> members = switchStatement.members;
         int index = members.indexOf(node);
         if (index != -1 && index < members.length - 1) {
@@ -15954,17 +17589,20 @@
       }
     } else {
       Statement statement = statements[statements.length - 1];
+      // terminated with statement
       if (statement is BreakStatement || statement is ContinueStatement || statement is ReturnStatement) {
         return false;
       }
+      // terminated with 'throw' expression
       if (statement is ExpressionStatement) {
-        Expression expression = (statement as ExpressionStatement).expression;
+        Expression expression = statement.expression;
         if (expression is ThrowExpression) {
           return false;
         }
       }
     }
-    _errorReporter.reportError5(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword, []);
+    // report error
+    _errorReporter.reportError6(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword, []);
     return true;
   }
 
@@ -15983,7 +17621,7 @@
     for (int i = 0; i < lastMember; i++) {
       SwitchMember member = members[i];
       if (member is SwitchCase) {
-        foundError = javaBooleanOr(foundError, checkForCaseBlockNotTerminated(member as SwitchCase));
+        foundError = javaBooleanOr(foundError, checkForCaseBlockNotTerminated(member));
       }
     }
     return foundError;
@@ -16002,7 +17640,8 @@
     if (!implementsEqualsWhenNotAllowed(type)) {
       return false;
     }
-    _errorReporter.reportError5(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, node.keyword, [type.displayName]);
+    // report error
+    _errorReporter.reportError6(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, node.keyword, [type.displayName]);
     return true;
   }
 
@@ -16017,7 +17656,7 @@
   bool checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
     if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstract) {
       SimpleIdentifier methodName = node.name;
-      _errorReporter.reportError2(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, methodName, [methodName.name, _enclosingClass.displayName]);
+      _errorReporter.reportError3(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, methodName, [methodName.name, _enclosingClass.displayName]);
       return true;
     }
     return false;
@@ -16039,6 +17678,7 @@
     SimpleIdentifier constructorName = node.name;
     String name = constructorElement.name;
     ClassElement classElement = constructorElement.enclosingElement;
+    // constructors
     List<ConstructorElement> constructors = classElement.constructors;
     for (ConstructorElement otherConstructor in constructors) {
       if (identical(otherConstructor, constructorElement)) {
@@ -16046,27 +17686,26 @@
       }
       if (name == otherConstructor.name) {
         if (name == null || name.length == 0) {
-          _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node, []);
+          _errorReporter.reportError3(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node, []);
         } else {
-          _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]);
+          _errorReporter.reportError3(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]);
         }
         return true;
       }
     }
+    // conflict with class member
     if (constructorName != null && constructorElement != null && !constructorName.isSynthetic) {
-      List<FieldElement> fields = classElement.fields;
-      for (FieldElement field in fields) {
-        if (field.name == name) {
-          _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name]);
-          return true;
-        }
+      // fields
+      FieldElement field = classElement.getField(name);
+      if (field != null) {
+        _errorReporter.reportError3(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name]);
+        return true;
       }
-      List<MethodElement> methods = classElement.methods;
-      for (MethodElement method in methods) {
-        if (method.name == name) {
-          _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name]);
-          return true;
-        }
+      // methods
+      MethodElement method = classElement.getMethod(name);
+      if (method != null) {
+        _errorReporter.reportError3(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name]);
+        return true;
       }
     }
     return false;
@@ -16085,33 +17724,40 @@
       return false;
     }
     bool hasProblem = false;
+    // method declared in the enclosing class vs. inherited getter
     for (MethodElement method in _enclosingClass.methods) {
       String name = method.name;
+      // find inherited property accessor (and can be only getter)
       ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclosingClass, name);
       if (inherited is! PropertyAccessorElement) {
         continue;
       }
+      // report problem
       hasProblem = true;
-      _errorReporter.reportError4(CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method.nameOffset, name.length, [
+      _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method.nameOffset, name.length, [
           _enclosingClass.displayName,
           inherited.enclosingElement.displayName,
           name]);
     }
+    // getter declared in the enclosing class vs. inherited method
     for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
       if (!accessor.isGetter) {
         continue;
       }
       String name = accessor.name;
+      // find inherited method
       ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclosingClass, name);
       if (inherited is! MethodElement) {
         continue;
       }
+      // report problem
       hasProblem = true;
-      _errorReporter.reportError4(CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor.nameOffset, name.length, [
+      _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor.nameOffset, name.length, [
           _enclosingClass.displayName,
           inherited.enclosingElement.displayName,
           name]);
     }
+    // done
     return hasProblem;
   }
 
@@ -16130,16 +17776,21 @@
       return false;
     }
     InterfaceType enclosingType = _enclosingClass.type;
+    // check every accessor
     bool hasProblem = false;
     for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
+      // we analyze instance accessors here
       if (accessor.isStatic) {
         continue;
       }
+      // prepare accessor properties
       String name = accessor.displayName;
       bool getter = accessor.isGetter;
+      // if non-final variable, ignore setter - we alreay reported problem for getter
       if (accessor.isSetter && accessor.isSynthetic) {
         continue;
       }
+      // try to find super element
       ExecutableElement superElement;
       superElement = enclosingType.lookUpGetterInSuperclass(name, _currentLibrary);
       if (superElement == null) {
@@ -16151,18 +17802,22 @@
       if (superElement == null) {
         continue;
       }
+      // OK, not static
       if (!superElement.isStatic) {
         continue;
       }
+      // prepare "super" type to report its name
       ClassElement superElementClass = superElement.enclosingElement as ClassElement;
       InterfaceType superElementType = superElementClass.type;
+      // report problem
       hasProblem = true;
       if (getter) {
-        _errorReporter.reportError3(StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
+        _errorReporter.reportError4(StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
       } else {
-        _errorReporter.reportError3(StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
+        _errorReporter.reportError4(StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
       }
     }
+    // done
     return hasProblem;
   }
 
@@ -16178,19 +17833,23 @@
     if (node.isStatic) {
       return false;
     }
+    // prepare name
     SimpleIdentifier nameNode = node.name;
     if (nameNode == null) {
       return false;
     }
     String name = nameNode.name;
+    // ensure that we have enclosing class
     if (_enclosingClass == null) {
       return false;
     }
+    // try to find setter
     ExecutableElement setter = _inheritanceManager.lookupMember(_enclosingClass, "${name}=");
     if (setter == null) {
       return false;
     }
-    _errorReporter.reportError2(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, nameNode, [
+    // report problem
+    _errorReporter.reportError3(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, nameNode, [
         _enclosingClass.displayName,
         name,
         setter.enclosingElement.displayName]);
@@ -16209,25 +17868,31 @@
     if (!node.isStatic) {
       return false;
     }
+    // prepare name
     SimpleIdentifier nameNode = node.name;
     if (nameNode == null) {
       return false;
     }
     String name = nameNode.name;
+    // prepare enclosing type
     if (_enclosingClass == null) {
       return false;
     }
     InterfaceType enclosingType = _enclosingClass.type;
+    // try to find setter
     ExecutableElement setter = enclosingType.lookUpSetter(name, _currentLibrary);
     if (setter == null) {
       return false;
     }
+    // OK, also static
     if (setter.isStatic) {
       return false;
     }
+    // prepare "setter" type to report its name
     ClassElement setterClass = setter.enclosingElement as ClassElement;
     InterfaceType setterType = setterClass.type;
-    _errorReporter.reportError2(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, nameNode, [setterType.displayName]);
+    // report problem
+    _errorReporter.reportError3(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, nameNode, [setterType.displayName]);
     return true;
   }
 
@@ -16243,15 +17908,18 @@
     if (!node.isStatic) {
       return false;
     }
+    // prepare name
     SimpleIdentifier nameNode = node.name;
     if (nameNode == null) {
       return false;
     }
     String name = nameNode.name;
+    // prepare enclosing type
     if (_enclosingClass == null) {
       return false;
     }
     InterfaceType enclosingType = _enclosingClass.type;
+    // try to find member
     ExecutableElement member;
     member = enclosingType.lookUpMethod(name, _currentLibrary);
     if (member == null) {
@@ -16263,12 +17931,15 @@
     if (member == null) {
       return false;
     }
+    // OK, also static
     if (member.isStatic) {
       return false;
     }
+    // prepare "member" type to report its name
     ClassElement memberClass = member.enclosingElement as ClassElement;
     InterfaceType memberType = memberClass.type;
-    _errorReporter.reportError2(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, nameNode, [memberType.displayName]);
+    // report problem
+    _errorReporter.reportError3(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, nameNode, [memberType.displayName]);
     return true;
   }
 
@@ -16284,12 +17955,14 @@
     bool problemReported = false;
     for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) {
       String name = typeParameter.name;
+      // name is same as the name of the enclosing class
       if (_enclosingClass.name == name) {
-        _errorReporter.reportError4(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, typeParameter.nameOffset, name.length, [name]);
+        _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, typeParameter.nameOffset, name.length, [name]);
         problemReported = true;
       }
+      // check members
       if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(name) != null || _enclosingClass.getSetter(name) != null) {
-        _errorReporter.reportError4(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]);
+        _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]);
         problemReported = true;
       }
     }
@@ -16308,20 +17981,23 @@
     if (!_isEnclosingConstructorConst) {
       return false;
     }
+    // OK, const factory, checked elsewhere
     if (node.factoryKeyword != null) {
       return false;
     }
+    // try to find and check super constructor invocation
     for (ConstructorInitializer initializer in node.initializers) {
       if (initializer is SuperConstructorInvocation) {
-        SuperConstructorInvocation superInvocation = initializer as SuperConstructorInvocation;
+        SuperConstructorInvocation superInvocation = initializer;
         ConstructorElement element = superInvocation.staticElement;
         if (element == null || element.isConst) {
           return false;
         }
-        _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, superInvocation, []);
+        _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, superInvocation, []);
         return true;
       }
     }
+    // no explicit super constructor invocation, check default constructor
     InterfaceType supertype = _enclosingClass.supertype;
     if (supertype == null) {
       return false;
@@ -16336,7 +18012,8 @@
     if (unnamedConstructor.isConst) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, node, []);
+    // default constructor is not 'const', report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, node, []);
     return true;
   }
 
@@ -16352,12 +18029,14 @@
     if (!_isEnclosingConstructorConst) {
       return false;
     }
+    // check if there is non-final field
     ConstructorElement constructorElement = node.element;
     ClassElement classElement = constructorElement.enclosingElement;
     if (!classElement.hasNonFinalField()) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node, []);
+    // report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node, []);
     return true;
   }
 
@@ -16371,7 +18050,7 @@
    */
   bool checkForConstEvalThrowsException(ThrowExpression node) {
     if (_isEnclosingConstructorConst) {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node, []);
       return true;
     }
     return false;
@@ -16386,7 +18065,7 @@
    */
   bool checkForConstFormalParameter(NormalFormalParameter node) {
     if (node.isConst) {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node, []);
       return true;
     }
     return false;
@@ -16405,7 +18084,8 @@
     if (!implementsEqualsWhenNotAllowed(type)) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, key, [type.displayName]);
+    // report error
+    _errorReporter.reportError3(CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, key, [type.displayName]);
     return true;
   }
 
@@ -16418,9 +18098,11 @@
    * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
    */
   bool checkForConstMapKeyExpressionTypeImplementsEquals2(MapLiteral node) {
+    // OK, not const.
     if (node.constKeyword == null) {
       return false;
     }
+    // Check every map entry.
     bool hasProblems = false;
     for (MapLiteralEntry entry in node.entries) {
       Expression key = entry.key;
@@ -16446,9 +18128,9 @@
       ConstructorElement element = node.staticElement;
       if (element != null && !element.isFactory) {
         if (identical((node.keyword as sc.KeywordToken).keyword, sc.Keyword.CONST)) {
-          _errorReporter.reportError2(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
+          _errorReporter.reportError3(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
         } else {
-          _errorReporter.reportError2(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
+          _errorReporter.reportError3(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
         }
         return true;
       }
@@ -16469,7 +18151,7 @@
   bool checkForConstWithNonConst(InstanceCreationExpression node) {
     ConstructorElement constructorElement = node.staticElement;
     if (constructorElement != null && !constructorElement.isConst) {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_NON_CONST, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_NON_CONST, node, []);
       return true;
     }
     return false;
@@ -16502,6 +18184,7 @@
    * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
    */
   bool checkForConstWithTypeParameters2(TypeName typeName) {
+    // something wrong with AST
     if (typeName == null) {
       return false;
     }
@@ -16509,9 +18192,11 @@
     if (name == null) {
       return false;
     }
+    // should not be a type parameter
     if (name.staticElement is TypeParameterElement) {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name, []);
     }
+    // check type arguments
     TypeArgumentList typeArguments = typeName.typeArguments;
     if (typeArguments != null) {
       bool hasError = false;
@@ -16520,6 +18205,7 @@
       }
       return hasError;
     }
+    // OK
     return false;
   }
 
@@ -16535,23 +18221,27 @@
    * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
    */
   bool checkForConstWithUndefinedConstructor(InstanceCreationExpression node) {
+    // OK if resolved
     if (node.staticElement != null) {
       return false;
     }
+    // prepare constructor name
     ConstructorName constructorName = node.constructorName;
     if (constructorName == null) {
       return false;
     }
+    // prepare class name
     TypeName type = constructorName.type;
     if (type == null) {
       return false;
     }
     Identifier className = type.name;
+    // report as named or default constructor absence
     SimpleIdentifier name = constructorName.name;
     if (name != null) {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
     } else {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
     }
     return true;
   }
@@ -16569,9 +18259,9 @@
     NodeList<FormalParameter> parameters = formalParameterList.parameters;
     for (FormalParameter formalParameter in parameters) {
       if (formalParameter is DefaultFormalParameter) {
-        DefaultFormalParameter defaultFormalParameter = formalParameter as DefaultFormalParameter;
+        DefaultFormalParameter defaultFormalParameter = formalParameter;
         if (defaultFormalParameter.defaultValue != null) {
-          _errorReporter.reportError2(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node, []);
+          _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node, []);
           result = true;
         }
       }
@@ -16588,13 +18278,16 @@
    * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
    */
   bool checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node) {
+    // OK, not in a function typed parameter.
     if (!_isInFunctionTypedFormalParameter) {
       return false;
     }
+    // OK, no default value.
     if (node.defaultValue == null) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node, []);
+    // Report problem.
+    _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node, []);
     return true;
   }
 
@@ -16634,18 +18327,22 @@
    * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE
    */
   bool checkForDuplicateDefinitionInheritance2(ExecutableElement staticMember) {
+    // prepare name
     String name = staticMember.name;
     if (name == null) {
       return false;
     }
+    // try to find member
     ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_enclosingClass, name);
     if (inheritedMember == null) {
       return false;
     }
+    // OK, also static
     if (inheritedMember.isStatic) {
       return false;
     }
-    _errorReporter.reportError4(CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, staticMember.nameOffset, name.length, [name, inheritedMember.enclosingElement.displayName]);
+    // report problem
+    _errorReporter.reportError5(CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, staticMember.nameOffset, name.length, [name, inheritedMember.enclosingElement.displayName]);
     return true;
   }
 
@@ -16657,15 +18354,18 @@
    * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS
    */
   bool checkForExpectedOneListTypeArgument(ListLiteral node) {
+    // prepare type arguments
     TypeArgumentList typeArguments = node.typeArguments;
     if (typeArguments == null) {
       return false;
     }
+    // check number of type arguments
     int num = typeArguments.arguments.length;
     if (num == 1) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [num]);
+    // report problem
+    _errorReporter.reportError3(StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [num]);
     return true;
   }
 
@@ -16677,20 +18377,23 @@
    * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME
    */
   bool checkForExportDuplicateLibraryName(ExportDirective node) {
+    // prepare import element
     Element nodeElement = node.element;
     if (nodeElement is! ExportElement) {
       return false;
     }
     ExportElement nodeExportElement = nodeElement as ExportElement;
+    // prepare exported library
     LibraryElement nodeLibrary = nodeExportElement.exportedLibrary;
     if (nodeLibrary == null) {
       return false;
     }
     String name = nodeLibrary.name;
+    // check if there is other exported library with the same name
     LibraryElement prevLibrary = _nameToExportElement[name];
     if (prevLibrary != null) {
       if (prevLibrary != nodeLibrary) {
-        _errorReporter.reportError2(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAME, node, [
+        _errorReporter.reportError3(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAME, node, [
             prevLibrary.definingCompilationUnit.displayName,
             nodeLibrary.definingCompilationUnit.displayName,
             name]);
@@ -16699,6 +18402,7 @@
     } else {
       _nameToExportElement[name] = nodeLibrary;
     }
+    // OK
     return false;
   }
 
@@ -16714,11 +18418,13 @@
     if (_isInSystemLibrary) {
       return false;
     }
+    // prepare export element
     Element element = node.element;
     if (element is! ExportElement) {
       return false;
     }
     ExportElement exportElement = element as ExportElement;
+    // should be private
     DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
     String uri = exportElement.uri;
     SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
@@ -16728,7 +18434,8 @@
     if (!sdkLibrary.isInternal) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]);
+    // report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]);
     return true;
   }
 
@@ -16764,17 +18471,24 @@
     Type2 superType = typeName.type;
     for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT) {
       if (superType != null && superType == disallowedType) {
+        // if the violating type happens to be 'num', we need to rule out the case where the
+        // enclosing class is 'int' or 'double'
         if (superType == _typeProvider.numType) {
           ASTNode grandParent = typeName.parent.parent;
+          // Note: this is a corner case that won't happen often, so adding a field currentClass
+          // (see currentFunction) to ErrorVerifier isn't worth if for this case, but if the field
+          // currentClass is added, then this message should become a todo to not lookup the
+          // grandparent node
           if (grandParent is ClassDeclaration) {
-            ClassElement classElement = (grandParent as ClassDeclaration).element;
+            ClassElement classElement = grandParent.element;
             Type2 classType = classElement.type;
             if (classType != null && (classType == _typeProvider.intType || classType == _typeProvider.doubleType)) {
               return false;
             }
           }
         }
-        _errorReporter.reportError2(errorCode, typeName, [disallowedType.displayName]);
+        // otherwise, report the error
+        _errorReporter.reportError3(errorCode, typeName, [disallowedType.displayName]);
         return true;
       }
     }
@@ -16791,16 +18505,20 @@
    * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE
    */
   bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) {
+    // prepare field element
     Element fieldNameElement = node.fieldName.staticElement;
     if (fieldNameElement is! FieldElement) {
       return false;
     }
     FieldElement fieldElement = fieldNameElement as FieldElement;
+    // prepare field type
     Type2 fieldType = fieldElement.type;
+    // prepare expression type
     Expression expression = node.expression;
     if (expression == null) {
       return false;
     }
+    // test the static type of the expression
     Type2 staticType = getStaticType(expression);
     if (staticType == null) {
       return false;
@@ -16808,10 +18526,11 @@
     if (staticType.isAssignableTo(fieldType)) {
       return false;
     }
+    // report problem
     if (_isEnclosingConstructorConst) {
-      _errorReporter.reportError2(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]);
+      _errorReporter.reportError3(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]);
     } else {
-      _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]);
+      _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]);
     }
     return true;
   }
@@ -16826,19 +18545,22 @@
   bool checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParameter node) {
     ConstructorDeclaration constructor = node.getAncestor(ConstructorDeclaration);
     if (constructor == null) {
-      _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node, []);
       return true;
     }
+    // constructor cannot be a factory
     if (constructor.factoryKeyword != null) {
-      _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node, []);
       return true;
     }
+    // constructor cannot have a redirection
     for (ConstructorInitializer initializer in constructor.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
-        _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, node, []);
+        _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, node, []);
         return true;
       }
     }
+    // OK
     return false;
   }
 
@@ -16862,7 +18584,7 @@
     bool foundError = false;
     for (ClassMember classMember in classMembers) {
       if (classMember is FieldDeclaration) {
-        FieldDeclaration field = classMember as FieldDeclaration;
+        FieldDeclaration field = classMember;
         foundError = javaBooleanOr(foundError, checkForFinalNotInitialized2(field.fields));
       }
     }
@@ -16891,9 +18613,9 @@
       for (VariableDeclaration variable in variables) {
         if (variable.initializer == null) {
           if (node.isConst) {
-            _errorReporter.reportError2(CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [variable.name.name]);
+            _errorReporter.reportError3(CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [variable.name.name]);
           } else if (node.isFinal) {
-            _errorReporter.reportError2(StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [variable.name.name]);
+            _errorReporter.reportError3(StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [variable.name.name]);
           }
           foundError = true;
         }
@@ -16934,44 +18656,51 @@
     if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInInstanceVariableInitializer && !_isInStaticVariableDeclaration) {
       return false;
     }
+    // prepare element
     Element element = node.staticElement;
     if (!(element is MethodElement || element is PropertyAccessorElement)) {
       return false;
     }
+    // static element
     ExecutableElement executableElement = element as ExecutableElement;
     if (executableElement.isStatic) {
       return false;
     }
+    // not a class member
     Element enclosingElement = element.enclosingElement;
     if (enclosingElement is! ClassElement) {
       return false;
     }
+    // comment
     ASTNode parent = node.parent;
     if (parent is CommentReference) {
       return false;
     }
+    // qualified method invocation
     if (parent is MethodInvocation) {
-      MethodInvocation invocation = parent as MethodInvocation;
+      MethodInvocation invocation = parent;
       if (identical(invocation.methodName, node) && invocation.realTarget != null) {
         return false;
       }
     }
+    // qualified property access
     if (parent is PropertyAccess) {
-      PropertyAccess access = parent as PropertyAccess;
+      PropertyAccess access = parent;
       if (identical(access.propertyName, node) && access.realTarget != null) {
         return false;
       }
     }
     if (parent is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
+      PrefixedIdentifier prefixed = parent;
       if (identical(prefixed.identifier, node)) {
         return false;
       }
     }
+    // report problem
     if (_isInStaticMethod) {
-      _errorReporter.reportError2(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node, []);
     } else {
-      _errorReporter.reportError2(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node, []);
     }
     return true;
   }
@@ -16984,19 +18713,22 @@
    * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME
    */
   bool checkForImportDuplicateLibraryName(ImportDirective node) {
+    // prepare import element
     ImportElement nodeImportElement = node.element;
     if (nodeImportElement == null) {
       return false;
     }
+    // prepare imported library
     LibraryElement nodeLibrary = nodeImportElement.importedLibrary;
     if (nodeLibrary == null) {
       return false;
     }
     String name = nodeLibrary.name;
+    // check if there is other imported library with the same name
     LibraryElement prevLibrary = _nameToImportElement[name];
     if (prevLibrary != null) {
       if (prevLibrary != nodeLibrary) {
-        _errorReporter.reportError2(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAME, node, [
+        _errorReporter.reportError3(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAME, node, [
             prevLibrary.definingCompilationUnit.displayName,
             nodeLibrary.definingCompilationUnit.displayName,
             name]);
@@ -17005,6 +18737,7 @@
     } else {
       _nameToImportElement[name] = nodeLibrary;
     }
+    // OK
     return false;
   }
 
@@ -17020,10 +18753,12 @@
     if (_isInSystemLibrary) {
       return false;
     }
+    // prepare import element
     ImportElement importElement = node.element;
     if (importElement == null) {
       return false;
     }
+    // should be private
     DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
     String uri = importElement.uri;
     SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
@@ -17033,7 +18768,8 @@
     if (!sdkLibrary.isInternal) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]);
+    // report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]);
     return true;
   }
 
@@ -17045,19 +18781,23 @@
    * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES
    */
   bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) {
+    // TODO(jwren) Revisit this algorithm, should there up to n-1 errors?
     NodeList<SwitchMember> switchMembers = node.members;
     bool foundError = false;
     Type2 firstType = null;
     for (SwitchMember switchMember in switchMembers) {
       if (switchMember is SwitchCase) {
-        SwitchCase switchCase = switchMember as SwitchCase;
+        SwitchCase switchCase = switchMember;
         Expression expression = switchCase.expression;
         if (firstType == null) {
+          // TODO(brianwilkerson) This is failing with const variables whose declared type is
+          // dynamic. The problem is that we don't have any way to propagate type information for
+          // the variable.
           firstType = expression.bestType;
         } else {
           Type2 nType = expression.bestType;
           if (firstType != nType) {
-            _errorReporter.reportError2(CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName]);
+            _errorReporter.reportError3(CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName]);
             foundError = true;
           }
         }
@@ -17077,6 +18817,8 @@
    * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE
    */
   bool checkForInconsistentMethodInheritance() {
+    // Ensure that the inheritance manager has a chance to generate all errors we may care about,
+    // note that we ensure that the interfaces data since there are no errors.
     _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
     Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass);
     if (errors == null || errors.isEmpty) {
@@ -17100,24 +18842,30 @@
    * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER
    */
   bool checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleIdentifier name) {
+    // OK, in comment
     if (_isInComment) {
       return false;
     }
+    // OK, target is a type
     if (typeReference != null) {
       return false;
     }
+    // prepare member Element
     Element element = name.staticElement;
     if (element is! ExecutableElement) {
       return false;
     }
     ExecutableElement executableElement = element as ExecutableElement;
+    // OK, top-level element
     if (executableElement.enclosingElement is! ClassElement) {
       return false;
     }
+    // OK, instance member
     if (!executableElement.isStatic) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [name.name]);
+    // report problem
+    _errorReporter.reportError3(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [name.name]);
     return true;
   }
 
@@ -17165,7 +18913,7 @@
       return false;
     }
     if (!rightType.isAssignableTo(leftType)) {
-      _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightType.displayName, leftType.displayName]);
+      _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightType.displayName, leftType.displayName]);
       return true;
     }
     return false;
@@ -17188,9 +18936,20 @@
     Type2 staticRightType = getStaticType(rhs);
     bool isStaticAssignable = staticRightType.isAssignableTo(leftType);
     if (!isStaticAssignable) {
-      _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [staticRightType.displayName, leftType.displayName]);
+      _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [staticRightType.displayName, leftType.displayName]);
       return true;
     }
+    // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate.
+    //    Type propagatedRightType = rhs.getPropagatedType();
+    //    boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType);
+    //    if (!isStaticAssignable && !isPropagatedAssignable) {
+    //      errorReporter.reportError(
+    //          StaticTypeWarningCode.INVALID_ASSIGNMENT,
+    //          rhs,
+    //          staticRightType.getDisplayName(),
+    //          leftType.getDisplayName());
+    //      return true;
+    //    }
     return false;
   }
 
@@ -17203,7 +18962,7 @@
    */
   bool checkForInvalidReferenceToThis(ThisExpression node) {
     if (!isThisInValidContext(node)) {
-      _errorReporter.reportError2(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node, []);
       return true;
     }
     return false;
@@ -17223,7 +18982,7 @@
     bool foundError = false;
     for (TypeName typeName in arguments) {
       if (typeName.type is TypeParameterType) {
-        _errorReporter.reportError2(errorCode, typeName, [typeName.name]);
+        _errorReporter.reportError3(errorCode, typeName, [typeName.name]);
         foundError = true;
       }
     }
@@ -17240,6 +18999,7 @@
    * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
    */
   bool checkForListElementTypeNotAssignable(ListLiteral node) {
+    // Prepare list element type.
     TypeArgumentList typeArgumentList = node.typeArguments;
     if (typeArgumentList == null) {
       return false;
@@ -17249,12 +19009,14 @@
       return false;
     }
     Type2 listElementType = typeArguments[0].type;
+    // Prepare problem to report.
     ErrorCode errorCode;
     if (node.constKeyword != null) {
       errorCode = CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE;
     } else {
       errorCode = StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE;
     }
+    // Check every list element.
     bool hasProblems = false;
     for (Expression element in node.elements) {
       hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable3(element, listElementType, null, errorCode));
@@ -17274,6 +19036,7 @@
    * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
    */
   bool checkForMapTypeNotAssignable(MapLiteral node) {
+    // Prepare maps key/value types.
     TypeArgumentList typeArgumentList = node.typeArguments;
     if (typeArgumentList == null) {
       return false;
@@ -17284,6 +19047,7 @@
     }
     Type2 keyType = typeArguments[0].type;
     Type2 valueType = typeArguments[1].type;
+    // Prepare problem to report.
     ErrorCode keyErrorCode;
     ErrorCode valueErrorCode;
     if (node.constKeyword != null) {
@@ -17293,6 +19057,7 @@
       keyErrorCode = StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE;
       valueErrorCode = StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE;
     }
+    // Check every map entry.
     bool hasProblems = false;
     NodeList<MapLiteralEntry> entries = node.entries;
     for (MapLiteralEntry entry in entries) {
@@ -17320,12 +19085,15 @@
       return false;
     }
     bool problemReported = false;
+    // check accessors
     for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
       if (className == accessor.name) {
-        _errorReporter.reportError4(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, className.length, []);
+        _errorReporter.reportError5(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, className.length, []);
         problemReported = true;
       }
     }
+    // don't check methods, they would be constructors
+    // done
     return problemReported;
   }
 
@@ -17350,30 +19118,39 @@
       counterpartAccessor = propertyAccessorElement.correspondingSetter;
     } else {
       counterpartAccessor = propertyAccessorElement.correspondingGetter;
+      // If the setter and getter are in the same enclosing element, return, this prevents having
+      // MISMATCHED_GETTER_AND_SETTER_TYPES reported twice.
       if (counterpartAccessor != null && identical(counterpartAccessor.enclosingElement, propertyAccessorElement.enclosingElement)) {
         return false;
       }
     }
     if (counterpartAccessor == null) {
+      // If the accessor is declared in a class, check the superclasses.
       if (_enclosingClass != null) {
+        // Figure out the correct identifier to lookup in the inheritance graph, if 'x', then 'x=',
+        // or if 'x=', then 'x'.
         String lookupIdentifier = propertyAccessorElement.name;
         if (lookupIdentifier.endsWith("=")) {
           lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.length - 1);
         } else {
           lookupIdentifier += "=";
         }
+        // lookup with the identifier.
         ExecutableElement elementFromInheritance = _inheritanceManager.lookupInheritance(_enclosingClass, lookupIdentifier);
+        // Verify that we found something, and that it is an accessor
         if (elementFromInheritance != null && elementFromInheritance is PropertyAccessorElement) {
           enclosingClassForCounterpart = elementFromInheritance.enclosingElement as ClassElement;
-          counterpartAccessor = elementFromInheritance as PropertyAccessorElement;
+          counterpartAccessor = elementFromInheritance;
         }
       }
       if (counterpartAccessor == null) {
         return false;
       }
     }
+    // Default of null == no accessor or no type (dynamic)
     Type2 getterType = null;
     Type2 setterType = null;
+    // Get an existing counterpart accessor if any.
     if (propertyAccessorElement.isGetter) {
       getterType = getGetterType(propertyAccessorElement);
       setterType = getSetterType(counterpartAccessor);
@@ -17381,15 +19158,17 @@
       setterType = getSetterType(propertyAccessorElement);
       getterType = getGetterType(counterpartAccessor);
     }
+    // If either types are not assignable to each other, report an error (if the getter is null,
+    // it is dynamic which is assignable to everything).
     if (setterType != null && getterType != null && !getterType.isAssignableTo(setterType)) {
       if (enclosingClassForCounterpart == null) {
-        _errorReporter.reportError2(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, accessorDeclaration, [
+        _errorReporter.reportError3(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, [
+        _errorReporter.reportError3(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [
             accessorTextName,
             setterType.displayName,
             getterType.displayName,
@@ -17409,7 +19188,7 @@
    */
   bool checkForMixedReturns(BlockFunctionBody node) {
     if (_returnWithCount > 0 && _returnWithoutCount > 0) {
-      _errorReporter.reportError2(StaticWarningCode.MIXED_RETURN_TYPES, node, []);
+      _errorReporter.reportError3(StaticWarningCode.MIXED_RETURN_TYPES, node, []);
       return true;
     }
     return false;
@@ -17426,7 +19205,7 @@
   bool checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinElement) {
     for (ConstructorElement constructor in mixinElement.constructors) {
       if (!constructor.isSynthetic && !constructor.isFactory) {
-        _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [mixinElement.name]);
+        _errorReporter.reportError3(CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [mixinElement.name]);
         return true;
       }
     }
@@ -17445,7 +19224,7 @@
     InterfaceType mixinSupertype = mixinElement.supertype;
     if (mixinSupertype != null) {
       if (!mixinSupertype.isObject || !mixinElement.isTypedef && mixinElement.mixins.length != 0) {
-        _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [mixinElement.name]);
+        _errorReporter.reportError3(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [mixinElement.name]);
         return true;
       }
     }
@@ -17462,7 +19241,7 @@
    */
   bool checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinElement) {
     if (mixinElement.hasReferenceToSuper()) {
-      _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [mixinElement.name]);
+      _errorReporter.reportError3(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [mixinElement.name]);
     }
     return false;
   }
@@ -17480,7 +19259,7 @@
       if (initializer is SuperConstructorInvocation) {
         numSuperInitializers++;
         if (numSuperInitializers > 1) {
-          _errorReporter.reportError2(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer, []);
+          _errorReporter.reportError3(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer, []);
         }
       }
     }
@@ -17495,8 +19274,9 @@
    * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
    */
   bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
+    // TODO(brianwilkerson) Figure out the right rule for when 'native' is allowed.
     if (!_isInSystemLibrary) {
-      _errorReporter.reportError2(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node, []);
+      _errorReporter.reportError3(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node, []);
       return true;
     }
     return false;
@@ -17512,23 +19292,27 @@
    * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR
    */
   bool checkForNewWithUndefinedConstructor(InstanceCreationExpression node) {
+    // OK if resolved
     if (node.staticElement != null) {
       return false;
     }
+    // prepare constructor name
     ConstructorName constructorName = node.constructorName;
     if (constructorName == null) {
       return false;
     }
+    // prepare class name
     TypeName type = constructorName.type;
     if (type == null) {
       return false;
     }
     Identifier className = type.name;
+    // report as named or default constructor absence
     SimpleIdentifier name = constructorName.name;
     if (name != null) {
-      _errorReporter.reportError2(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
+      _errorReporter.reportError3(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
     } else {
-      _errorReporter.reportError2(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
+      _errorReporter.reportError3(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
     }
     return true;
   }
@@ -17542,26 +19326,30 @@
    * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
    */
   bool checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) {
+    // do nothing if there is explicit constructor
     List<ConstructorElement> constructors = _enclosingClass.constructors;
     if (!constructors[0].isSynthetic) {
       return false;
     }
+    // prepare super
     InterfaceType superType = _enclosingClass.supertype;
     if (superType == null) {
       return false;
     }
     ClassElement superElement = superType.element;
+    // try to find default generative super constructor
     ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
     if (superUnnamedConstructor != null) {
       if (superUnnamedConstructor.isFactory) {
-        _errorReporter.reportError2(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [superUnnamedConstructor]);
+        _errorReporter.reportError3(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [superUnnamedConstructor]);
         return true;
       }
       if (superUnnamedConstructor.isDefaultConstructor) {
         return true;
       }
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [superType.displayName]);
+    // report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [superType.displayName]);
     return true;
   }
 
@@ -17581,11 +19369,18 @@
     if (_enclosingClass.isAbstract) {
       return false;
     }
+    //
+    // Store in local sets the set of all method and accessor names
+    //
     List<MethodElement> methods = _enclosingClass.methods;
     List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
     Set<String> methodsInEnclosingClass = new Set<String>();
     for (MethodElement method in methods) {
       String methodName = method.name;
+      // If the enclosing class declares the method noSuchMethod(), then return.
+      // From Spec:  It is a static warning if a concrete class does not have an implementation for
+      // a method in any of its superinterfaces unless it declares its own noSuchMethod
+      // method (7.10).
       if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) {
         return false;
       }
@@ -17596,6 +19391,9 @@
       accessorsInEnclosingClass.add(accessor.name);
     }
     Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
+    //
+    // Loop through the set of all executable elements declared in the implicit interface.
+    //
     MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
     MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMembersInheritedFromClasses(_enclosingClass);
     for (int i = 0; i < membersInheritedFromInterfaces.size; i++) {
@@ -17604,24 +19402,44 @@
       if (memberName == null) {
         break;
       }
+      // If the element is defined in Object, skip it.
+      if ((executableElt.enclosingElement as ClassElement).type.isObject) {
+        continue;
+      }
+      // Reference the type of the enclosing class
+      InterfaceType enclosingType = _enclosingClass.type;
+      // Check to see if some element is in local enclosing class that matches the name of the
+      // required member.
+      if (isMemberInClassOrMixin(executableElt, _enclosingClass)) {
+        // We do not have to verify that this implementation of the found method matches the
+        // required function type: the set of StaticWarningCode.INVALID_METHOD_OVERRIDE_* warnings
+        // break out the different specific situations.
+        continue;
+      }
+      // First check to see if this element was declared in the superclass chain, in which case
+      // there is already a concrete implementation.
       ExecutableElement elt = membersInheritedFromSuperclasses.get(executableElt.name);
+      // Check to see if an element was found in the superclass chain with the correct name.
       if (elt != null) {
-        if (elt is MethodElement && !(elt as MethodElement).isAbstract) {
-          continue;
-        } else if (elt is PropertyAccessorElement && !(elt as PropertyAccessorElement).isAbstract) {
-          continue;
+        // Some element was found in the superclass chain that matches the name of the required
+        // member.
+        // If it is not abstract and it is the correct one (types match- the version of this method
+        // that we have has the correct number of parameters, etc), then this class has a valid
+        // implementation of this method, so skip it.
+        if ((elt is MethodElement && !elt.isAbstract) || (elt is PropertyAccessorElement && !elt.isAbstract)) {
+          // Since we are comparing two function types, we need to do the appropriate type
+          // substitutions first ().
+          FunctionType foundConcreteFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(elt.type, executableElt.name, enclosingType);
+          FunctionType requiredMemberFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(executableElt.type, executableElt.name, enclosingType);
+          if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) {
+            continue;
+          }
         }
       }
-      if (executableElt is MethodElement) {
-        if (!methodsInEnclosingClass.contains(memberName) && !memberHasConcreteMethodImplementationInSuperclassChain(_enclosingClass, memberName, new List<ClassElement>())) {
-          missingOverrides.add(executableElt);
-        }
-      } else if (executableElt is PropertyAccessorElement) {
-        if (!accessorsInEnclosingClass.contains(memberName) && !memberHasConcreteAccessorImplementationInSuperclassChain(_enclosingClass, memberName, new List<ClassElement>())) {
-          missingOverrides.add(executableElt);
-        }
-      }
+      // The not qualifying concrete executable element was found, add it to the list.
+      missingOverrides.add(executableElt);
     }
+    // Now that we have the set of missing overrides, generate a warning on this class
     int missingOverridesSize = missingOverrides.length;
     if (missingOverridesSize == 0) {
       return false;
@@ -17675,7 +19493,7 @@
   bool checkForNonBoolCondition(Expression condition) {
     Type2 conditionType = getStaticType(condition);
     if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
-      _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
+      _errorReporter.reportError3(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
       return true;
     }
     return false;
@@ -17693,13 +19511,13 @@
     Type2 type = getStaticType(expression);
     if (type is InterfaceType) {
       if (!type.isAssignableTo(_boolType)) {
-        _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
+        _errorReporter.reportError3(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
         return true;
       }
     } else if (type is FunctionType) {
-      FunctionType functionType = type as FunctionType;
+      FunctionType functionType = type;
       if (functionType.typeArguments.length == 0 && !functionType.returnType.isAssignableTo(_boolType)) {
-        _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
+        _errorReporter.reportError3(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
         return true;
       }
     }
@@ -17716,7 +19534,7 @@
   bool checkForNonBoolNegationExpression(Expression expression) {
     Type2 conditionType = getStaticType(expression);
     if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
-      _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
+      _errorReporter.reportError3(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
       return true;
     }
     return false;
@@ -17735,20 +19553,25 @@
    * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT
    */
   bool checkForNonConstMapAsExpressionStatement(MapLiteral node) {
+    // "const"
     if (node.constKeyword != null) {
       return false;
     }
+    // has type arguments
     if (node.typeArguments != null) {
       return false;
     }
+    // prepare statement
     Statement statement = node.getAncestor(ExpressionStatement);
     if (statement == null) {
       return false;
     }
+    // OK, statement does not start with map
     if (statement.beginToken != node.beginToken) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node, []);
+    // report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node, []);
     return true;
   }
 
@@ -17761,17 +19584,20 @@
    * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR
    */
   bool checkForNonVoidReturnTypeForOperator(MethodDeclaration node) {
+    // check that []= operator
     SimpleIdentifier name = node.name;
     if (name.name != "[]=") {
       return false;
     }
+    // check return type
     TypeName typeName = node.returnType;
     if (typeName != null) {
       Type2 type = typeName.type;
       if (type != null && !type.isVoid) {
-        _errorReporter.reportError2(StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName, []);
+        _errorReporter.reportError3(StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName, []);
       }
     }
+    // no warning
     return false;
   }
 
@@ -17786,7 +19612,7 @@
     if (typeName != null) {
       Type2 type = typeName.type;
       if (type != null && !type.isVoid) {
-        _errorReporter.reportError2(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName, []);
+        _errorReporter.reportError3(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName, []);
       }
     }
     return false;
@@ -17811,7 +19637,7 @@
     NodeList<FormalParameter> formalParameters = parameterList.parameters;
     for (FormalParameter formalParameter in formalParameters) {
       if (formalParameter.kind.isOptional) {
-        _errorReporter.reportError2(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, formalParameter, []);
+        _errorReporter.reportError3(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, formalParameter, []);
         foundError = true;
       }
     }
@@ -17826,14 +19652,17 @@
    * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER
    */
   bool checkForPrivateOptionalParameter(FormalParameter node) {
+    // should be named parameter
     if (node.kind != ParameterKind.NAMED) {
       return false;
     }
+    // name should start with '_'
     SimpleIdentifier name = node.identifier;
     if (name.isSynthetic || !name.name.startsWith("_")) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node, []);
+    // report problem
+    _errorReporter.reportError3(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node, []);
     return true;
   }
 
@@ -17846,19 +19675,24 @@
    * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT
    */
   bool checkForRecursiveConstructorRedirect(ConstructorDeclaration node) {
+    // we check generative constructor here
     if (node.factoryKeyword != null) {
       return false;
     }
+    // try to find redirecting constructor invocation and analyzer it for recursion
     for (ConstructorInitializer initializer in node.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
+        // OK if no cycle
         ConstructorElement element = node.element;
         if (!hasRedirectingFactoryConstructorCycle(element)) {
           return false;
         }
-        _errorReporter.reportError2(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer, []);
+        // report error
+        _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer, []);
         return true;
       }
     }
+    // OK, no redirecting constructor invocation
     return false;
   }
 
@@ -17871,15 +19705,18 @@
    * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT
    */
   bool checkForRecursiveFactoryRedirect(ConstructorDeclaration node) {
+    // prepare redirected constructor
     ConstructorName redirectedConstructorNode = node.redirectedConstructor;
     if (redirectedConstructorNode == null) {
       return false;
     }
+    // OK if no cycle
     ConstructorElement element = node.element;
     if (!hasRedirectingFactoryConstructorCycle(element)) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, redirectedConstructorNode, []);
+    // report error
+    _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, redirectedConstructorNode, []);
     return true;
   }
 
@@ -17910,10 +19747,14 @@
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
    */
   bool checkForRecursiveInterfaceInheritance2(ClassElement classElt, List<ClassElement> path) {
+    // Detect error condition.
     int size = path.length;
+    // If this is not the base case (size > 0), and the enclosing class is the passed class
+    // element then an error an error.
     if (size > 0 && _enclosingClass == classElt) {
       String enclosingClassName = _enclosingClass.displayName;
       if (size > 1) {
+        // Construct a string showing the cyclic implements path: "A, B, C, D, A"
         String separator = ", ";
         JavaStringBuilder builder = new JavaStringBuilder();
         for (int i = 0; i < size; i++) {
@@ -17921,12 +19762,13 @@
           builder.append(separator);
         }
         builder.append(classElt.displayName);
-        _errorReporter.reportError4(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName, builder.toString()]);
+        _errorReporter.reportError5(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName, builder.toString()]);
         return true;
       } else {
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
         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.reportError4(errorCode, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName]);
+        ErrorCode errorCode = (supertype != null && _enclosingClass == supertype.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS);
+        _errorReporter.reportError5(errorCode, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName]);
         return true;
       }
     }
@@ -17934,6 +19776,7 @@
       return false;
     }
     path.add(classElt);
+    // n-case
     InterfaceType supertype = classElt.supertype;
     if (supertype != null && checkForRecursiveInterfaceInheritance2(supertype.element, path)) {
       return true;
@@ -17961,37 +19804,43 @@
    */
   bool checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) {
     bool errorReported = false;
+    //
+    // Check for default values in the parameters
+    //
     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, []);
+        if (parameter is DefaultFormalParameter && parameter.defaultValue != null) {
+          _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []);
           errorReported = true;
         }
       }
     }
+    // check if there are redirected invocations
     int numRedirections = 0;
     for (ConstructorInitializer initializer in node.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         if (numRedirections > 0) {
-          _errorReporter.reportError2(CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, initializer, []);
+          _errorReporter.reportError3(CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, initializer, []);
           errorReported = true;
         }
         numRedirections++;
       }
     }
+    // check for other initializers
     if (numRedirections > 0) {
       for (ConstructorInitializer initializer in node.initializers) {
         if (initializer is SuperConstructorInvocation) {
-          _errorReporter.reportError2(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, initializer, []);
+          _errorReporter.reportError3(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, initializer, []);
           errorReported = true;
         }
         if (initializer is ConstructorFieldInitializer) {
-          _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, initializer, []);
+          _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, initializer, []);
           errorReported = true;
         }
       }
     }
+    // done
     return errorReported;
   }
 
@@ -18004,25 +19853,31 @@
    * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR
    */
   bool checkForRedirectToNonConstConstructor(ConstructorDeclaration node) {
+    // prepare redirected constructor
     ConstructorName redirectedConstructorNode = node.redirectedConstructor;
     if (redirectedConstructorNode == null) {
       return false;
     }
+    // prepare element
     ConstructorElement element = node.element;
     if (element == null) {
       return false;
     }
+    // OK, it is not 'const'
     if (!element.isConst) {
       return false;
     }
+    // prepare redirected constructor
     ConstructorElement redirectedConstructor = element.redirectedConstructor;
     if (redirectedConstructor == null) {
       return false;
     }
+    // OK, it is also 'const'
     if (redirectedConstructor.isConst) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, redirectedConstructorNode, []);
+    // report error
+    _errorReporter.reportError3(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, redirectedConstructorNode, []);
     return true;
   }
 
@@ -18035,7 +19890,7 @@
    */
   bool checkForRethrowOutsideCatch(RethrowExpression node) {
     if (!_isInCatchClause) {
-      _errorReporter.reportError2(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node, []);
       return true;
     }
     return false;
@@ -18050,14 +19905,17 @@
    * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
    */
   bool checkForReturnInGenerativeConstructor(ConstructorDeclaration node) {
+    // ignore factory
     if (node.factoryKeyword != null) {
       return false;
     }
+    // block body (with possible return statement) is checked elsewhere
     FunctionBody body = node.body;
     if (body is! ExpressionFunctionBody) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body, []);
+    // report error
+    _errorReporter.reportError3(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body, []);
     return true;
   }
 
@@ -18079,7 +19937,7 @@
       if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnType.isBottom) {
         return false;
       }
-      _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
+      _errorReporter.reportError3(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
           staticReturnType.displayName,
           expectedReturnType.displayName,
           _enclosingFunction.displayName]);
@@ -18089,7 +19947,7 @@
     if (isStaticAssignable) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
+    _errorReporter.reportError3(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
         staticReturnType.displayName,
         expectedReturnType.displayName,
         _enclosingFunction.displayName]);
@@ -18108,18 +19966,22 @@
    * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
    */
   bool checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleIdentifier name) {
+    // OK, target is not a type
     if (typeReference == null) {
       return false;
     }
+    // prepare member Element
     Element element = name.staticElement;
     if (element is! ExecutableElement) {
       return false;
     }
     ExecutableElement memberElement = element as ExecutableElement;
+    // OK, static
     if (memberElement.isStatic) {
       return false;
     }
-    _errorReporter.reportError2(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
+    // report problem
+    _errorReporter.reportError3(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
     return true;
   }
 
@@ -18132,23 +19994,28 @@
    * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE
    */
   bool checkForSwitchExpressionNotAssignable(SwitchStatement node) {
+    // prepare 'switch' expression type
     Expression expression = node.expression;
     Type2 expressionType = getStaticType(expression);
     if (expressionType == null) {
       return false;
     }
+    // compare with type of the first 'case'
     NodeList<SwitchMember> members = node.members;
     for (SwitchMember switchMember in members) {
       if (switchMember is! SwitchCase) {
         continue;
       }
       SwitchCase switchCase = switchMember as SwitchCase;
+      // prepare 'case' type
       Expression caseExpression = switchCase.expression;
       Type2 caseType = getStaticType(caseExpression);
+      // check types
       if (expressionType.isAssignableTo(caseType)) {
         return false;
       }
-      _errorReporter.reportError2(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [expressionType, caseType]);
+      // report problem
+      _errorReporter.reportError3(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [expressionType, caseType]);
       return true;
     }
     return false;
@@ -18166,7 +20033,7 @@
     if (!hasTypedefSelfReference(element)) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node, []);
+    _errorReporter.reportError3(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node, []);
     return true;
   }
 
@@ -18181,7 +20048,7 @@
     if (!hasTypedefSelfReference(element)) {
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node, []);
+    _errorReporter.reportError3(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node, []);
     return true;
   }
 
@@ -18196,17 +20063,21 @@
     if (node.typeArguments == null) {
       return false;
     }
+    // prepare Type
     Type2 type = node.type;
     if (type == null) {
       return false;
     }
+    // prepare ClassElement
     Element element = type.element;
     if (element is! ClassElement) {
       return false;
     }
     ClassElement classElement = element as ClassElement;
+    // prepare type parameters
     List<Type2> typeParameters = classElement.type.typeArguments;
     List<TypeParameterElement> boundingElts = classElement.typeParameters;
+    // iterate over each bounded type parameter and corresponding argument
     NodeList<TypeName> typeNameArgList = node.typeArguments.arguments;
     List<Type2> typeArguments = (type as InterfaceType).typeArguments;
     int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.length);
@@ -18224,7 +20095,7 @@
           } else {
             errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
           }
-          _errorReporter.reportError2(errorCode, argTypeName, [argType.displayName, boundType.displayName]);
+          _errorReporter.reportError3(errorCode, argTypeName, [argType.displayName, boundType.displayName]);
           foundError = true;
         }
       }
@@ -18244,7 +20115,7 @@
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
       Type2 type = node.type;
       if (type is TypeParameterType) {
-        _errorReporter.reportError2(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node, []);
+        _errorReporter.reportError3(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node, []);
         return true;
       }
     }
@@ -18260,14 +20131,17 @@
    */
   bool checkForTypeParameterSupertypeOfItsBound(TypeParameter node) {
     TypeParameterElement element = node.element;
+    // prepare bound
     Type2 bound = element.bound;
     if (bound == null) {
       return false;
     }
+    // OK, type parameter is not supertype of its bound
     if (!bound.isMoreSpecificThan(element.type)) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [element.displayName]);
+    // report problem
+    _errorReporter.reportError3(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [element.displayName]);
     return true;
   }
 
@@ -18283,14 +20157,24 @@
    * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT
    */
   bool checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration node) {
+    //
+    // Ignore if the constructor is not generative.
+    //
     if (node.factoryKeyword != null) {
       return false;
     }
+    //
+    // Ignore if the constructor has either an implicit super constructor invocation or a
+    // redirecting constructor invocation.
+    //
     for (ConstructorInitializer constructorInitializer in node.initializers) {
       if (constructorInitializer is SuperConstructorInvocation || constructorInitializer is RedirectingConstructorInvocation) {
         return false;
       }
     }
+    //
+    // Check to see whether the superclass has a non-factory unnamed constructor.
+    //
     if (_enclosingClass == null) {
       return false;
     }
@@ -18302,7 +20186,7 @@
     ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
     if (superUnnamedConstructor != null) {
       if (superUnnamedConstructor.isFactory) {
-        _errorReporter.reportError2(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [superUnnamedConstructor]);
+        _errorReporter.reportError3(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [superUnnamedConstructor]);
         return true;
       }
       if (!superUnnamedConstructor.isDefaultConstructor) {
@@ -18314,11 +20198,11 @@
           offset = returnType.offset;
           length = (name != null ? name.end : returnType.end) - offset;
         }
-        _errorReporter.reportError4(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, length, [superType.displayName]);
+        _errorReporter.reportError5(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, length, [superType.displayName]);
       }
       return false;
     }
-    _errorReporter.reportError2(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node.returnType, [superElement.name]);
+    _errorReporter.reportError3(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node.returnType, [superElement.name]);
     return true;
   }
 
@@ -18339,13 +20223,13 @@
     if (enclosingElement is! ClassElement) {
       return false;
     }
-    if ((element is MethodElement && !(element as MethodElement).isStatic) || (element is PropertyAccessorElement && !(element as PropertyAccessorElement).isStatic)) {
+    if ((element is MethodElement && !element.isStatic) || (element is PropertyAccessorElement && !element.isStatic)) {
       return false;
     }
     if (identical(enclosingElement, _enclosingClass)) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]);
+    _errorReporter.reportError3(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]);
     return true;
   }
 
@@ -18360,16 +20244,19 @@
    * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
    */
   bool checkForWrongNumberOfParametersForOperator(MethodDeclaration node) {
+    // prepare number of parameters
     FormalParameterList parameterList = node.parameters;
     if (parameterList == null) {
       return false;
     }
     int numParameters = parameterList.parameters.length;
+    // prepare operator name
     SimpleIdentifier nameNode = node.name;
     if (nameNode == null) {
       return false;
     }
     String name = nameNode.name;
+    // check for exact number of parameters
     int expected = -1;
     if ("[]=" == name) {
       expected = 2;
@@ -18379,13 +20266,15 @@
       expected = 0;
     }
     if (expected != -1 && numParameters != expected) {
-      _errorReporter.reportError2(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, nameNode, [name, expected, numParameters]);
+      _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, nameNode, [name, expected, numParameters]);
       return true;
     }
+    // check for operator "-"
     if ("-" == name && numParameters > 1) {
-      _errorReporter.reportError2(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, nameNode, [numParameters]);
+      _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, nameNode, [numParameters]);
       return true;
     }
+    // OK
     return false;
   }
 
@@ -18408,7 +20297,7 @@
     }
     NodeList<FormalParameter> parameters = parameterList.parameters;
     if (parameters.length != 1 || parameters[0].kind != ParameterKind.REQUIRED) {
-      _errorReporter.reportError2(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, setterName, []);
+      _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, setterName, []);
       return true;
     }
     return false;
@@ -18434,7 +20323,7 @@
     }
     ExecutableElement callMethod = _inheritanceManager.lookupMember(classElement, "call");
     if (callMethod == null || callMethod is! MethodElement || (callMethod as MethodElement).isAbstract) {
-      _errorReporter.reportError2(StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name, []);
+      _errorReporter.reportError3(StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name, []);
       return true;
     }
     return false;
@@ -18448,21 +20337,25 @@
    * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS
    */
   bool checkImplementsSuperClass(ClassDeclaration node) {
+    // prepare super type
     InterfaceType superType = _enclosingClass.supertype;
     if (superType == null) {
       return false;
     }
+    // prepare interfaces
     ImplementsClause implementsClause = node.implementsClause;
     if (implementsClause == null) {
       return false;
     }
+    // check interfaces
     bool hasProblem = false;
     for (TypeName interfaceNode in implementsClause.interfaces) {
       if (interfaceNode.type == superType) {
         hasProblem = true;
-        _errorReporter.reportError2(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, [superType.displayName]);
+        _errorReporter.reportError3(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, [superType.displayName]);
       }
     }
+    // done
     return hasProblem;
   }
 
@@ -18488,7 +20381,9 @@
    * @return The type of the given setter.
    */
   Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) {
+    // Get the parameters for MethodDeclaration or FunctionDeclaration
     List<ParameterElement> setterParameters = propertyAccessorElement.parameters;
+    // If there are no setter parameters, return no type.
     if (setterParameters.length == 0) {
       return null;
     }
@@ -18504,6 +20399,7 @@
   Type2 getStaticType(Expression expression) {
     Type2 type = expression.staticType;
     if (type == null) {
+      // TODO(brianwilkerson) This should never happen.
       return _dynamicType;
     }
     return type;
@@ -18518,9 +20414,9 @@
    */
   VariableElement getVariableElement(Expression expression) {
     if (expression is Identifier) {
-      Element element = (expression as Identifier).staticElement;
+      Element element = expression.staticElement;
       if (element is VariableElement) {
-        return element as VariableElement;
+        return element;
       }
     }
     return null;
@@ -18556,10 +20452,13 @@
     bool firstIteration = true;
     while (true) {
       Element current;
+      // get next element
       while (true) {
+        // may be no more elements to check
         if (toCheck.isEmpty) {
           return false;
         }
+        // try to get next element
         current = toCheck.removeAt(toCheck.length - 1);
         if (target == current) {
           if (firstIteration) {
@@ -18573,7 +20472,8 @@
           break;
         }
       }
-      current.accept(new GeneralizingElementVisitor_14(target, toCheck));
+      // check current element
+      current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(target, toCheck));
       checked.add(current);
     }
   }
@@ -18583,18 +20483,22 @@
    *         <i>int</i> or <i>String</i>.
    */
   bool implementsEqualsWhenNotAllowed(Type2 type) {
+    // ignore int or String
     if (type == null || type == _typeProvider.intType || type == _typeProvider.stringType) {
       return false;
     }
+    // prepare ClassElement
     Element element = type.element;
     if (element is! ClassElement) {
       return false;
     }
     ClassElement classElement = element as ClassElement;
+    // lookup for ==
     MethodElement method = classElement.lookUpMethod("==", _currentLibrary);
     if (method == null || method.enclosingElement.type.isObject) {
       return false;
     }
+    // there is == that we don't like
     return true;
   }
 
@@ -18604,7 +20508,7 @@
     } else if (type is FunctionType || type.isDartCoreFunction) {
       return true;
     } else if (type is InterfaceType) {
-      MethodElement callMethod = (type as InterfaceType).lookUpMethod(ElementResolver.CALL_METHOD_NAME, _currentLibrary);
+      MethodElement callMethod = type.lookUpMethod(ElementResolver.CALL_METHOD_NAME, _currentLibrary);
       return callMethod != null;
     }
     return false;
@@ -18623,6 +20527,56 @@
   }
 
   /**
+   * Return `true` iff the passed [ClassElement] has a method, getter or setter that
+   * matches the name of the passed [ExecutableElement] in either the class itself, or one of
+   * its' mixins.
+   *
+   * By "match", only the name of the member is tested to match, it does not have to equal or be a
+   * subtype of the passed executable element, this is due to the specific use where this method is
+   * used in [checkForNonAbstractClassInheritsAbstractMember].
+   *
+   * @param executableElt the executable to search for in the passed class element
+   * @param classElt the class method to search through the members of
+   * @return `true` iff the passed member is found in the passed class element
+   */
+  bool isMemberInClassOrMixin(ExecutableElement executableElt, ClassElement classElt) {
+    ExecutableElement foundElt;
+    String executableName = executableElt.name;
+    if (executableElt is MethodElement) {
+      foundElt = classElt.getMethod(executableName);
+      if (foundElt != null) {
+        return true;
+      }
+      List<InterfaceType> mixins = classElt.mixins;
+      for (int i = 0; i < mixins.length && foundElt == null; i++) {
+        foundElt = mixins[i].getMethod(executableName);
+      }
+      if (foundElt != null) {
+        return true;
+      }
+    } else if (executableElt is PropertyAccessorElement) {
+      foundElt = classElt.getGetter(executableElt.name);
+      if (foundElt == null) {
+        foundElt = classElt.getSetter(executableName);
+      }
+      if (foundElt != null) {
+        return true;
+      }
+      List<InterfaceType> mixins = classElt.mixins;
+      for (int i = 0; i < mixins.length && foundElt == null; i++) {
+        foundElt = mixins[i].getGetter(executableName);
+        if (foundElt == null) {
+          foundElt = mixins[i].getSetter(executableName);
+        }
+      }
+      if (foundElt != null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
    * @param node the 'this' expression to analyze
    * @return `true` if the given 'this' expression is in the valid context
    */
@@ -18662,14 +20616,14 @@
     if (parent is ConstructorName || parent is MethodInvocation || parent is PropertyAccess || parent is SuperConstructorInvocation) {
       return true;
     }
-    if (parent is PrefixedIdentifier && identical((parent as PrefixedIdentifier).identifier, node)) {
+    if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
       return true;
     }
-    if (parent is Annotation && identical((parent as Annotation).constructorName, node)) {
+    if (parent is Annotation && identical(parent.constructorName, node)) {
       return true;
     }
     if (parent is CommentReference) {
-      CommentReference commentReference = parent as CommentReference;
+      CommentReference commentReference = parent;
       if (commentReference.newKeyword != null) {
         return true;
       }
@@ -18677,6 +20631,8 @@
     return false;
   }
 
+  bool isUserDefinedObject(EvaluationResultImpl result) => result == null || (result is ValidResult && result.isUserDefinedObject);
+
   /**
    * Return `true` iff the passed [ClassElement] has a concrete implementation of the
    * passed accessor name in the superclass chain.
@@ -18783,12 +20739,12 @@
   INIT_STATE(String name, int ordinal) : super(name, ordinal);
 }
 
-class GeneralizingElementVisitor_14 extends GeneralizingElementVisitor<Object> {
+class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends GeneralizingElementVisitor<Object> {
   Element target;
 
   List<Element> toCheck;
 
-  GeneralizingElementVisitor_14(this.target, this.toCheck) : super();
+  GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.target, this.toCheck) : super();
 
   bool _inClass = false;
 
@@ -18838,12 +20794,15 @@
       return;
     }
     Element element = type.element;
+    // it is OK to reference target from class
     if (_inClass && target == element) {
       return;
     }
+    // schedule for checking
     toCheck.add(element);
+    // type arguments
     if (type is InterfaceType) {
-      InterfaceType interfaceType = type as InterfaceType;
+      InterfaceType interfaceType = type;
       for (Type2 typeArgument in interfaceType.typeArguments) {
         addTypeToCheck(typeArgument);
       }
@@ -18885,7 +20844,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction9;
+  String correction10;
 
   /**
    * Initialize a newly created error code to have the given type and message.
@@ -18903,10 +20862,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, String correction) : super(name, ordinal) {
-    this.correction9 = correction;
+    this.correction10 = correction;
   }
 
-  String get correction => correction9;
+  String get correction => correction10;
 
   ErrorSeverity get errorSeverity => type.severity;
 }
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 6d0fe31..ee1ec2c 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -169,7 +173,7 @@
    * The template used to create the correction to be displayed for this error, or `null` if
    * there is no correction information for this error.
    */
-  String correction10;
+  String correction11;
 
   /**
    * Initialize a newly created error code to have the given message.
@@ -185,10 +189,10 @@
    * @param correction the template used to create the correction to be displayed for the error
    */
   ScannerErrorCode.con2(String name, int ordinal, this.message, String correction) : super(name, ordinal) {
-    this.correction10 = correction;
+    this.correction11 = correction;
   }
 
-  String get correction => correction10;
+  String get correction => correction11;
 
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
 
@@ -646,12 +650,23 @@
    * @param insertedLength the number of characters added to the modified source
    */
   Token rescan(Token originalStream, int index, int removedLength, int insertedLength) {
+    //
+    // Copy all of the tokens in the originalStream whose end is less than the replacement start.
+    // (If the replacement start is equal to the end of an existing token, then it means that the
+    // existing token might have been modified, so we need to rescan it.)
+    //
     while (originalStream.type != TokenType.EOF && originalStream.end < index) {
       originalStream = copyAndAdvance(originalStream, 0);
     }
     Token oldFirst = originalStream;
     Token oldLeftToken = originalStream.previous;
     _leftToken = tail;
+    //
+    // Skip tokens in the original stream until we find a token whose offset is greater than the end
+    // of the removed region. (If the end of the removed region is equal to the beginning of an
+    // existing token, then it means that the existing token might have been modified, so we need to
+    // rescan it.)
+    //
     int removedEnd = index + (removedLength == 0 ? 0 : removedLength - 1);
     while (originalStream.type != TokenType.EOF && originalStream.offset <= removedEnd) {
       originalStream = originalStream.next;
@@ -666,16 +681,33 @@
       oldLast = originalStream.previous;
       oldRightToken = originalStream;
     }
+    //
+    // Compute the delta between the character index of characters after the modified region in the
+    // original source and the index of the corresponding character in the modified source.
+    //
     int delta = insertedLength - removedLength;
+    //
+    // Compute the range of characters that are known to need to be rescanned. If the index is
+    // within an existing token, then we need to start at the beginning of the token.
+    //
     int scanStart = Math.min(oldFirst.offset, index);
     int oldEnd = oldLast.end + delta - 1;
     int newEnd = index + insertedLength - 1;
     int scanEnd = Math.max(newEnd, oldEnd);
+    //
+    // Starting at the start of the scan region, scan tokens from the modifiedSource until the end
+    // of the just scanned token is greater than or equal to end of the scan region in the modified
+    // source. Include trailing characters of any token that was split as a result of inserted text,
+    // as in "ab" --> "a.b".
+    //
     _reader.offset = scanStart - 1;
     int next = _reader.advance();
     while (next != -1 && _reader.offset <= scanEnd) {
       next = bigSwitch(next);
     }
+    //
+    // Copy the remaining tokens in the original stream, but apply the delta to the token's offset.
+    //
     if (identical(originalStream.type, TokenType.EOF)) {
       copyAndAdvance(originalStream, delta);
       _rightToken = tail;
@@ -689,6 +721,12 @@
       Token eof = copyAndAdvance(originalStream, delta);
       eof.setNextWithoutSettingPrevious(eof);
     }
+    //
+    // If the index is immediately after an existing token and the inserted characters did not
+    // change that original token, then adjust the leftToken to be the next token. For example, in
+    // "a; c;" --> "a;b c;", the leftToken was ";", but this code advances it to "b" since "b" is
+    // the first new token.
+    //
     Token newFirst = _leftToken.next;
     while (newFirst != _rightToken && oldFirst != oldRightToken && newFirst.type != TokenType.EOF && equals3(oldFirst, newFirst)) {
       _tokenMap.put(oldFirst, newFirst);
@@ -706,6 +744,12 @@
       newLast = newLast.previous;
     }
     _hasNonWhitespaceChange2 = _leftToken.next != _rightToken || oldLeftToken.next != oldRightToken;
+    //
+    // TODO(brianwilkerson) Begin tokens are not getting associated with the corresponding end
+    //     tokens (because the end tokens have not been copied when we're copying the begin tokens).
+    //     This could have implications for parsing.
+    // TODO(brianwilkerson) Update the lineInfo.
+    //
     return firstToken;
   }
 
@@ -1085,9 +1129,11 @@
   }
 
   void appendCommentToken(TokenType type, String value) {
+    // Ignore comment tokens if client specified that it doesn't need them.
     if (!_preserveComments) {
       return;
     }
+    // OK, remember comment tokens.
     if (_firstComment == null) {
       _firstComment = new StringToken(type, value, _tokenStart);
       _lastComment = _firstComment;
@@ -1124,6 +1170,7 @@
       _firstComment = null;
       _lastComment = null;
     }
+    // The EOF token points to itself so that there is always infinite look-ahead.
     eofToken.setNext(eofToken);
     _tail = _tail.setNext(eofToken);
     if (_stackEnd >= 0) {
@@ -1201,6 +1248,10 @@
       _hasUnmatchedGroups2 = true;
       _groupingStack.removeAt(_stackEnd--);
     }
+    //
+    // We should never get to this point because we wouldn't be inside a string interpolation
+    // expression unless we had previously found the start of the expression.
+    //
     return null;
   }
 
@@ -1237,6 +1288,7 @@
   }
 
   int tokenizeAmpersand(int next) {
+    // && &= &
     next = _reader.advance();
     if (next == 0x26) {
       appendToken2(TokenType.AMPERSAND_AMPERSAND);
@@ -1251,6 +1303,7 @@
   }
 
   int tokenizeBar(int next) {
+    // | || |=
     next = _reader.advance();
     if (next == 0x7C) {
       appendToken2(TokenType.BAR_BAR);
@@ -1280,6 +1333,7 @@
   }
 
   int tokenizeEquals(int next) {
+    // = == =>
     next = _reader.advance();
     if (next == 0x3D) {
       appendToken2(TokenType.EQ_EQ);
@@ -1293,6 +1347,7 @@
   }
 
   int tokenizeExclamation(int next) {
+    // ! !=
     next = _reader.advance();
     if (next == 0x3D) {
       appendToken2(TokenType.BANG_EQ);
@@ -1350,6 +1405,7 @@
   }
 
   int tokenizeGreaterThan(int next) {
+    // > >= >> >>=
     next = _reader.advance();
     if (0x3D == next) {
       appendToken2(TokenType.GT_EQ);
@@ -1453,7 +1509,7 @@
     KeywordState state = KeywordState.KEYWORD_STATE;
     int start = _reader.offset;
     while (state != null && 0x61 <= next && next <= 0x7A) {
-      state = state.next(next as int);
+      state = state.next(next);
       next = _reader.advance();
     }
     if (state == null || state.keyword() == null) {
@@ -1470,6 +1526,7 @@
   }
 
   int tokenizeLessThan(int next) {
+    // < <= << <<=
     next = _reader.advance();
     if (0x3D == next) {
       appendToken2(TokenType.LT_EQ);
@@ -1483,6 +1540,7 @@
   }
 
   int tokenizeMinus(int next) {
+    // - -- -=
     next = _reader.advance();
     if (next == 0x2D) {
       appendToken2(TokenType.MINUS_MINUS);
@@ -1647,6 +1705,7 @@
   }
 
   int tokenizeOpenSquareBracket(int next) {
+    // [ []  []=
     next = _reader.advance();
     if (next == 0x5D) {
       return select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
@@ -1659,6 +1718,7 @@
   int tokenizePercent(int next) => select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);
 
   int tokenizePlus(int next) {
+    // + ++ +=
     next = _reader.advance();
     if (0x2B == next) {
       appendToken2(TokenType.PLUS_PLUS);
@@ -1746,8 +1806,10 @@
     if (quoteChar == next) {
       next = _reader.advance();
       if (quoteChar == next) {
+        // Multiline string.
         return tokenizeMultiLineString(quoteChar, start, raw);
       } else {
+        // Empty string.
         appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         return next;
       }
@@ -1770,6 +1832,7 @@
   }
 
   int tokenizeTag(int next) {
+    // # or #!.*[\n\r]
     if (_reader.offset == 0) {
       if (_reader.peek() == 0x21) {
         do {
@@ -1784,6 +1847,7 @@
   }
 
   int tokenizeTilde(int next) {
+    // ~ ~/ ~/=
     next = _reader.advance();
     if (next == 0x2F) {
       return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 327b3e5..9697515 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 018b655..eaca50f 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -450,15 +454,26 @@
   /**
    * Return the library map read from the given source.
    *
+   * @param file the [File] of the library file
+   * @param libraryFileContents the contents from the library file
    * @return the library map read from the given source
    */
-  LibraryMap readFrom(JavaFile librariesFile, String libraryFileContents) {
+  LibraryMap readFrom(JavaFile file, String libraryFileContents) => readFrom2(new FileBasedSource.con2(null, file, UriKind.FILE_URI), libraryFileContents);
+
+  /**
+   * Return the library map read from the given source.
+   *
+   * @param source the source of the library file
+   * @param libraryFileContents the contents from the library file
+   * @return the library map read from the given source
+   */
+  LibraryMap readFrom2(Source source, String libraryFileContents) {
     BooleanErrorListener errorListener = new BooleanErrorListener();
-    Source source = new FileBasedSource.con2(null, librariesFile, UriKind.FILE_URI);
     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();
+    // If any syntactic errors were found then don't try to visit the AST structure.
     if (!errorListener.errorReported) {
       unit.accept(libraryBuilder);
     }
@@ -511,18 +526,18 @@
     String libraryName = null;
     Expression key = node.key;
     if (key is SimpleStringLiteral) {
-      libraryName = "${_LIBRARY_PREFIX}${(key as SimpleStringLiteral).value}";
+      libraryName = "${_LIBRARY_PREFIX}${key.value}";
     }
     Expression value = node.value;
     if (value is InstanceCreationExpression) {
       SdkLibraryImpl library = new SdkLibraryImpl(libraryName);
-      List<Expression> arguments = (value as InstanceCreationExpression).argumentList.arguments;
+      List<Expression> arguments = value.argumentList.arguments;
       for (Expression argument in arguments) {
         if (argument is SimpleStringLiteral) {
-          library.path = (argument as SimpleStringLiteral).value;
+          library.path = argument.value;
         } else if (argument is NamedExpression) {
-          String name = (argument as NamedExpression).name.label.name;
-          Expression expression = (argument as NamedExpression).expression;
+          String name = argument.name.label.name;
+          Expression expression = argument.expression;
           if (name == _CATEGORY) {
             library.category = (expression as SimpleStringLiteral).value;
           } else if (name == _IMPLEMENTATION) {
@@ -531,7 +546,7 @@
             library.documented = (expression as BooleanLiteral).value;
           } else if (name == _PLATFORMS) {
             if (expression is SimpleIdentifier) {
-              String identifier = (expression as SimpleIdentifier).name;
+              String identifier = expression.name;
               if (identifier == _VM_PLATFORM) {
                 library.setVmLibrary();
               } else {
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 1a812c6..fc9d672 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -17,18 +21,18 @@
   /**
    * Instance of [LocalSourcePredicate] that always returns `false`.
    */
-  static final LocalSourcePredicate FALSE = new LocalSourcePredicate_15();
+  static final LocalSourcePredicate FALSE = new LocalSourcePredicate_FALSE();
 
   /**
    * Instance of [LocalSourcePredicate] that always returns `true`.
    */
-  static final LocalSourcePredicate TRUE = new LocalSourcePredicate_16();
+  static final LocalSourcePredicate TRUE = new LocalSourcePredicate_TRUE();
 
   /**
    * Instance of [LocalSourcePredicate] that returns `true` for all [Source]s
    * except of SDK.
    */
-  static final LocalSourcePredicate NOT_SDK = new LocalSourcePredicate_17();
+  static final LocalSourcePredicate NOT_SDK = new LocalSourcePredicate_NOT_SDK();
 
   /**
    * Determines if the given [Source] is local.
@@ -39,15 +43,15 @@
   bool isLocal(Source source);
 }
 
-class LocalSourcePredicate_15 implements LocalSourcePredicate {
+class LocalSourcePredicate_FALSE implements LocalSourcePredicate {
   bool isLocal(Source source) => false;
 }
 
-class LocalSourcePredicate_16 implements LocalSourcePredicate {
+class LocalSourcePredicate_TRUE implements LocalSourcePredicate {
   bool isLocal(Source source) => true;
 }
 
-class LocalSourcePredicate_17 implements LocalSourcePredicate {
+class LocalSourcePredicate_NOT_SDK implements LocalSourcePredicate {
   bool isLocal(Source source) => source.uriKind != UriKind.DART_URI;
 }
 
@@ -162,7 +166,7 @@
   DartSdk get dartSdk {
     for (UriResolver resolver in _resolvers) {
       if (resolver is DartUriResolver) {
-        DartUriResolver dartUriResolver = resolver as DartUriResolver;
+        DartUriResolver dartUriResolver = resolver;
         return dartUriResolver.dartSdk;
       }
     }
@@ -192,6 +196,7 @@
       return null;
     }
     try {
+      // Force the creation of an escaped URI to deal with spaces, etc.
       return resolveUri2(containingSource, parseUriWithException(containedUri));
     } on URISyntaxException catch (exception) {
       return null;
@@ -892,6 +897,8 @@
     } else {
       int newStamp = JavaSystem.currentTimeMillis();
       int oldStamp = javaMapPut(_stampMap, source, newStamp);
+      // Occasionally, if this method is called in rapid succession, the timestamps are equal.
+      // Guard against this by artificially incrementing the new timestamp
       if (newStamp == oldStamp) {
         _stampMap[source] = newStamp + 1;
       }
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 60fe02c..0068239 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -19,18 +23,18 @@
   /**
    * Instance of [LocalSourcePredicate] that always returns `false`.
    */
-  static final LocalSourcePredicate FALSE = new LocalSourcePredicate_15();
+  static final LocalSourcePredicate FALSE = new LocalSourcePredicate_FALSE();
 
   /**
    * Instance of [LocalSourcePredicate] that always returns `true`.
    */
-  static final LocalSourcePredicate TRUE = new LocalSourcePredicate_16();
+  static final LocalSourcePredicate TRUE = new LocalSourcePredicate_TRUE();
 
   /**
    * Instance of [LocalSourcePredicate] that returns `true` for all [Source]s
    * except of SDK.
    */
-  static final LocalSourcePredicate NOT_SDK = new LocalSourcePredicate_17();
+  static final LocalSourcePredicate NOT_SDK = new LocalSourcePredicate_NOT_SDK();
 
   /**
    * Determines if the given [Source] is local.
@@ -41,15 +45,15 @@
   bool isLocal(Source source);
 }
 
-class LocalSourcePredicate_15 implements LocalSourcePredicate {
+class LocalSourcePredicate_FALSE implements LocalSourcePredicate {
   bool isLocal(Source source) => false;
 }
 
-class LocalSourcePredicate_16 implements LocalSourcePredicate {
+class LocalSourcePredicate_TRUE implements LocalSourcePredicate {
   bool isLocal(Source source) => true;
 }
 
-class LocalSourcePredicate_17 implements LocalSourcePredicate {
+class LocalSourcePredicate_NOT_SDK implements LocalSourcePredicate {
   bool isLocal(Source source) => source.uriKind != UriKind.DART_URI;
 }
 
@@ -107,11 +111,17 @@
   bool exists() => _contentCache.getContents(this) != null || (_file.exists() && !_file.isDirectory());
 
   void getContents(Source_ContentReceiver receiver) {
+    //
+    // First check to see whether our content cache has an override for our contents.
+    //
     String contents = _contentCache.getContents(this);
     if (contents != null) {
       receiver.accept2(contents, _contentCache.getModificationStamp(this));
       return;
     }
+    //
+    // If not, read the contents from the file using native I/O.
+    //
     getContentsFromFile(receiver);
   }
 
@@ -251,11 +261,14 @@
     String relPath;
     int index = path.indexOf('/');
     if (index == -1) {
+      // No slash
       pkgName = path;
       relPath = "";
     } else if (index == 0) {
+      // Leading slash is invalid
       return null;
     } else {
+      // <pkgName>/<relPath>
       pkgName = path.substring(0, index);
       relPath = path.substring(index + 1);
     }
@@ -272,7 +285,7 @@
 
   Uri restoreAbsolute(Source source) {
     if (source is FileBasedSource) {
-      String sourcePath = (source as FileBasedSource).file.getPath();
+      String sourcePath = source.file.getPath();
       for (JavaFile packagesDirectory in _packagesDirectories) {
         List<JavaFile> pkgFolders = packagesDirectory.listFiles();
         if (pkgFolders != null) {
@@ -379,7 +392,7 @@
 
   bool contains(Source source) => source.fullName.startsWith(_path);
 
-  bool operator ==(Object obj) => (obj is DirectoryBasedSourceContainer) && (obj as DirectoryBasedSourceContainer).path == path;
+  bool operator ==(Object obj) => (obj is DirectoryBasedSourceContainer) && obj.path == path;
 
   /**
    * Answer the receiver's path, used to determine if a source is contained in the receiver.
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index adb9ccc..8653603 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index bfefac5..8df7125 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index 2d7b26d..abee059 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -1,20 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 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.utilities.general;
 
-import 'java_core.dart';
-
 /**
  * Helper for measuring how much time is spent doing some operation.
  */
 class TimeCounter {
-  int _result = 0;
+  Stopwatch _sw = new Stopwatch();
 
   /**
    * @return the number of milliseconds spent between [start] and [stop].
    */
-  int get result => _result;
+  int get result => _sw.elapsedMilliseconds;
 
   /**
    * Starts counting time.
@@ -28,18 +30,16 @@
  * The handle object that should be used to stop and update counter.
  */
 class TimeCounter_TimeCounterHandle {
-  final TimeCounter TimeCounter_this;
+  final TimeCounter _counter;
 
-  int _startTime = JavaSystem.currentTimeMillis();
-
-  TimeCounter_TimeCounterHandle(this.TimeCounter_this);
+  TimeCounter_TimeCounterHandle(this._counter) {
+    _counter._sw.start();
+  }
 
   /**
    * Stops counting time and updates counter.
    */
   void stop() {
-    {
-      TimeCounter_this._result += JavaSystem.currentTimeMillis() - _startTime;
-    }
+    _counter._sw.stop();
   }
 }
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
index 2bae3ec..09491c1 100644
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -133,7 +133,7 @@
     var node = parse(kind, startToken);
     checkForErrors();
 
-    var formatter = new SourceVisitor(options, lineInfo, selection);
+    var formatter = new SourceVisitor(options, lineInfo, source, selection);
     node.accept(formatter);
 
     var formattedSource = formatter.writer.toString();
@@ -366,21 +366,31 @@
   /// Used for matching EOL comments
   final twoSlashes = new RegExp(r'//[^/]');
 
+  /// A weight for potential breakpoints.
+  int breakWeight = DEFAULT_SPACE_WEIGHT;
+
   /// Original pre-format selection information (may be null).
   final Selection preSelection;
 
   final bool codeTransforms;
 
+
+  /// The source being formatted (used in interpolation handling)
+  final String source;
+
   /// Post format selection information.
   Selection selection;
 
 
   /// Initialize a newly created visitor to write source code representing
   /// the visited nodes to the given [writer].
-  SourceVisitor(FormatterOptions options, this.lineInfo, this.preSelection):
-      writer = new SourceWriter(indentCount: options.initialIndentationLevel,
-                                lineSeparator: options.lineSeparator),
-      codeTransforms = options.codeTransforms;
+  SourceVisitor(FormatterOptions options, this.lineInfo, this.source,
+    this.preSelection)
+      : writer = new SourceWriter(indentCount: options.initialIndentationLevel,
+                                lineSeparator: options.lineSeparator,
+                                useTabs: options.tabsForIndent,
+                                spacesPerIndent: options.spacesPerIndent),
+       codeTransforms = options.codeTransforms;
 
   visitAdjacentStrings(AdjacentStrings node) {
     visitNodes(node.strings, separatedBy: space);
@@ -496,6 +506,7 @@
 
   visitClassDeclaration(ClassDeclaration node) {
     preserveLeadingNewlines();
+    visitNodes(node.metadata, followedBy: newlines);
     modifier(node.abstractKeyword);
     token(node.classKeyword);
     space();
@@ -505,6 +516,7 @@
       visitNode(node.extendsClause, precededBy: space);
       visitNode(node.withClause, precededBy: space);
       visitNode(node.implementsClause, precededBy: space);
+      visitNode(node.nativeClause, precededBy: space);
       space();
     });
     token(node.leftBracket);
@@ -516,6 +528,16 @@
   }
 
   visitClassTypeAlias(ClassTypeAlias node) {
+    preserveLeadingNewlines();
+    visitNodes(node.metadata, followedBy: newlines);
+    //TODO(pquitslund): the following _should_ work (dartbug.com/15912)
+    //modifier(node.abstractKeyword);
+    // ... in the meantime we use this workaround
+    var prev = node.keyword.previous;
+    if (prev is KeywordToken && prev.keyword == Keyword.ABSTRACT) {
+      token(prev);
+      space();
+    }
     token(node.keyword);
     space();
     visit(node.name);
@@ -523,10 +545,6 @@
     space();
     token(node.equals);
     space();
-    if (node.abstractKeyword != null) {
-      token(node.abstractKeyword);
-      space();
-    }
     visit(node.superclass);
     visitNode(node.withClause, precededBy: space);
     visitNode(node.implementsClause, precededBy: space);
@@ -577,6 +595,7 @@
   }
 
   visitConstructorDeclaration(ConstructorDeclaration node) {
+    visitNodes(node.metadata, followedBy: newlines);
     modifier(node.externalKeyword);
     modifier(node.constKeyword);
     modifier(node.factoryKeyword);
@@ -697,6 +716,7 @@
   }
 
   visitExportDirective(ExportDirective node) {
+    visitNodes(node.metadata, followedBy: newlines);
     token(node.keyword);
     space();
     visit(node.uri);
@@ -725,6 +745,7 @@
   }
 
   visitFieldDeclaration(FieldDeclaration node) {
+    visitNodes(node.metadata, followedBy: newlines);
     modifier(node.staticKeyword);
     visit(node.fields);
     token(node.semicolon);
@@ -743,7 +764,11 @@
     token(node.forKeyword);
     space();
     token(node.leftParenthesis);
-    visit(node.loopVariable);
+    if (node.loopVariable != null) {
+      visit(node.loopVariable);
+    } else {
+      visit(node.identifier);
+    }
     space();
     token(node.inKeyword);
     space();
@@ -810,8 +835,19 @@
 
   visitFunctionDeclaration(FunctionDeclaration node) {
     preserveLeadingNewlines();
-    visitNode(node.returnType, followedBy: space);
-    token(node.propertyKeyword, followedBy: space);
+    visitNodes(node.metadata, followedBy: newlines);
+    modifier(node.externalKeyword);
+    //TODO(pquitslund): remove this workaround once setter functions
+    //have their return types properly set (dartbug.com/15914)
+    if (node.returnType == null && node.propertyKeyword != null) {
+      var previous = node.propertyKeyword.previous;
+      if (previous is KeywordToken && previous.keyword == Keyword.VOID) {
+        modifier(previous);
+      }
+    } else {
+      visitNode(node.returnType, followedBy: space);
+    }
+    modifier(node.propertyKeyword);
     visit(node.name);
     visit(node.functionExpression);
   }
@@ -822,7 +858,9 @@
 
   visitFunctionExpression(FunctionExpression node) {
     visit(node.parameters);
-    space();
+    if (node.body is! EmptyFunctionBody) {
+      space();
+    }
     visit(node.body);
   }
 
@@ -832,6 +870,7 @@
   }
 
   visitFunctionTypeAlias(FunctionTypeAlias node) {
+    visitNodes(node.metadata, separatedBy: newlines, followedBy: newlines);
     token(node.keyword);
     space();
     visitNode(node.returnType, followedBy: space);
@@ -881,6 +920,7 @@
   }
 
   visitImportDirective(ImportDirective node) {
+    visitNodes(node.metadata, followedBy: newlines);
     token(node.keyword);
     space();
     visit(node.uri);
@@ -949,6 +989,7 @@
   }
 
   visitLibraryDirective(LibraryDirective node) {
+    visitNodes(node.metadata, followedBy: newlines);
     token(node.keyword);
     space();
     visit(node.name);
@@ -964,7 +1005,7 @@
     visit(node.typeArguments);
     token(node.leftBracket);
     indent();
-    visitCommaSeparatedNodes(node.elements);
+    visitCommaSeparatedNodes(node.elements /*, followedBy: breakableSpace*/);
     optionalTrailingComma(node.rightBracket);
     unindent();
     token(node.rightBracket);
@@ -991,6 +1032,7 @@
   }
 
   visitMethodDeclaration(MethodDeclaration node) {
+    visitNodes(node.metadata, followedBy: newlines);
     modifier(node.externalKeyword);
     modifier(node.modifierKeyword);
     visitNode(node.returnType, followedBy: space);
@@ -1117,6 +1159,7 @@
   }
 
   visitSimpleFormalParameter(SimpleFormalParameter node) {
+    visitNodes(node.metadata, followedBy: space);
     modifier(node.keyword);
     visitNode(node.type, followedBy: space);
     visit(node.identifier);
@@ -1131,7 +1174,15 @@
   }
 
   visitStringInterpolation(StringInterpolation node) {
-    visitNodes(node.elements);
+    // Ensure that interpolated strings don't get broken up by treating them as
+    // a single String token
+    // Process token (for comments etc. but don't print the lexeme)
+    token(node.beginToken, printToken: (tok) => null);
+    var start = node.beginToken.offset;
+    var end = node.endToken.end;
+    String string = source.substring(start, end);
+    append(string);
+    //visitNodes(node.elements);
   }
 
   visitSuperConstructorInvocation(SuperConstructorInvocation node) {
@@ -1181,7 +1232,16 @@
   }
 
   visitSymbolLiteral(SymbolLiteral node) {
-     // No-op ?
+    token(node.poundSign);
+    var components = node.components;
+    var size = components.length;
+    for (var component in components) {
+      // The '.' separator
+      if (component.previous.lexeme == '.') {
+        token(component.previous);
+      }
+      token(component);
+    }
   }
 
   visitThisExpression(ThisExpression node) {
@@ -1220,6 +1280,7 @@
   }
 
   visitTypeParameter(TypeParameter node) {
+    visitNodes(node.metadata, followedBy: space);
     visit(node.name);
     token(node.keyword /* extends */, precededBy: space, followedBy: space);
     visit(node.bound);
@@ -1250,6 +1311,7 @@
   }
 
   visitVariableDeclarationList(VariableDeclarationList node) {
+    visitNodes(node.metadata, followedBy: newlines);
     modifier(node.keyword);
     visitNode(node.type, followedBy: space);
     visitCommaSeparatedNodes(node.variables);
@@ -1389,7 +1451,8 @@
     preserveNewlines = true;
   }
 
-  token(Token token, {precededBy(), followedBy(), int minNewlines: 0}) {
+  token(Token token, {precededBy(), followedBy(),
+      printToken(tok), int minNewlines: 0}) {
     if (token != null) {
       if (needsNewline) {
         minNewlines = max(1, minNewlines);
@@ -1402,7 +1465,11 @@
         precededBy();
       }
       checkForSelectionUpdate(token);
-      append(token.lexeme);
+      if (printToken == null) {
+        append(token.lexeme);
+      } else {
+        printToken(token);
+      }
       if (followedBy != null) {
         followedBy();
       }
@@ -1411,12 +1478,13 @@
   }
 
   emitSpaces() {
-    while (leadingSpaces > 0) {
-      if (!writer.currentLine.isWhitespace() || allowLineLeadingSpaces) {
-        writer.print(' ');
+    if (leadingSpaces > 0) {
+      if (allowLineLeadingSpaces || !writer.currentLine.isWhitespace()) {
+        writer.spaces(leadingSpaces, breakWeight: breakWeight);
       }
+      leadingSpaces = 0;
       allowLineLeadingSpaces = false;
-      leadingSpaces--;
+      breakWeight = DEFAULT_SPACE_WEIGHT;
     }
   }
 
@@ -1443,9 +1511,11 @@
     allowLineLeadingSpaces = allowLineLeading;
   }
 
-  /// Emit a breakable space
+  /// Mark a breakable space
   breakableSpace() {
-    //Implement
+    space();
+    breakWeight =
+        countNewlinesBetween(previousToken, previousToken.next) > 0 ? 1 : 0;
   }
 
   /// Append the given [string] to the source writer if it's non-null.
@@ -1497,6 +1567,8 @@
       emitComment(comment, previousToken);
       comment = comment.next;
       currentToken = comment != null ? comment : token;
+      // Ensure EOL comments force a linebreak
+      needsNewline = true;
     }
 
     var lines = 0;
diff --git a/pkg/analyzer/lib/src/services/writer.dart b/pkg/analyzer/lib/src/services/writer.dart
index d7f8fd3..96966f9 100644
--- a/pkg/analyzer/lib/src/services/writer.dart
+++ b/pkg/analyzer/lib/src/services/writer.dart
@@ -5,15 +5,20 @@
 library source_writer;
 
 
+/// DEBUG flag indicating whether to use the experimental line-breaker
+const _USE_LINE_BREAKER = false;
+
+
 class Line {
 
-  final int lineLength;
   final tokens = <LineToken>[];
   final bool useTabs;
   final int spacesPerIndent;
+  final int indent;
+  final LinePrinter printer;
 
-  Line({indent: 0, this.lineLength: 80, this.useTabs: false,
-        this.spacesPerIndent: 2}) {
+  Line({this.indent: 0, this.useTabs: false, this.spacesPerIndent: 2,
+      this.printer: const SimpleLinePrinter()}) {
     if (indent > 0) {
       _indent(indent);
     }
@@ -23,9 +28,9 @@
     addSpaces(1);
   }
 
-  void addSpaces(int n) {
+  void addSpaces(int n, {breakWeight: DEFAULT_SPACE_WEIGHT}) {
     if (n > 0) {
-      tokens.add(new SpaceToken(n));
+      tokens.add(new SpaceToken(n, breakWeight: breakWeight));
     }
   }
 
@@ -39,29 +44,197 @@
     tokens.add(useTabs ? new TabToken(n) : new SpaceToken(n * spacesPerIndent));
   }
 
-  String toString() {
+  String toString() => printer.printLine(this);
+
+}
+
+
+/// Base class for line printers
+abstract class LinePrinter {
+
+  const LinePrinter();
+
+  /// Convert this [line] to a [String] representation.
+  String printLine(Line line);
+}
+
+
+typedef String Indenter(int n);
+
+
+/// A simple line breaking [LinePrinter]
+class SimpleLineBreaker extends LinePrinter {
+
+  static final NO_OP_INDENTER = (n) => '';
+
+  final chunks = <Chunk>[];
+  final int maxLength;
+  Indenter indenter;
+
+  SimpleLineBreaker(this.maxLength, [this.indenter]) {
+    if (indenter == null) {
+      indenter = NO_OP_INDENTER;
+    }
+  }
+
+  String printLine(Line line) {
+    var buf = new StringBuffer();
+    var chunks = breakLine(line);
+    for (var i = 0; i < chunks.length; ++i) {
+      if (i > 0) {
+        buf.write(indent(chunks[i], line.indent));
+      } else {
+        buf.write(chunks[i]);
+      }
+    }
+    return buf.toString();
+  }
+
+  String indent(Chunk chunk, int level) =>
+      '\n' + indenter(level + 2) + chunk.toString();
+
+  List<Chunk> breakLine(Line line) {
+
+    var chunks = <Chunk>[];
+
+    // The current unbroken line
+    var current = new Chunk(maxLength: maxLength);
+
+    // A tentative working chunk that will either start a new line or get
+    // absorbed into 'current'
+    var work = new Chunk(maxLength: maxLength);
+
+    line.tokens.forEach((tok) {
+
+      if (goodStart(tok, work)) {
+        if (current.fits(work)) {
+          current.add(work);
+        } else {
+          if (current.length > 0) {
+            chunks.add(current);
+          }
+          current = work;
+        }
+        work = new Chunk(start: tok, maxLength: maxLength - current.length);
+      } else {
+        if (work.fits(tok)) {
+          work.add(tok);
+        } else {
+          if (!isAllWhitespace(work)) {
+            current.add(work);
+          }
+          if (current.length > 0) {
+            chunks.add(current);
+            current = new Chunk(maxLength: maxLength);
+          }
+          work = new Chunk(maxLength: maxLength);
+          work.add(tok);
+        }
+      }
+
+    });
+
+    current.add(work);
+    if (current.length > 0) {
+      chunks.add(current);
+    }
+    return chunks;
+  }
+
+  bool isAllWhitespace(Chunk chunk) => isWhitespace(chunk.buffer.toString());
+
+  /// Test whether this token is a good start for a new working chunk
+  bool goodStart(LineToken tok, Chunk workingChunk) =>
+      tok is SpaceToken && tok.breakWeight >= workingChunk.start.breakWeight;
+
+}
+
+/// Test if this [string] contains only whitespace characters
+bool isWhitespace(String string) => string.codeUnits.every(
+      (c) => c == 0x09 || c == 0x20 || c == 0x0A || c == 0x0D);
+
+/// Special token indicating a line start
+final LINE_START = new SpaceToken(0);
+
+const DEFAULT_SPACE_WEIGHT = -1;
+
+/// Simple non-breaking printer
+class SimpleLinePrinter extends LinePrinter {
+
+  const SimpleLinePrinter();
+
+  String printLine(Line line) {
     var buffer = new StringBuffer();
-    tokens.forEach((tok) => buffer.write(tok.toString()));
+    line.tokens.forEach((tok) => buffer.write(tok.toString()));
     return buffer.toString();
   }
 
 }
 
 
-class LineToken {
+/// Describes a piece of text in a [Line].
+abstract class LineText {
+  int get length;
+  void addTo(Chunk chunk);
+}
+
+
+/// A working piece of text used in calculating line breaks
+class Chunk implements LineText {
+
+  final StringBuffer buffer = new StringBuffer();
+
+  int maxLength;
+  SpaceToken start;
+
+  Chunk({this.start, this.maxLength}) {
+    if (start == null) {
+      start = LINE_START;
+    }
+  }
+
+  bool fits(LineText text) => length + text.length < maxLength;
+
+  int get length => start.value.length + buffer.length;
+
+  void add(LineText text) {
+    text.addTo(this);
+  }
+
+  String toString() => buffer.toString();
+
+  void addTo(Chunk chunk) {
+    chunk.buffer.write(start.value);
+    chunk.buffer.write(buffer.toString());
+  }
+}
+
+
+class LineToken implements LineText {
 
   final String value;
 
   LineToken(this.value);
 
   String toString() => value;
+
+  int get length => value.length;
+
+  void addTo(Chunk chunk) {
+    chunk.buffer.write(value);
+  }
 }
 
+
 class SpaceToken extends LineToken {
 
-  SpaceToken(int n) : super(getSpaces(n));
+  final int breakWeight;
+
+  SpaceToken(int n, {this.breakWeight: DEFAULT_SPACE_WEIGHT}) :
+      super(getSpaces(n));
 }
 
+
 class TabToken extends LineToken {
 
   TabToken(int n) : super(getTabs(n));
@@ -74,7 +247,6 @@
 }
 
 
-
 class SourceWriter {
 
   final StringBuffer buffer = new StringBuffer();
@@ -82,20 +254,28 @@
 
   final String lineSeparator;
   int indentCount = 0;
-  
+
+  LinePrinter linePrinter;
   LineToken _lastToken;
-  
-  SourceWriter({this.indentCount: 0, this.lineSeparator: NEW_LINE}) {
-    currentLine = new Line(indent: indentCount);
+
+  SourceWriter({this.indentCount: 0, this.lineSeparator: NEW_LINE,
+      bool useTabs: false, int spacesPerIndent: 2, int maxLineLength: 80}) {
+    if (_USE_LINE_BREAKER) {
+      linePrinter = new SimpleLineBreaker(maxLineLength, (n) =>
+          getIndentString(n, useTabs: useTabs, spacesPerIndent: spacesPerIndent));
+    } else {
+      linePrinter = new SimpleLinePrinter();
+    }
+    currentLine = new Line(indent: indentCount, printer: linePrinter);
   }
 
   LineToken get lastToken => _lastToken;
-  
+
   _addToken(LineToken token) {
     _lastToken = token;
     currentLine.addToken(token);
   }
-  
+
   void indent() {
     ++indentCount;
   }
@@ -106,7 +286,7 @@
     }
     _addToken(new NewlineToken(this.lineSeparator));
     buffer.write(currentLine.toString());
-    currentLine = new Line(indent: indentCount);
+    currentLine = new Line(indent: indentCount, printer: linePrinter);
   }
 
   void newlines(int num) {
@@ -118,24 +298,24 @@
   void print(x) {
     _addToken(new LineToken(x));
   }
-  
+
   void println(String s) {
     print(s);
     newline();
   }
-  
+
   void space() {
     spaces(1);
   }
 
-  void spaces(n) {
-    currentLine.addSpaces(n);
+  void spaces(n, {breakWeight: DEFAULT_SPACE_WEIGHT}) {
+    currentLine.addSpaces(n, breakWeight: breakWeight);
   }
-  
+
   void unindent() {
     --indentCount;
   }
-  
+
   String toString() {
     var source = new StringBuffer(buffer.toString());
     if (!currentLine.isWhitespace()) {
@@ -186,8 +366,9 @@
 ];
 
 
-String getIndentString(int indentWidth, {bool useTabs: false}) =>
-    useTabs ? getTabs(indentWidth) : getSpaces(indentWidth);
+String getIndentString(int indentWidth, {bool useTabs: false,
+  int spacesPerIndent: 2}) => useTabs ? getTabs(indentWidth) :
+    getSpaces(indentWidth * spacesPerIndent);
 
 String getSpaces(int n) => n < SPACES.length ? SPACES[n] : repeat(' ', n);
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index bc61dc1..5c2b129a 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.11.1
+version: 0.11.7
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index 2d5f33a..182d035 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -87,42 +91,49 @@
 class IndexExpressionTest extends EngineTestCase {
   void test_inGetterContext_assignment_compound_left() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // a[i] += ?
     ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
     JUnitTestCase.assertTrue(expression.inGetterContext());
   }
 
   void test_inGetterContext_assignment_simple_left() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // a[i] = ?
     ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
     JUnitTestCase.assertFalse(expression.inGetterContext());
   }
 
   void test_inGetterContext_nonAssignment() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // a[i] + ?
     ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
     JUnitTestCase.assertTrue(expression.inGetterContext());
   }
 
   void test_inSetterContext_assignment_compound_left() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // a[i] += ?
     ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
     JUnitTestCase.assertTrue(expression.inSetterContext());
   }
 
   void test_inSetterContext_assignment_compound_right() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // ? += a[i]
     ASTFactory.assignmentExpression(null, TokenType.PLUS_EQ, expression);
     JUnitTestCase.assertFalse(expression.inSetterContext());
   }
 
   void test_inSetterContext_assignment_simple_left() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // a[i] = ?
     ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
     JUnitTestCase.assertTrue(expression.inSetterContext());
   }
 
   void test_inSetterContext_assignment_simple_right() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // ? = a[i]
     ASTFactory.assignmentExpression(null, TokenType.EQ, expression);
     JUnitTestCase.assertFalse(expression.inSetterContext());
   }
@@ -130,29 +141,34 @@
   void test_inSetterContext_nonAssignment() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
     ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
+    // a[i] + ?
     JUnitTestCase.assertFalse(expression.inSetterContext());
   }
 
   void test_inSetterContext_postfix() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
     ASTFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+    // a[i]++
     JUnitTestCase.assertTrue(expression.inSetterContext());
   }
 
   void test_inSetterContext_prefix_bang() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // !a[i]
     ASTFactory.prefixExpression(TokenType.BANG, expression);
     JUnitTestCase.assertFalse(expression.inSetterContext());
   }
 
   void test_inSetterContext_prefix_minusMinus() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // --a[i]
     ASTFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
     JUnitTestCase.assertTrue(expression.inSetterContext());
   }
 
   void test_inSetterContext_prefix_plusPlus() {
     IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"));
+    // ++a[i]
     ASTFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
     JUnitTestCase.assertTrue(expression.inSetterContext());
   }
@@ -212,6 +228,18 @@
 }
 
 class ClassDeclarationTest extends ParserTestCase {
+  void test_getConstructor() {
+    List<ConstructorInitializer> initializers = new List<ConstructorInitializer>();
+    ConstructorDeclaration defaultConstructor = ASTFactory.constructorDeclaration(ASTFactory.identifier3("Test"), null, ASTFactory.formalParameterList([]), initializers);
+    ConstructorDeclaration aConstructor = ASTFactory.constructorDeclaration(ASTFactory.identifier3("Test"), "a", ASTFactory.formalParameterList([]), initializers);
+    ConstructorDeclaration bConstructor = ASTFactory.constructorDeclaration(ASTFactory.identifier3("Test"), "b", ASTFactory.formalParameterList([]), initializers);
+    ClassDeclaration clazz = ASTFactory.classDeclaration(null, "Test", null, null, null, null, [defaultConstructor, aConstructor, bConstructor]);
+    JUnitTestCase.assertSame(defaultConstructor, clazz.getConstructor(null));
+    JUnitTestCase.assertSame(aConstructor, clazz.getConstructor("a"));
+    JUnitTestCase.assertSame(bConstructor, clazz.getConstructor("b"));
+    JUnitTestCase.assertSame(null, clazz.getConstructor("noSuchConstructor"));
+  }
+
   void test_getField() {
     VariableDeclaration aVar = ASTFactory.variableDeclaration("a");
     VariableDeclaration bVar = ASTFactory.variableDeclaration("b");
@@ -225,12 +253,29 @@
     JUnitTestCase.assertSame(null, clazz.getField("noSuchField"));
   }
 
+  void test_getMethod() {
+    MethodDeclaration aMethod = ASTFactory.methodDeclaration(null, null, null, null, ASTFactory.identifier3("a"), ASTFactory.formalParameterList([]));
+    MethodDeclaration bMethod = ASTFactory.methodDeclaration(null, null, null, null, ASTFactory.identifier3("b"), ASTFactory.formalParameterList([]));
+    ClassDeclaration clazz = ASTFactory.classDeclaration(null, "Test", null, null, null, null, [aMethod, bMethod]);
+    JUnitTestCase.assertSame(aMethod, clazz.getMethod("a"));
+    JUnitTestCase.assertSame(bMethod, clazz.getMethod("b"));
+    JUnitTestCase.assertSame(null, clazz.getMethod("noSuchMethod"));
+  }
+
   static dartSuite() {
     _ut.group('ClassDeclarationTest', () {
+      _ut.test('test_getConstructor', () {
+        final __test = new ClassDeclarationTest();
+        runJUnitTest(__test, __test.test_getConstructor);
+      });
       _ut.test('test_getField', () {
         final __test = new ClassDeclarationTest();
         runJUnitTest(__test, __test.test_getField);
       });
+      _ut.test('test_getMethod', () {
+        final __test = new ClassDeclarationTest();
+        runJUnitTest(__test, __test.test_getMethod);
+      });
     });
   }
 }
@@ -1035,7 +1080,7 @@
         "}"]);
     CompilationUnit unit = ParserTestCase.parseCompilationUnit(source, []);
     List<ASTNode> nodes = new List<ASTNode>();
-    BreadthFirstVisitor<Object> visitor = new BreadthFirstVisitor_20(nodes);
+    BreadthFirstVisitor<Object> visitor = new BreadthFirstVisitor_BreadthFirstVisitorTest_testIt(nodes);
     visitor.visitAllNodes(unit);
     EngineTestCase.assertSize(59, nodes);
     EngineTestCase.assertInstanceOf(CompilationUnit, nodes[0]);
@@ -1055,10 +1100,10 @@
   }
 }
 
-class BreadthFirstVisitor_20 extends BreadthFirstVisitor<Object> {
+class BreadthFirstVisitor_BreadthFirstVisitorTest_testIt extends BreadthFirstVisitor<Object> {
   List<ASTNode> nodes;
 
-  BreadthFirstVisitor_20(this.nodes) : super();
+  BreadthFirstVisitor_BreadthFirstVisitorTest_testIt(this.nodes) : super();
 
   Object visitNode(ASTNode node) {
     nodes.add(node);
@@ -1889,6 +1934,71 @@
   }
 }
 
+class SimpleStringLiteralTest extends ParserTestCase {
+  void test_getValueOffset() {
+    JUnitTestCase.assertEquals(1, new SimpleStringLiteral(TokenFactory.token2("'X'"), "X").valueOffset);
+    JUnitTestCase.assertEquals(1, new SimpleStringLiteral(TokenFactory.token2("\"X\""), "X").valueOffset);
+    JUnitTestCase.assertEquals(3, new SimpleStringLiteral(TokenFactory.token2("\"\"\"X\"\"\""), "X").valueOffset);
+    JUnitTestCase.assertEquals(3, new SimpleStringLiteral(TokenFactory.token2("'''X'''"), "X").valueOffset);
+    JUnitTestCase.assertEquals(2, new SimpleStringLiteral(TokenFactory.token2("r'X'"), "X").valueOffset);
+    JUnitTestCase.assertEquals(2, new SimpleStringLiteral(TokenFactory.token2("r\"X\""), "X").valueOffset);
+    JUnitTestCase.assertEquals(4, new SimpleStringLiteral(TokenFactory.token2("r\"\"\"X\"\"\""), "X").valueOffset);
+    JUnitTestCase.assertEquals(4, new SimpleStringLiteral(TokenFactory.token2("r'''X'''"), "X").valueOffset);
+  }
+
+  void test_isMultiline() {
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("'X'"), "X").isMultiline);
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("r'X'"), "X").isMultiline);
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("\"X\""), "X").isMultiline);
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("r\"X\""), "X").isMultiline);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("'''X'''"), "X").isMultiline);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("r'''X'''"), "X").isMultiline);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("\"\"\"X\"\"\""), "X").isMultiline);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("r\"\"\"X\"\"\""), "X").isMultiline);
+  }
+
+  void test_isRaw() {
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("'X'"), "X").isRaw);
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("\"X\""), "X").isRaw);
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("\"\"\"X\"\"\""), "X").isRaw);
+    JUnitTestCase.assertFalse(new SimpleStringLiteral(TokenFactory.token2("'''X'''"), "X").isRaw);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("r'X'"), "X").isRaw);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("r\"X\""), "X").isRaw);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("r\"\"\"X\"\"\""), "X").isRaw);
+    JUnitTestCase.assertTrue(new SimpleStringLiteral(TokenFactory.token2("r'''X'''"), "X").isRaw);
+  }
+
+  void test_simple() {
+    Token token = TokenFactory.token2("'value'");
+    SimpleStringLiteral stringLiteral = new SimpleStringLiteral(token, "value");
+    JUnitTestCase.assertSame(token, stringLiteral.literal);
+    JUnitTestCase.assertSame(token, stringLiteral.beginToken);
+    JUnitTestCase.assertSame(token, stringLiteral.endToken);
+    JUnitTestCase.assertEquals("value", stringLiteral.value);
+  }
+
+  static dartSuite() {
+    _ut.group('SimpleStringLiteralTest', () {
+      _ut.test('test_getValueOffset', () {
+        final __test = new SimpleStringLiteralTest();
+        runJUnitTest(__test, __test.test_getValueOffset);
+      });
+      _ut.test('test_isMultiline', () {
+        final __test = new SimpleStringLiteralTest();
+        runJUnitTest(__test, __test.test_isMultiline);
+      });
+      _ut.test('test_isRaw', () {
+        final __test = new SimpleStringLiteralTest();
+        runJUnitTest(__test, __test.test_isRaw);
+      });
+      _ut.test('test_simple', () {
+        final __test = new SimpleStringLiteralTest();
+        runJUnitTest(__test, __test.test_simple);
+      });
+    });
+  }
+}
+
 class ToSourceVisitorTest extends EngineTestCase {
   void test_visitAdjacentStrings() {
     assertSource("'a' 'b'", ASTFactory.adjacentStrings([ASTFactory.string2("a"), ASTFactory.string2("b")]));
@@ -2099,7 +2209,7 @@
   }
 
   void test_visitCompilationUnit_directive_declaration() {
-    assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([ASTFactory.libraryDirective2("l") as Directive]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember])));
+    assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([ASTFactory.libraryDirective2("l")]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")])])));
   }
 
   void test_visitCompilationUnit_empty() {
@@ -2119,7 +2229,7 @@
   }
 
   void test_visitCompilationUnit_script_directives_declarations() {
-    assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([ASTFactory.libraryDirective2("l") as Directive]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember])));
+    assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([ASTFactory.libraryDirective2("l")]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")])])));
   }
 
   void test_visitConditionalExpression() {
@@ -2140,7 +2250,7 @@
 
   void test_visitConstructorDeclaration_multipleInitializers() {
     assertSource("C() : a = b, c = d {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([
-        ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer,
+        ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")),
         ASTFactory.constructorFieldInitializer(false, "c", ASTFactory.identifier3("d"))]), ASTFactory.blockFunctionBody2([])));
   }
 
@@ -2155,7 +2265,7 @@
   }
 
   void test_visitConstructorDeclaration_singleInitializer() {
-    assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer]), ASTFactory.blockFunctionBody2([])));
+    assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b"))]), ASTFactory.blockFunctionBody2([])));
   }
 
   void test_visitConstructorFieldInitializer_withoutThis() {
@@ -2219,7 +2329,7 @@
   }
 
   void test_visitExportDirective_combinator() {
-    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [ASTFactory.showCombinator([ASTFactory.identifier3("A")]) as Combinator]));
+    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [ASTFactory.showCombinator([ASTFactory.identifier3("A")])]));
   }
 
   void test_visitExportDirective_combinators() {
@@ -2363,11 +2473,11 @@
   }
 
   void test_visitForStatement_c() {
-    assertSource("for (; c;) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), null, ASTFactory.block([])));
+    assertSource("for (; c;) {}", ASTFactory.forStatement(null, ASTFactory.identifier3("c"), null, ASTFactory.block([])));
   }
 
   void test_visitForStatement_cu() {
-    assertSource("for (; c; u) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
+    assertSource("for (; c; u) {}", ASTFactory.forStatement(null, ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u")]), ASTFactory.block([])));
   }
 
   void test_visitForStatement_e() {
@@ -2379,11 +2489,11 @@
   }
 
   void test_visitForStatement_ecu() {
-    assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
+    assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u")]), ASTFactory.block([])));
   }
 
   void test_visitForStatement_eu() {
-    assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
+    assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, ASTFactory.list([ASTFactory.identifier3("u")]), ASTFactory.block([])));
   }
 
   void test_visitForStatement_i() {
@@ -2395,15 +2505,15 @@
   }
 
   void test_visitForStatement_icu() {
-    assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
+    assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u")]), ASTFactory.block([])));
   }
 
   void test_visitForStatement_iu() {
-    assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
+    assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([ASTFactory.identifier3("u")]), ASTFactory.block([])));
   }
 
   void test_visitForStatement_u() {
-    assertSource("for (;; u) {}", ASTFactory.forStatement(null as Expression, null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
+    assertSource("for (;; u) {}", ASTFactory.forStatement(null, null, ASTFactory.list([ASTFactory.identifier3("u")]), ASTFactory.block([])));
   }
 
   void test_visitFunctionDeclaration_getter() {
@@ -3981,5 +4091,6 @@
   IndexExpressionTest.dartSuite();
   NodeListTest.dartSuite();
   SimpleIdentifierTest.dartSuite();
+  SimpleStringLiteralTest.dartSuite();
   VariableDeclarationTest.dartSuite();
 }
\ No newline at end of file
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
index c7d032b..432f5fc 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -14,7 +18,7 @@
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 import 'ast_test.dart' show ASTFactory;
-import 'resolver_test.dart' show TestTypeProvider;
+import 'resolver_test.dart' show TestTypeProvider, AnalysisContextHelper;
 
 class ElementLocationImplTest extends EngineTestCase {
   void test_create_encoding() {
@@ -224,12 +228,73 @@
     }
   }
 
+  void test_getVisibleLibraries_cycle() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    libraryA.imports = <ImportElementImpl> [ElementFactory.importFor(library, null, [])];
+    library.imports = <ImportElementImpl> [ElementFactory.importFor(libraryA, null, [])];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library, libraryA], libraries);
+  }
+
+  void test_getVisibleLibraries_directExports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    library.exports = <ExportElementImpl> [ElementFactory.exportFor(libraryA, [])];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library], libraries);
+  }
+
+  void test_getVisibleLibraries_directImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    library.imports = <ImportElementImpl> [ElementFactory.importFor(libraryA, null, [])];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library, libraryA], libraries);
+  }
+
+  void test_getVisibleLibraries_indirectExports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
+    libraryA.exports = <ExportElementImpl> [ElementFactory.exportFor(libraryAA, [])];
+    library.imports = <ImportElementImpl> [ElementFactory.importFor(libraryA, null, [])];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library, libraryA, libraryAA], libraries);
+  }
+
+  void test_getVisibleLibraries_indirectImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    LibraryElementImpl libraryA = ElementFactory.library(context, "A");
+    LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
+    LibraryElementImpl libraryB = ElementFactory.library(context, "B");
+    libraryA.imports = <ImportElementImpl> [ElementFactory.importFor(libraryAA, null, [])];
+    library.imports = <ImportElementImpl> [
+        ElementFactory.importFor(libraryA, null, []),
+        ElementFactory.importFor(libraryB, null, [])];
+    List<LibraryElement> libraries = library.visibleLibraries;
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library, libraryA, libraryAA, libraryB], libraries);
+  }
+
+  void test_getVisibleLibraries_noImports() {
+    AnalysisContext context = createAnalysisContext();
+    LibraryElementImpl library = ElementFactory.library(context, "app");
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library], library.visibleLibraries);
+  }
+
   void test_isUpToDate() {
     AnalysisContext context = createAnalysisContext();
     context.sourceFactory = new SourceFactory.con2([]);
     LibraryElement library = ElementFactory.library(context, "foo");
     context.sourceFactory.setContents(library.definingCompilationUnit.source, "sdfsdff");
+    // Assert that we are not up to date if the target has an old time stamp.
     JUnitTestCase.assertFalse(library.isUpToDate2(0));
+    // Assert that we are up to date with a target modification time in the future.
     JUnitTestCase.assertTrue(library.isUpToDate2(JavaSystem.currentTimeMillis() + 1000));
   }
 
@@ -261,6 +326,30 @@
         final __test = new LibraryElementImplTest();
         runJUnitTest(__test, __test.test_getPrefixes);
       });
+      _ut.test('test_getVisibleLibraries_cycle', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getVisibleLibraries_cycle);
+      });
+      _ut.test('test_getVisibleLibraries_directExports', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getVisibleLibraries_directExports);
+      });
+      _ut.test('test_getVisibleLibraries_directImports', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getVisibleLibraries_directImports);
+      });
+      _ut.test('test_getVisibleLibraries_indirectExports', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getVisibleLibraries_indirectExports);
+      });
+      _ut.test('test_getVisibleLibraries_indirectImports', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getVisibleLibraries_indirectImports);
+      });
+      _ut.test('test_getVisibleLibraries_noImports', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getVisibleLibraries_noImports);
+      });
       _ut.test('test_isUpToDate', () {
         final __test = new LibraryElementImplTest();
         runJUnitTest(__test, __test.test_isUpToDate);
@@ -287,18 +376,21 @@
   void test_isMoreSpecificThan_typeArguments_bottom() {
     TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << bottom
     JUnitTestCase.assertTrue(type.isMoreSpecificThan(BottomTypeImpl.instance));
   }
 
   void test_isMoreSpecificThan_typeArguments_dynamic() {
     TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << dynamic
     JUnitTestCase.assertTrue(type.isMoreSpecificThan(DynamicTypeImpl.instance));
   }
 
   void test_isMoreSpecificThan_typeArguments_object() {
     TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << Object
     JUnitTestCase.assertTrue(type.isMoreSpecificThan(ElementFactory.object.type));
   }
 
@@ -310,16 +402,22 @@
     TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);
     typeParameterT.bound = typeParameterTypeU;
     typeParameterU.bound = typeParameterTypeU;
+    // <T extends U> and <U extends T>
+    // T << S
     JUnitTestCase.assertFalse(typeParameterTypeT.isMoreSpecificThan(classS.type));
   }
 
   void test_isMoreSpecificThan_typeArguments_self() {
     TypeParameterElementImpl element = new TypeParameterElementImpl(ASTFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
+    // E << E
     JUnitTestCase.assertTrue(type.isMoreSpecificThan(type));
   }
 
   void test_isMoreSpecificThan_typeArguments_transitivity_interfaceTypes() {
+    //  class A {}
+    //  class B extends A {}
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     InterfaceType typeA = classA.type;
@@ -327,6 +425,8 @@
     TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(ASTFactory.identifier3("T"));
     typeParameterT.bound = typeB;
     TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);
+    // <T extends B>
+    // T << A
     JUnitTestCase.assertTrue(typeParameterTypeT.isMoreSpecificThan(typeA));
   }
 
@@ -338,6 +438,8 @@
     TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(ASTFactory.identifier3("T"));
     typeParameterT.bound = typeParameterTypeU;
     TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);
+    // <T extends U> and <U extends S>
+    // T << S
     JUnitTestCase.assertTrue(typeParameterTypeT.isMoreSpecificThan(classS.type));
   }
 
@@ -346,6 +448,8 @@
     TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(ASTFactory.identifier3("T"));
     typeParameterT.bound = classS.type;
     TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);
+    // <T extends S>
+    // T << S
     JUnitTestCase.assertTrue(typeParameterTypeT.isMoreSpecificThan(classS.type));
   }
 
@@ -429,6 +533,17 @@
   }
 
   void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
+    //
+    //   Object
+    //     |
+    //     A
+    //    / \
+    //   B   C
+    //   |   |
+    //   |   D
+    //    \ /
+    //     E
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement2("B", []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -438,22 +553,42 @@
     classC.interfaces = <InterfaceType> [classA.type];
     classD.interfaces = <InterfaceType> [classC.type];
     classE.interfaces = <InterfaceType> [classB.type, classD.type];
+    // assertion: even though the longest path to Object for typeB is 2, and typeE implements typeB,
+    // the longest path for typeE is 4 since it also implements typeD
     JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type));
     JUnitTestCase.assertEquals(4, InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type));
   }
 
   void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
+    //
+    //   Object
+    //     |
+    //     A
+    //    / \
+    //   B   C
+    //   |   |
+    //   |   D
+    //    \ /
+    //     E
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElement classC = ElementFactory.classElement("C", classA.type, []);
     ClassElement classD = ElementFactory.classElement("D", classC.type, []);
     ClassElementImpl classE = ElementFactory.classElement("E", classB.type, []);
     classE.interfaces = <InterfaceType> [classD.type];
+    // assertion: even though the longest path to Object for typeB is 2, and typeE extends typeB,
+    // the longest path for typeE is 4 since it also implements typeD
     JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type));
     JUnitTestCase.assertEquals(4, InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type));
   }
 
   void test_computeLongestInheritancePathToObject_object() {
+    //
+    //   Object
+    //     |
+    //     A
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     InterfaceType object = classA.supertype;
     JUnitTestCase.assertEquals(0, InterfaceTypeImpl.computeLongestInheritancePathToObject(object));
@@ -467,6 +602,15 @@
   }
 
   void test_computeLongestInheritancePathToObject_singleInterfacePath() {
+    //
+    //   Object
+    //     |
+    //     A
+    //     |
+    //     B
+    //     |
+    //     C
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement2("B", []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -478,6 +622,15 @@
   }
 
   void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
+    //
+    //   Object
+    //     |
+    //     A
+    //     |
+    //     B
+    //     |
+    //     C
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElement classC = ElementFactory.classElement("C", classB.type, []);
@@ -496,11 +649,13 @@
     classC.interfaces = <InterfaceType> [classA.type];
     classD.interfaces = <InterfaceType> [classC.type];
     classE.interfaces = <InterfaceType> [classB.type, classD.type];
+    // D
     Set<InterfaceType> superinterfacesOfD = InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
     EngineTestCase.assertSize3(3, superinterfacesOfD);
     JUnitTestCase.assertTrue(superinterfacesOfD.contains(ElementFactory.object.type));
     JUnitTestCase.assertTrue(superinterfacesOfD.contains(classA.type));
     JUnitTestCase.assertTrue(superinterfacesOfD.contains(classC.type));
+    // E
     Set<InterfaceType> superinterfacesOfE = InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
     EngineTestCase.assertSize3(5, superinterfacesOfE);
     JUnitTestCase.assertTrue(superinterfacesOfE.contains(ElementFactory.object.type));
@@ -517,11 +672,13 @@
     ClassElement classD = ElementFactory.classElement("D", classC.type, []);
     ClassElementImpl classE = ElementFactory.classElement("E", classB.type, []);
     classE.interfaces = <InterfaceType> [classD.type];
+    // D
     Set<InterfaceType> superinterfacesOfD = InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
     EngineTestCase.assertSize3(3, superinterfacesOfD);
     JUnitTestCase.assertTrue(superinterfacesOfD.contains(ElementFactory.object.type));
     JUnitTestCase.assertTrue(superinterfacesOfD.contains(classA.type));
     JUnitTestCase.assertTrue(superinterfacesOfD.contains(classC.type));
+    // E
     Set<InterfaceType> superinterfacesOfE = InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
     EngineTestCase.assertSize3(5, superinterfacesOfE);
     JUnitTestCase.assertTrue(superinterfacesOfE.contains(ElementFactory.object.type));
@@ -545,13 +702,16 @@
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
     classB.interfaces = <InterfaceType> [classA.type];
     classC.interfaces = <InterfaceType> [classB.type];
+    // A
     Set<InterfaceType> superinterfacesOfA = InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
     EngineTestCase.assertSize3(1, superinterfacesOfA);
     JUnitTestCase.assertTrue(superinterfacesOfA.contains(ElementFactory.object.type));
+    // B
     Set<InterfaceType> superinterfacesOfB = InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
     EngineTestCase.assertSize3(2, superinterfacesOfB);
     JUnitTestCase.assertTrue(superinterfacesOfB.contains(ElementFactory.object.type));
     JUnitTestCase.assertTrue(superinterfacesOfB.contains(classA.type));
+    // C
     Set<InterfaceType> superinterfacesOfC = InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
     EngineTestCase.assertSize3(3, superinterfacesOfC);
     JUnitTestCase.assertTrue(superinterfacesOfC.contains(ElementFactory.object.type));
@@ -560,16 +720,26 @@
   }
 
   void test_computeSuperinterfaceSet_singleSuperclassPath() {
+    //
+    //  A
+    //  |
+    //  B
+    //  |
+    //  C
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElement classC = ElementFactory.classElement("C", classB.type, []);
+    // A
     Set<InterfaceType> superinterfacesOfA = InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
     EngineTestCase.assertSize3(1, superinterfacesOfA);
     JUnitTestCase.assertTrue(superinterfacesOfA.contains(ElementFactory.object.type));
+    // B
     Set<InterfaceType> superinterfacesOfB = InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
     EngineTestCase.assertSize3(2, superinterfacesOfB);
     JUnitTestCase.assertTrue(superinterfacesOfB.contains(ElementFactory.object.type));
     JUnitTestCase.assertTrue(superinterfacesOfB.contains(classA.type));
+    // C
     Set<InterfaceType> superinterfacesOfC = InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
     EngineTestCase.assertSize3(3, superinterfacesOfC);
     JUnitTestCase.assertTrue(superinterfacesOfC.contains(ElementFactory.object.type));
@@ -603,6 +773,9 @@
   }
 
   void test_getGetter_implemented() {
+    //
+    // class A { g {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String getterName = "g";
     PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, null);
@@ -612,12 +785,18 @@
   }
 
   void test_getGetter_parameterized() {
+    //
+    // class A<E> { E get g {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     Type2 typeE = classA.type.typeArguments[0];
     String getterName = "g";
     PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, typeE);
     classA.accessors = <PropertyAccessorElement> [getterG];
     (getterG.type as FunctionTypeImpl).typeArguments = classA.type.typeArguments;
+    //
+    // A<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
     typeAI.typeArguments = <Type2> [typeI];
@@ -628,12 +807,18 @@
   }
 
   void test_getGetter_unimplemented() {
+    //
+    // class A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     JUnitTestCase.assertNull(typeA.getGetter("g"));
   }
 
   void test_getInterfaces_nonParameterized() {
+    //
+    // class C implements A, B
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement2("B", []);
@@ -651,12 +836,19 @@
   }
 
   void test_getInterfaces_parameterized() {
+    //
+    // class A<E>
+    // class B<F> implements A<F>
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
     InterfaceType typeB = classB.type;
     InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
     typeAF.typeArguments = <Type2> [typeB.typeArguments[0]];
     classB.interfaces = <InterfaceType> [typeAF];
+    //
+    // B<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
     typeBI.typeArguments = <Type2> [typeI];
@@ -668,6 +860,11 @@
   }
 
   void test_getLeastUpperBound_directInterfaceCase() {
+    //
+    // class A
+    // class B implements A
+    // class C implements B
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement2("B", []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -681,6 +878,11 @@
   }
 
   void test_getLeastUpperBound_directSubclassCase() {
+    //
+    // class A
+    // class B extends A
+    // class C extends B
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement("C", classB.type, []);
@@ -697,6 +899,12 @@
   }
 
   void test_getLeastUpperBound_mixinCase() {
+    //
+    // class A
+    // class B extends A
+    // class C extends A
+    // class D extends B with M, N, O, P
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElement classC = ElementFactory.classElement("C", classA.type, []);
@@ -724,8 +932,11 @@
     InterfaceType typeA = classA.type;
     InterfaceType typeB = classB.type;
     Type2 typeObject = typeA.element.supertype;
+    // assert that object does not have a super type
     JUnitTestCase.assertNull((typeObject.element as ClassElement).supertype);
+    // assert that both A and B have the same super type of Object
     JUnitTestCase.assertEquals(typeObject, typeB.element.supertype);
+    // finally, assert that the only least upper bound of A and B is Object
     JUnitTestCase.assertEquals(typeObject, typeA.getLeastUpperBound(typeB));
   }
 
@@ -856,6 +1067,10 @@
   }
 
   void test_getLeastUpperBound_typeParameters_different() {
+    //
+    // class List<int>
+    // class List<double>
+    //
     InterfaceType listType = _typeProvider.listType;
     InterfaceType intType = _typeProvider.intType;
     InterfaceType doubleType = _typeProvider.doubleType;
@@ -865,6 +1080,10 @@
   }
 
   void test_getLeastUpperBound_typeParameters_same() {
+    //
+    // List<int>
+    // List<int>
+    //
     InterfaceType listType = _typeProvider.listType;
     InterfaceType intType = _typeProvider.intType;
     InterfaceType listOfIntType = listType.substitute4(<Type2> [intType]);
@@ -872,6 +1091,9 @@
   }
 
   void test_getMethod_implemented() {
+    //
+    // class A { m() {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String methodName = "m";
     MethodElementImpl methodM = ElementFactory.methodElement(methodName, null, []);
@@ -881,12 +1103,18 @@
   }
 
   void test_getMethod_parameterized() {
+    //
+    // class A<E> { E m(E p) {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     Type2 typeE = classA.type.typeArguments[0];
     String methodName = "m";
     MethodElementImpl methodM = ElementFactory.methodElement(methodName, typeE, [typeE]);
     classA.methods = <MethodElement> [methodM];
     (methodM.type as FunctionTypeImpl).typeArguments = classA.type.typeArguments;
+    //
+    // A<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
     typeAI.typeArguments = <Type2> [typeI];
@@ -900,6 +1128,9 @@
   }
 
   void test_getMethod_unimplemented() {
+    //
+    // class A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     JUnitTestCase.assertNull(typeA.getMethod("m"));
@@ -921,6 +1152,9 @@
   }
 
   void test_getMixins_nonParameterized() {
+    //
+    // class C extends Object with A, B
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement2("B", []);
@@ -938,12 +1172,19 @@
   }
 
   void test_getMixins_parameterized() {
+    //
+    // class A<E>
+    // class B<F> extends Object with A<F>
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
     InterfaceType typeB = classB.type;
     InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
     typeAF.typeArguments = <Type2> [typeB.typeArguments[0]];
     classB.mixins = <InterfaceType> [typeAF];
+    //
+    // B<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
     typeBI.typeArguments = <Type2> [typeI];
@@ -955,6 +1196,9 @@
   }
 
   void test_getSetter_implemented() {
+    //
+    // class A { s() {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String setterName = "s";
     PropertyAccessorElement setterS = ElementFactory.setterElement(setterName, false, null);
@@ -964,12 +1208,18 @@
   }
 
   void test_getSetter_parameterized() {
+    //
+    // class A<E> { set s(E p) {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     Type2 typeE = classA.type.typeArguments[0];
     String setterName = "s";
     PropertyAccessorElement setterS = ElementFactory.setterElement(setterName, false, typeE);
     classA.accessors = <PropertyAccessorElement> [setterS];
     (setterS.type as FunctionTypeImpl).typeArguments = classA.type.typeArguments;
+    //
+    // A<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
     typeAI.typeArguments = <Type2> [typeI];
@@ -982,12 +1232,18 @@
   }
 
   void test_getSetter_unimplemented() {
+    //
+    // class A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     JUnitTestCase.assertNull(typeA.getSetter("s"));
   }
 
   void test_getSuperclass_nonParameterized() {
+    //
+    // class B extends A
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement("B", typeA, []);
@@ -996,12 +1252,19 @@
   }
 
   void test_getSuperclass_parameterized() {
+    //
+    // class A<E>
+    // class B<F> extends A<F>
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
     InterfaceType typeB = classB.type;
     InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
     typeAF.typeArguments = <Type2> [typeB.typeArguments[0]];
     classB.supertype = typeAF;
+    //
+    // B<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
     typeBI.typeArguments = <Type2> [typeI];
@@ -1022,6 +1285,15 @@
   }
 
   void test_isAssignableTo_typeVariables() {
+    //
+    // class A<E> {}
+    // class B<F, G> {
+    //   A<F> af;
+    //   f (A<G> ag) {
+    //     af = ag;
+    //   }
+    // }
+    //
     ClassElement classA = ElementFactory.classElement2("A", ["E"]);
     ClassElement classB = ElementFactory.classElement2("B", ["F", "G"]);
     InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
@@ -1093,6 +1365,7 @@
     InterfaceType typeA = classA.type;
     InterfaceType typeB = classB.type;
     JUnitTestCase.assertTrue(typeB.isMoreSpecificThan(typeA));
+    // the opposite test tests a different branch in isMoreSpecificThan()
     JUnitTestCase.assertFalse(typeA.isMoreSpecificThan(typeB));
   }
 
@@ -1107,6 +1380,11 @@
   }
 
   void test_isMoreSpecificThan_transitive_interface() {
+    //
+    //  class A {}
+    //  class B extends A {}
+    //  class C implements B {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -1117,6 +1395,11 @@
   }
 
   void test_isMoreSpecificThan_transitive_mixin() {
+    //
+    //  class A {}
+    //  class B extends A {}
+    //  class C with B {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -1127,6 +1410,11 @@
   }
 
   void test_isMoreSpecificThan_transitive_recursive() {
+    //
+    //  class A extends B {}
+    //  class B extends A {}
+    //  class C {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -1137,6 +1425,11 @@
   }
 
   void test_isMoreSpecificThan_transitive_superclass() {
+    //
+    //  class A {}
+    //  class B extends A {}
+    //  class C extends B {}
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElement classC = ElementFactory.classElement("C", classB.type, []);
@@ -1163,6 +1456,12 @@
   }
 
   void test_isSubtypeOf_function() {
+    //
+    // void f(String s) {}
+    // class A {
+    //   void call(String s) {}
+    // }
+    //
     InterfaceType stringType = _typeProvider.stringType;
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     classA.methods = <MethodElement> [ElementFactory.methodElement("call", VoidTypeImpl.instance, [stringType])];
@@ -1186,6 +1485,11 @@
   }
 
   void test_isSubtypeOf_mixins() {
+    //
+    // class A {}
+    // class B extends A {}
+    // class C with B {}
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -1215,6 +1519,11 @@
   }
 
   void test_isSubtypeOf_transitive_recursive() {
+    //
+    //  class A extends B {}
+    //  class B extends A {}
+    //  class C {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -1248,13 +1557,18 @@
     typeAI.typeArguments = <Type2> [classI.type];
     typeAJ.typeArguments = <Type2> [classJ.type];
     typeAK.typeArguments = <Type2> [classK.type];
+    // A<J> <: A<I> since J <: I
     JUnitTestCase.assertTrue(typeAJ.isSubtypeOf(typeAI));
     JUnitTestCase.assertFalse(typeAI.isSubtypeOf(typeAJ));
+    // A<I> <: A<I> since I <: I
     JUnitTestCase.assertTrue(typeAI.isSubtypeOf(typeAI));
+    // A <: A<I> and A <: A<J>
     JUnitTestCase.assertTrue(typeA_dynamic.isSubtypeOf(typeAI));
     JUnitTestCase.assertTrue(typeA_dynamic.isSubtypeOf(typeAJ));
+    // A<I> <: A and A<J> <: A
     JUnitTestCase.assertTrue(typeAI.isSubtypeOf(typeA_dynamic));
     JUnitTestCase.assertTrue(typeAJ.isSubtypeOf(typeA_dynamic));
+    // A<I> !<: A<K> and A<K> !<: A<I>
     JUnitTestCase.assertFalse(typeAI.isSubtypeOf(typeAK));
     JUnitTestCase.assertFalse(typeAK.isSubtypeOf(typeAI));
   }
@@ -1302,6 +1616,11 @@
   }
 
   void test_isSupertypeOf_mixins() {
+    //
+    // class A {}
+    // class B extends A {}
+    // class C with B {}
+    //
     ClassElement classA = ElementFactory.classElement2("A", []);
     ClassElement classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
@@ -1331,6 +1650,9 @@
   }
 
   void test_lookUpGetter_implemented() {
+    //
+    // class A { g {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String getterName = "g";
     PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, null);
@@ -1343,6 +1665,10 @@
   }
 
   void test_lookUpGetter_inherited() {
+    //
+    // class A { g {} }
+    // class B extends A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String getterName = "g";
     PropertyAccessorElement getterG = ElementFactory.getterElement(getterName, false, null);
@@ -1356,6 +1682,10 @@
   }
 
   void test_lookUpGetter_recursive() {
+    //
+    // class A extends B {}
+    // class B extends A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement("B", typeA, []);
@@ -1367,6 +1697,9 @@
   }
 
   void test_lookUpGetter_unimplemented() {
+    //
+    // class A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     LibraryElementImpl library = ElementFactory.library(createAnalysisContext(), "lib");
@@ -1376,6 +1709,9 @@
   }
 
   void test_lookUpMethod_implemented() {
+    //
+    // class A { m() {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String methodName = "m";
     MethodElementImpl methodM = ElementFactory.methodElement(methodName, null, []);
@@ -1388,6 +1724,10 @@
   }
 
   void test_lookUpMethod_inherited() {
+    //
+    // class A { m() {} }
+    // class B extends A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String methodName = "m";
     MethodElementImpl methodM = ElementFactory.methodElement(methodName, null, []);
@@ -1401,6 +1741,10 @@
   }
 
   void test_lookUpMethod_parameterized() {
+    //
+    // class A<E> { E m(E p) {} }
+    // class B<F> extends A<F> {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
     Type2 typeE = classA.type.typeArguments[0];
     String methodName = "m";
@@ -1415,6 +1759,9 @@
     LibraryElementImpl library = ElementFactory.library(createAnalysisContext(), "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
     (unit as CompilationUnitElementImpl).types = <ClassElement> [classA];
+    //
+    // B<I>
+    //
     InterfaceType typeI = ElementFactory.classElement2("I", []).type;
     InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
     typeBI.typeArguments = <Type2> [typeI];
@@ -1428,6 +1775,10 @@
   }
 
   void test_lookUpMethod_recursive() {
+    //
+    // class A extends B {}
+    // class B extends A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement("B", typeA, []);
@@ -1439,6 +1790,9 @@
   }
 
   void test_lookUpMethod_unimplemented() {
+    //
+    // class A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     LibraryElementImpl library = ElementFactory.library(createAnalysisContext(), "lib");
@@ -1448,6 +1802,9 @@
   }
 
   void test_lookUpSetter_implemented() {
+    //
+    // class A { s(x) {} }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String setterName = "s";
     PropertyAccessorElement setterS = ElementFactory.setterElement(setterName, false, null);
@@ -1460,6 +1817,10 @@
   }
 
   void test_lookUpSetter_inherited() {
+    //
+    // class A { s(x) {} }
+    // class B extends A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String setterName = "g";
     PropertyAccessorElement setterS = ElementFactory.setterElement(setterName, false, null);
@@ -1473,6 +1834,10 @@
   }
 
   void test_lookUpSetter_recursive() {
+    //
+    // class A extends B {}
+    // class B extends A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement("B", typeA, []);
@@ -1484,6 +1849,9 @@
   }
 
   void test_lookUpSetter_unimplemented() {
+    //
+    // class A {}
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     LibraryElementImpl library = ElementFactory.library(createAnalysisContext(), "lib");
@@ -2119,14 +2487,17 @@
   static FunctionElementImpl functionElement2(String functionName, ClassElement returnElement) => functionElement3(functionName, returnElement, null, null);
 
   static FunctionElementImpl functionElement3(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) {
+    // We don't create parameter elements because we don't have parameter names
     FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3(functionName));
     FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionElement.type = functionType;
+    // return type
     if (returnElement == null) {
       functionElement.returnType = VoidTypeImpl.instance;
     } else {
       functionElement.returnType = returnElement.type;
     }
+    // parameters
     int normalCount = normalParameters == null ? 0 : normalParameters.length;
     int optionalCount = optionalParameters == null ? 0 : optionalParameters.length;
     int totalCount = normalCount + optionalCount;
@@ -2143,6 +2514,7 @@
       parameters[i] = parameter;
     }
     functionElement.parameters = parameters;
+    // done
     return functionElement;
   }
 
@@ -2150,6 +2522,7 @@
     FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier3(functionName));
     FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
     functionElement.type = functionType;
+    // parameters
     int normalCount = normalParameters == null ? 0 : normalParameters.length;
     int nameCount = names == null ? 0 : names.length;
     int typeCount = namedParameters == null ? 0 : namedParameters.length;
@@ -2172,6 +2545,7 @@
       }
     }
     functionElement.parameters = parameters;
+    // return type
     if (returnElement == null) {
       functionElement.returnType = VoidTypeImpl.instance;
     } else {
@@ -2188,7 +2562,7 @@
 
   static ClassElementImpl get object {
     if (_objectElement == null) {
-      _objectElement = classElement("Object", null as InterfaceType, []);
+      _objectElement = classElement("Object", null, []);
     }
     return _objectElement;
   }
@@ -2210,7 +2584,7 @@
   }
 
   static ImportElementImpl importFor(LibraryElement importedLibrary, PrefixElement prefix, List<NamespaceCombinator> combinators) {
-    ImportElementImpl spec = new ImportElementImpl();
+    ImportElementImpl spec = new ImportElementImpl(0);
     spec.importedLibrary = importedLibrary;
     spec.prefix = prefix;
     spec.combinators = combinators;
@@ -2415,6 +2789,16 @@
     EngineTestCase.assertLength(1, supers);
   }
 
+  void test_getField() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    String fieldName = "f";
+    FieldElementImpl field = ElementFactory.fieldElement(fieldName, false, false, false, null);
+    classA.fields = <FieldElement> [field];
+    JUnitTestCase.assertSame(field, classA.getField(fieldName));
+    // no such field
+    JUnitTestCase.assertSame(null, classA.getField("noSuchField"));
+  }
+
   void test_getMethod_declared() {
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String methodName = "m";
@@ -2431,6 +2815,31 @@
     JUnitTestCase.assertNull(classA.getMethod("${methodName}x"));
   }
 
+  void test_getNode() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource("/test.dart", EngineTestCase.createSource(["class A {}", "class B {}"]));
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      ClassElement elementA = unitElement.getType("A");
+      ClassDeclaration nodeA = elementA.node;
+      JUnitTestCase.assertNotNull(nodeA);
+      JUnitTestCase.assertEquals("A", nodeA.name.name);
+      JUnitTestCase.assertSame(elementA, nodeA.element);
+    }
+    // B
+    {
+      ClassElement elementB = unitElement.getType("B");
+      ClassDeclaration nodeB = elementB.node;
+      JUnitTestCase.assertNotNull(nodeB);
+      JUnitTestCase.assertEquals("B", nodeB.name.name);
+      JUnitTestCase.assertSame(elementB, nodeB.element);
+    }
+  }
+
   void test_hasNonFinalField_false_const() {
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     classA.fields = <FieldElement> [ElementFactory.fieldElement("f", false, false, true, classA.type)];
@@ -2588,6 +2997,10 @@
         final __test = new ClassElementImplTest();
         runJUnitTest(__test, __test.test_getAllSupertypes_recursive);
       });
+      _ut.test('test_getField', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_getField);
+      });
       _ut.test('test_getMethod_declared', () {
         final __test = new ClassElementImplTest();
         runJUnitTest(__test, __test.test_getMethod_declared);
@@ -2596,6 +3009,10 @@
         final __test = new ClassElementImplTest();
         runJUnitTest(__test, __test.test_getMethod_undeclared);
       });
+      _ut.test('test_getNode', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_getNode);
+      });
       _ut.test('test_hasNonFinalField_false_const', () {
         final __test = new ClassElementImplTest();
         runJUnitTest(__test, __test.test_hasNonFinalField_false_const);
@@ -2668,6 +3085,63 @@
   }
 }
 
+class AngularPropertyKindTest extends EngineTestCase {
+  void test_ATTR() {
+    AngularPropertyKind kind = AngularPropertyKind.ATTR;
+    JUnitTestCase.assertFalse(kind.callsGetter());
+    JUnitTestCase.assertTrue(kind.callsSetter());
+  }
+
+  void test_CALLBACK() {
+    AngularPropertyKind kind = AngularPropertyKind.CALLBACK;
+    JUnitTestCase.assertFalse(kind.callsGetter());
+    JUnitTestCase.assertTrue(kind.callsSetter());
+  }
+
+  void test_ONE_WAY() {
+    AngularPropertyKind kind = AngularPropertyKind.ONE_WAY;
+    JUnitTestCase.assertFalse(kind.callsGetter());
+    JUnitTestCase.assertTrue(kind.callsSetter());
+  }
+
+  void test_ONE_WAY_ONE_TIME() {
+    AngularPropertyKind kind = AngularPropertyKind.ONE_WAY_ONE_TIME;
+    JUnitTestCase.assertFalse(kind.callsGetter());
+    JUnitTestCase.assertTrue(kind.callsSetter());
+  }
+
+  void test_TWO_WAY() {
+    AngularPropertyKind kind = AngularPropertyKind.TWO_WAY;
+    JUnitTestCase.assertTrue(kind.callsGetter());
+    JUnitTestCase.assertTrue(kind.callsSetter());
+  }
+
+  static dartSuite() {
+    _ut.group('AngularPropertyKindTest', () {
+      _ut.test('test_ATTR', () {
+        final __test = new AngularPropertyKindTest();
+        runJUnitTest(__test, __test.test_ATTR);
+      });
+      _ut.test('test_CALLBACK', () {
+        final __test = new AngularPropertyKindTest();
+        runJUnitTest(__test, __test.test_CALLBACK);
+      });
+      _ut.test('test_ONE_WAY', () {
+        final __test = new AngularPropertyKindTest();
+        runJUnitTest(__test, __test.test_ONE_WAY);
+      });
+      _ut.test('test_ONE_WAY_ONE_TIME', () {
+        final __test = new AngularPropertyKindTest();
+        runJUnitTest(__test, __test.test_ONE_WAY_ONE_TIME);
+      });
+      _ut.test('test_TWO_WAY', () {
+        final __test = new AngularPropertyKindTest();
+        runJUnitTest(__test, __test.test_TWO_WAY);
+      });
+    });
+  }
+}
+
 class ElementImplTest extends EngineTestCase {
   void test_equals() {
     LibraryElementImpl library = ElementFactory.library(createAnalysisContext(), "lib");
@@ -2713,6 +3187,36 @@
     JUnitTestCase.assertTrue(classElement.isAccessibleIn(library));
   }
 
+  void test_isPrivate_false() {
+    Element element = ElementFactory.classElement2("C", []);
+    JUnitTestCase.assertFalse(element.isPrivate);
+  }
+
+  void test_isPrivate_null() {
+    Element element = ElementFactory.classElement2(null, []);
+    JUnitTestCase.assertTrue(element.isPrivate);
+  }
+
+  void test_isPrivate_true() {
+    Element element = ElementFactory.classElement2("_C", []);
+    JUnitTestCase.assertTrue(element.isPrivate);
+  }
+
+  void test_isPublic_false() {
+    Element element = ElementFactory.classElement2("_C", []);
+    JUnitTestCase.assertFalse(element.isPublic);
+  }
+
+  void test_isPublic_null() {
+    Element element = ElementFactory.classElement2(null, []);
+    JUnitTestCase.assertFalse(element.isPublic);
+  }
+
+  void test_isPublic_true() {
+    Element element = ElementFactory.classElement2("C", []);
+    JUnitTestCase.assertTrue(element.isPublic);
+  }
+
   void test_SORT_BY_OFFSET() {
     ClassElementImpl classElementA = ElementFactory.classElement2("A", []);
     classElementA.nameOffset = 1;
@@ -2749,6 +3253,30 @@
         final __test = new ElementImplTest();
         runJUnitTest(__test, __test.test_isAccessibleIn_public_sameLibrary);
       });
+      _ut.test('test_isPrivate_false', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isPrivate_false);
+      });
+      _ut.test('test_isPrivate_null', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isPrivate_null);
+      });
+      _ut.test('test_isPrivate_true', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isPrivate_true);
+      });
+      _ut.test('test_isPublic_false', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isPublic_false);
+      });
+      _ut.test('test_isPublic_null', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isPublic_null);
+      });
+      _ut.test('test_isPublic_true', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isPublic_true);
+      });
     });
   }
 }
@@ -2797,44 +3325,54 @@
   }
 
   void test_hashCode_noElement() {
-    FunctionTypeImpl type = new FunctionTypeImpl.con1(null as ExecutableElement);
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(null);
     type.hashCode;
   }
 
   void test_isAssignableTo_normalAndPositionalArgs() {
+    // ([a]) -> void <: (a) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
     FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [a]).type;
     JUnitTestCase.assertTrue(t.isSubtypeOf(s));
     JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+    // assignable iff subtype
     JUnitTestCase.assertTrue(t.isAssignableTo(s));
     JUnitTestCase.assertFalse(s.isAssignableTo(t));
   }
 
   void test_isSubtypeOf_baseCase_classFunction() {
+    // () -> void <: Function
     ClassElementImpl functionElement = ElementFactory.classElement2("Function", []);
-    InterfaceTypeImpl functionType = new InterfaceTypeImpl_26(functionElement);
+    InterfaceTypeImpl functionType = new InterfaceTypeImpl_FunctionTypeImplTest_test_isSubtypeOf_baseCase_classFunction(functionElement);
     FunctionType f = ElementFactory.functionElement("f").type;
     JUnitTestCase.assertTrue(f.isSubtypeOf(functionType));
   }
 
   void test_isSubtypeOf_baseCase_notFunctionType() {
+    // class C
+    // ! () -> void <: C
     FunctionType f = ElementFactory.functionElement("f").type;
     InterfaceType t = ElementFactory.classElement2("C", []).type;
     JUnitTestCase.assertFalse(f.isSubtypeOf(t));
   }
 
   void test_isSubtypeOf_baseCase_null() {
+    // ! () -> void <: null
     FunctionType f = ElementFactory.functionElement("f").type;
     JUnitTestCase.assertFalse(f.isSubtypeOf(null));
   }
 
   void test_isSubtypeOf_baseCase_self() {
+    // () -> void <: () -> void
     FunctionType f = ElementFactory.functionElement("f").type;
     JUnitTestCase.assertTrue(f.isSubtypeOf(f));
   }
 
   void test_isSubtypeOf_namedParameters_isAssignable() {
+    // B extends A
+    // ({name: A}) -> void <: ({name: B}) -> void
+    // ({name: B}) -> void <: ({name: A}) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
@@ -2844,12 +3382,18 @@
   }
 
   void test_isSubtypeOf_namedParameters_isNotAssignable() {
+    // ! ({name: A}) -> void <: ({name: B}) -> void
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("A", [])]).type;
     FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("B", [])]).type;
     JUnitTestCase.assertFalse(t.isSubtypeOf(s));
   }
 
   void test_isSubtypeOf_namedParameters_namesDifferent() {
+    // B extends A
+    // void t({A name}) {}
+    // void s({A diff}) {}
+    // ! t <: s
+    // ! s <: t
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
@@ -2859,6 +3403,8 @@
   }
 
   void test_isSubtypeOf_namedParameters_orderOfParams() {
+    // B extends A
+    // ({A: A, B: B}) -> void <: ({B: B, A: A}) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
@@ -2867,6 +3413,8 @@
   }
 
   void test_isSubtypeOf_namedParameters_orderOfParams2() {
+    // B extends A
+    // ! ({B: B}) -> void <: ({B: B, A: A}) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["B"], <ClassElement> [b]).type;
@@ -2875,6 +3423,8 @@
   }
 
   void test_isSubtypeOf_namedParameters_orderOfParams3() {
+    // B extends A
+    // ({A: A, B: B}) -> void <: ({A: A}) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
@@ -2883,6 +3433,8 @@
   }
 
   void test_isSubtypeOf_namedParameters_sHasMoreParams() {
+    // B extends A
+    // ! ({name: A}) -> void <: ({name: B, name2: B}) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
@@ -2891,6 +3443,8 @@
   }
 
   void test_isSubtypeOf_namedParameters_tHasMoreParams() {
+    // B extends A
+    // ({name: A, name2: A}) -> void <: ({name: B}) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name", "name2"], <ClassElement> [a, a]).type;
@@ -2899,6 +3453,7 @@
   }
 
   void test_isSubtypeOf_normalAndPositionalArgs_1() {
+    // ([a]) -> void <: (a) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
     FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [a]).type;
@@ -2907,6 +3462,7 @@
   }
 
   void test_isSubtypeOf_normalAndPositionalArgs_2() {
+    // (a, [a]) -> void <: (a) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     FunctionType t = ElementFactory.functionElement6("t", <ClassElement> [a], <ClassElement> [a]).type;
     FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [a]).type;
@@ -2915,6 +3471,7 @@
   }
 
   void test_isSubtypeOf_normalAndPositionalArgs_3() {
+    // ([a]) -> void <: () -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
     FunctionType s = ElementFactory.functionElement("s").type;
@@ -2923,6 +3480,7 @@
   }
 
   void test_isSubtypeOf_normalAndPositionalArgs_4() {
+    // (a, b, [c, d, e]) -> void <: (a, b, c, [d]) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement2("B", []);
     ClassElement c = ElementFactory.classElement2("C", []);
@@ -2935,6 +3493,9 @@
   }
 
   void test_isSubtypeOf_normalParameters_isAssignable() {
+    // B extends A
+    // (a) -> void <: (b) -> void
+    // (b) -> void <: (a) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
@@ -2944,12 +3505,15 @@
   }
 
   void test_isSubtypeOf_normalParameters_isNotAssignable() {
+    // ! (a) -> void <: (b) -> void
     FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [ElementFactory.classElement2("A", [])]).type;
     FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [ElementFactory.classElement2("B", [])]).type;
     JUnitTestCase.assertFalse(t.isSubtypeOf(s));
   }
 
   void test_isSubtypeOf_normalParameters_sHasMoreParams() {
+    // B extends A
+    // ! (a) -> void <: (b, b) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
@@ -2958,20 +3522,28 @@
   }
 
   void test_isSubtypeOf_normalParameters_tHasMoreParams() {
+    // B extends A
+    // ! (a, a) -> void <: (a) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a, a]).type;
     FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
+    // note, this is a different assertion from the other "tHasMoreParams" tests, this is
+    // intentional as it is a difference of the "normal parameters"
     JUnitTestCase.assertFalse(t.isSubtypeOf(s));
   }
 
   void test_isSubtypeOf_Object() {
+    // () -> void <: Object
     FunctionType f = ElementFactory.functionElement("f").type;
     InterfaceType t = ElementFactory.object.type;
     JUnitTestCase.assertTrue(f.isSubtypeOf(t));
   }
 
   void test_isSubtypeOf_positionalParameters_isAssignable() {
+    // B extends A
+    // ([a]) -> void <: ([b]) -> void
+    // ([b]) -> void <: ([a]) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
@@ -2981,12 +3553,15 @@
   }
 
   void test_isSubtypeOf_positionalParameters_isNotAssignable() {
+    // ! ([a]) -> void <: ([b]) -> void
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [ElementFactory.classElement2("A", [])]).type;
     FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [ElementFactory.classElement2("B", [])]).type;
     JUnitTestCase.assertFalse(t.isSubtypeOf(s));
   }
 
   void test_isSubtypeOf_positionalParameters_sHasMoreParams() {
+    // B extends A
+    // ! ([a]) -> void <: ([b, b]) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
@@ -2995,6 +3570,8 @@
   }
 
   void test_isSubtypeOf_positionalParameters_tHasMoreParams() {
+    // B extends A
+    // ([a, a]) -> void <: ([b]) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a, a]).type;
@@ -3003,13 +3580,18 @@
   }
 
   void test_isSubtypeOf_returnType_sIsVoid() {
+    // () -> void <: void
     FunctionType t = ElementFactory.functionElement("t").type;
     FunctionType s = ElementFactory.functionElement("s").type;
+    // function s has the implicit return type of void, we assert it here
     JUnitTestCase.assertTrue(VoidTypeImpl.instance == s.returnType);
     JUnitTestCase.assertTrue(t.isSubtypeOf(s));
   }
 
   void test_isSubtypeOf_returnType_tAssignableToS() {
+    // B extends A
+    // () -> A <: () -> B
+    // () -> B <: () -> A
     ClassElement a = ElementFactory.classElement2("A", []);
     ClassElement b = ElementFactory.classElement("B", a.type, []);
     FunctionType t = ElementFactory.functionElement2("t", a).type;
@@ -3019,6 +3601,7 @@
   }
 
   void test_isSubtypeOf_returnType_tNotAssignableToS() {
+    // ! () -> A <: () -> B
     FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
     FunctionType s = ElementFactory.functionElement2("s", ElementFactory.classElement2("B", [])).type;
     JUnitTestCase.assertFalse(t.isSubtypeOf(s));
@@ -3052,6 +3635,8 @@
   }
 
   void test_isSubtypeOf_wrongFunctionType_normal_named() {
+    // ! (a) -> void <: ({name: A}) -> void
+    // ! ({name: A}) -> void <: (a) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
     FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
@@ -3060,6 +3645,8 @@
   }
 
   void test_isSubtypeOf_wrongFunctionType_optional_named() {
+    // ! ([a]) -> void <: ({name: A}) -> void
+    // ! ({name: A}) -> void <: ([a]) -> void
     ClassElement a = ElementFactory.classElement2("A", []);
     FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
     FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
@@ -3312,14 +3899,15 @@
   }
 }
 
-class InterfaceTypeImpl_26 extends InterfaceTypeImpl {
-  InterfaceTypeImpl_26(ClassElement arg0) : super.con1(arg0);
+class InterfaceTypeImpl_FunctionTypeImplTest_test_isSubtypeOf_baseCase_classFunction extends InterfaceTypeImpl {
+  InterfaceTypeImpl_FunctionTypeImplTest_test_isSubtypeOf_baseCase_classFunction(ClassElement arg0) : super.con1(arg0);
 
   bool get isDartCoreFunction => true;
 }
 
 main() {
   ElementKindTest.dartSuite();
+  AngularPropertyKindTest.dartSuite();
   FunctionTypeImplTest.dartSuite();
   InterfaceTypeImplTest.dartSuite();
   TypeParameterTypeImplTest.dartSuite();
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 81c0306..3928adb 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -27,6 +31,8 @@
  */
 class SimpleParserTest extends ParserTestCase {
   void fail_parseCommentReference_this() {
+    // This fails because we are returning null from the method and asserting that the return value
+    // is not null.
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["this", 5], "");
     SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
     JUnitTestCase.assertNotNull(identifier.token);
@@ -828,6 +834,7 @@
   }
 
   void test_parseClassMember_constructor_withInitializers() {
+    // TODO(brianwilkerson) Test other kinds of class members: fields, getters and setters.
     ConstructorDeclaration constructor = ParserTestCase.parse("parseClassMember", <Object> ["C"], "C(_, _\$, this.__) : _a = _ + _\$ {}");
     JUnitTestCase.assertNotNull(constructor.body);
     JUnitTestCase.assertNotNull(constructor.separator);
@@ -1133,7 +1140,7 @@
 
   void test_parseClassTypeAlias() {
     Token token = TokenFactory.token(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), token], "A = B;");
+    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), null, token], "A = B;");
     JUnitTestCase.assertNotNull(classTypeAlias.keyword);
     JUnitTestCase.assertEquals("A", classTypeAlias.name.name);
     JUnitTestCase.assertNotNull(classTypeAlias.equals);
@@ -1146,7 +1153,7 @@
 
   void test_parseClassTypeAlias_abstract() {
     Token token = TokenFactory.token(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), token], "A = abstract B;");
+    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), null, token], "A = abstract B;");
     JUnitTestCase.assertNotNull(classTypeAlias.keyword);
     JUnitTestCase.assertEquals("A", classTypeAlias.name.name);
     JUnitTestCase.assertNotNull(classTypeAlias.equals);
@@ -1159,7 +1166,7 @@
 
   void test_parseClassTypeAlias_implements() {
     Token token = TokenFactory.token(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), token], "A = B implements C;");
+    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), null, token], "A = B implements C;");
     JUnitTestCase.assertNotNull(classTypeAlias.keyword);
     JUnitTestCase.assertEquals("A", classTypeAlias.name.name);
     JUnitTestCase.assertNotNull(classTypeAlias.equals);
@@ -1172,7 +1179,7 @@
 
   void test_parseClassTypeAlias_with() {
     Token token = TokenFactory.token(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), token], "A = B with C;");
+    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), null, token], "A = B with C;");
     JUnitTestCase.assertNotNull(classTypeAlias.keyword);
     JUnitTestCase.assertEquals("A", classTypeAlias.name.name);
     JUnitTestCase.assertNotNull(classTypeAlias.equals);
@@ -1185,7 +1192,7 @@
 
   void test_parseClassTypeAlias_with_implements() {
     Token token = TokenFactory.token(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), token], "A = B with C implements D;");
+    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), null, token], "A = B with C implements D;");
     JUnitTestCase.assertNotNull(classTypeAlias.keyword);
     JUnitTestCase.assertEquals("A", classTypeAlias.name.name);
     JUnitTestCase.assertNotNull(classTypeAlias.equals);
@@ -1527,6 +1534,12 @@
     EngineTestCase.assertSize(0, declaration.members);
   }
 
+  void test_parseCompilationUnitMember_classTypeAlias() {
+    ClassTypeAlias alias = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "abstract class A = B with C;");
+    JUnitTestCase.assertEquals("A", alias.name.name);
+    JUnitTestCase.assertNotNull(alias.abstractKeyword);
+  }
+
   void test_parseCompilationUnitMember_constVariable() {
     TopLevelVariableDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "const int x = 0;");
     JUnitTestCase.assertNotNull(declaration.semicolon);
@@ -1620,6 +1633,7 @@
     FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "void set p(int v) {}");
     JUnitTestCase.assertNotNull(declaration.functionExpression);
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+    JUnitTestCase.assertNotNull(declaration.returnType);
   }
 
   void test_parseCompilationUnitMember_typeAlias_abstract() {
@@ -1954,6 +1968,7 @@
   }
 
   void test_parseExpression_assign() {
+    // TODO(brianwilkerson) Implement more tests for this method.
     AssignmentExpression expression = ParserTestCase.parse5("parseExpression", "x = y", []);
     JUnitTestCase.assertNotNull(expression.leftHandSide);
     JUnitTestCase.assertNotNull(expression.operator);
@@ -1998,6 +2013,7 @@
   }
 
   void test_parseExpressionWithoutCascade_assign() {
+    // TODO(brianwilkerson) Implement more tests for this method.
     AssignmentExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "x = y", []);
     JUnitTestCase.assertNotNull(expression.leftHandSide);
     JUnitTestCase.assertNotNull(expression.operator);
@@ -3080,6 +3096,7 @@
   }
 
   void test_parseNonLabeledStatement_const_map_nonEmpty() {
+    // TODO(brianwilkerson) Implement more tests for this method.
     ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {'a' : 1};", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
@@ -3468,6 +3485,21 @@
   void test_parsePrimaryExpression_string() {
     SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "\"string\"", []);
     JUnitTestCase.assertFalse(literal.isMultiline);
+    JUnitTestCase.assertFalse(literal.isRaw);
+    JUnitTestCase.assertEquals("string", literal.value);
+  }
+
+  void test_parsePrimaryExpression_string_multiline() {
+    SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "'''string'''", []);
+    JUnitTestCase.assertTrue(literal.isMultiline);
+    JUnitTestCase.assertFalse(literal.isRaw);
+    JUnitTestCase.assertEquals("string", literal.value);
+  }
+
+  void test_parsePrimaryExpression_string_raw() {
+    SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "r'string'", []);
+    JUnitTestCase.assertFalse(literal.isMultiline);
+    JUnitTestCase.assertTrue(literal.isRaw);
     JUnitTestCase.assertEquals("string", literal.value);
   }
 
@@ -3649,6 +3681,7 @@
   }
 
   void test_parseStatement_functionDeclaration() {
+    // TODO(brianwilkerson) Implement more tests for this method.
     FunctionDeclarationStatement statement = ParserTestCase.parse5("parseStatement", "int f(a, b) {};", []);
     JUnitTestCase.assertNotNull(statement.functionDeclaration);
   }
@@ -4404,7 +4437,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_27();
+    AnalysisErrorListener listener = new AnalysisErrorListener_SimpleParserTest_computeStringValue();
     Parser parser = new Parser(null, listener);
     return invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme, first, last], null) as String;
   }
@@ -4458,8 +4491,14 @@
    */
   bool isFunctionExpression(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
+    //
+    // Scan the source.
+    //
     Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     Token tokenStream = scanner.tokenize();
+    //
+    // Parse the source.
+    //
     Parser parser = new Parser(null, listener);
     return invokeParserMethodImpl(parser, "isFunctionExpression", <Object> [tokenStream], tokenStream) as bool;
   }
@@ -4502,8 +4541,14 @@
    */
   Token skip(String methodName, String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
+    //
+    // Scan the source.
+    //
     Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     Token tokenStream = scanner.tokenize();
+    //
+    // Parse the source.
+    //
     Parser parser = new Parser(null, listener);
     return invokeParserMethodImpl(parser, methodName, <Object> [tokenStream], tokenStream) as Token;
   }
@@ -5226,6 +5271,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnitMember_class);
       });
+      _ut.test('test_parseCompilationUnitMember_classTypeAlias', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_classTypeAlias);
+      });
       _ut.test('test_parseCompilationUnitMember_constVariable', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseCompilationUnitMember_constVariable);
@@ -6210,6 +6259,14 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parsePrimaryExpression_string);
       });
+      _ut.test('test_parsePrimaryExpression_string_multiline', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_string_multiline);
+      });
+      _ut.test('test_parsePrimaryExpression_string_raw', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_string_raw);
+      });
       _ut.test('test_parsePrimaryExpression_super', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parsePrimaryExpression_super);
@@ -6674,7 +6731,7 @@
   }
 }
 
-class AnalysisErrorListener_27 implements AnalysisErrorListener {
+class AnalysisErrorListener_SimpleParserTest_computeStringValue implements AnalysisErrorListener {
   void onError(AnalysisError event) {
     JUnitTestCase.fail("Unexpected compilation error: ${event.message} (${event.offset}, ${event.length})");
   }
@@ -6737,15 +6794,24 @@
   void test_assignableExpression_arguments_normal_chain() {
     PropertyAccess propertyAccess1 = ParserTestCase.parseExpression("a(b)(c).d(e).f", []);
     JUnitTestCase.assertEquals("f", propertyAccess1.propertyName.name);
+    //
+    // a(b)(c).d(e)
+    //
     MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(MethodInvocation, propertyAccess1.target);
     JUnitTestCase.assertEquals("d", invocation2.methodName.name);
     ArgumentList argumentList2 = invocation2.argumentList;
     JUnitTestCase.assertNotNull(argumentList2);
     EngineTestCase.assertSize(1, argumentList2.arguments);
+    //
+    // a(b)(c)
+    //
     FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, invocation2.target);
     ArgumentList argumentList3 = invocation3.argumentList;
     JUnitTestCase.assertNotNull(argumentList3);
     EngineTestCase.assertSize(1, argumentList3.arguments);
+    //
+    // a(b)
+    //
     MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(MethodInvocation, invocation3.function);
     JUnitTestCase.assertEquals("a", invocation4.methodName.name);
     ArgumentList argumentList4 = invocation4.argumentList;
@@ -7365,7 +7431,7 @@
     Expression expression = parser.parseExpression(token);
     JUnitTestCase.assertNotNull(expression);
     listener.assertErrors2(errorCodes);
-    return expression as Expression;
+    return expression;
   }
 
   /**
@@ -7386,7 +7452,7 @@
     Statement statement = parser.parseStatement(token);
     JUnitTestCase.assertNotNull(statement);
     listener.assertErrors2(errorCodes);
-    return statement as Statement;
+    return statement;
   }
 
   /**
@@ -7429,16 +7495,25 @@
    *           scanning and parsing the source do not match the expected errors
    */
   static Object invokeParserMethod(String methodName, List<Object> objects, String source, GatheringErrorListener listener) {
+    //
+    // Scan the source.
+    //
     Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     Token tokenStream = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    //
+    // Parse the source.
+    //
     Parser parser = new Parser(null, listener);
     parser.parseFunctionBodies = _parseFunctionBodies;
     Object result = invokeParserMethodImpl(parser, methodName, objects, tokenStream);
+    //
+    // Partially test the results.
+    //
     if (!listener.hasErrors()) {
       JUnitTestCase.assertNotNull(result);
     }
-    return result as Object;
+    return result;
   }
 
   /**
@@ -7683,7 +7758,7 @@
 
   void test_visitImportDirective() {
     ImportDirective fromNode = ASTFactory.importDirective2("dart:uri", null, []);
-    ImportElement element = new ImportElementImpl();
+    ImportElement element = new ImportElementImpl(0);
     fromNode.element = element;
     ImportDirective toNode = ASTFactory.importDirective2("dart:uri", null, []);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -9144,130 +9219,194 @@
 
 class IncrementalParserTest extends EngineTestCase {
   void test_delete_everything() {
+    // "f() => a + b;"
+    // ""
     assertParse("", "f() => a + b;", "", "");
   }
 
   void test_delete_identifier_beginning() {
+    // "f() => abs + b;"
+    // "f() => s + b;"
     assertParse("f() => ", "ab", "", "s + b;");
   }
 
   void test_delete_identifier_end() {
+    // "f() => abs + b;"
+    // "f() => a + b;"
     assertParse("f() => a", "bs", "", " + b;");
   }
 
   void test_delete_identifier_middle() {
+    // "f() => abs + b;"
+    // "f() => as + b;"
     assertParse("f() => a", "b", "", "s + b;");
   }
 
   void test_delete_mergeTokens() {
+    // "f() => a + b + c;"
+    // "f() => ac;"
     assertParse("f() => a", " + b + ", "", "c;");
   }
 
   void test_insert_afterIdentifier1() {
+    // "f() => a + b;"
+    // "f() => abs + b;"
     assertParse("f() => a", "", "bs", " + b;");
   }
 
   void test_insert_afterIdentifier2() {
+    // "f() => a + b;"
+    // "f() => a + bar;"
     assertParse("f() => a + b", "", "ar", ";");
   }
 
   void test_insert_beforeIdentifier1() {
+    // "f() => a + b;"
+    // "f() => xa + b;"
     assertParse("f() => ", "", "x", "a + b;");
   }
 
   void test_insert_beforeIdentifier2() {
+    // "f() => a + b;"
+    // "f() => a + xb;"
     assertParse("f() => a + ", "", "x", "b;");
   }
 
   void test_insert_convertOneFunctionToTwo() {
+    // "f() {}"
+    // "f() => 0; g() {}"
     assertParse("f()", "", " => 0; g()", " {}");
   }
 
   void test_insert_end() {
+    // "class A {}"
+    // "class A {} class B {}"
     assertParse("class A {}", "", " class B {}", "");
   }
 
   void test_insert_insideIdentifier() {
+    // "f() => cob;"
+    // "f() => cow.b;"
     assertParse("f() => co", "", "w.", "b;");
   }
 
   void test_insert_newIdentifier1() {
+    // "f() => a; c;"
+    // "f() => a; b c;"
     assertParse("f() => a;", "", " b", " c;");
   }
 
   void test_insert_newIdentifier2() {
+    // "f() => a;  c;"
+    // "f() => a;b  c;"
     assertParse("f() => a;", "", "b", "  c;");
   }
 
   void test_insert_newIdentifier3() {
+    // "/** A simple function. */ f() => a; c;"
+    // "/** A simple function. */ f() => a; b c;"
     assertParse("/** A simple function. */ f() => a;", "", " b", " c;");
   }
 
   void test_insert_newIdentifier4() {
+    // "/** An [A]. */ class A {} class B { m() { return 1; } }"
+    // "/** An [A]. */ class A {} class B { m() { return 1 + 2; } }"
     assertParse("/** An [A]. */ class A {} class B { m() { return 1", "", " + 2", "; } }");
   }
 
   void test_insert_period() {
+    // "f() => a + b;"
+    // "f() => a + b.;"
     assertParse("f() => a + b", "", ".", ";");
   }
 
   void test_insert_period_betweenIdentifiers1() {
+    // "f() => a b;"
+    // "f() => a. b;"
     assertParse("f() => a", "", ".", " b;");
   }
 
   void test_insert_period_betweenIdentifiers2() {
+    // "f() => a b;"
+    // "f() => a .b;"
     assertParse("f() => a ", "", ".", "b;");
   }
 
   void test_insert_period_betweenIdentifiers3() {
+    // "f() => a  b;"
+    // "f() => a . b;"
     assertParse("f() => a ", "", ".", " b;");
   }
 
   void test_insert_period_insideExistingIdentifier() {
+    // "f() => ab;"
+    // "f() => a.b;"
     assertParse("f() => a", "", ".", "b;");
   }
 
   void test_insert_periodAndIdentifier() {
+    // "f() => a + b;"
+    // "f() => a + b.x;"
     assertParse("f() => a + b", "", ".x", ";");
   }
 
   void test_insert_simpleToComplexExression() {
+    // "/** An [A]. */ class A {} class B { m() => 1; }"
+    // "/** An [A]. */ class A {} class B { m() => 1 + 2; }"
     assertParse("/** An [A]. */ class A {} class B { m() => 1", "", " + 2", "; }");
   }
 
   void test_insert_whitespace_end() {
+    // "f() => a + b;"
+    // "f() => a + b; "
     assertParse("f() => a + b;", "", " ", "");
   }
 
   void test_insert_whitespace_end_multiple() {
+    // "f() => a + b;"
+    // "f() => a + b;  "
     assertParse("f() => a + b;", "", "  ", "");
   }
 
   void test_insert_whitespace_middle() {
+    // "f() => a + b;"
+    // "f() => a  + b;"
     assertParse("f() => a", "", " ", " + b;");
   }
 
   void test_replace_identifier_beginning() {
+    // "f() => bell + b;"
+    // "f() => fell + b;"
     assertParse("f() => ", "b", "f", "ell + b;");
   }
 
   void test_replace_identifier_end() {
+    // "f() => bell + b;"
+    // "f() => belt + b;"
     assertParse("f() => bel", "l", "t", " + b;");
   }
 
   void test_replace_identifier_middle() {
+    // "f() => first + b;"
+    // "f() => frost + b;"
     assertParse("f() => f", "ir", "ro", "st + b;");
   }
 
   void test_replace_multiple_partialFirstAndLast() {
+    // "f() => aa + bb;"
+    // "f() => ab * ab;"
     assertParse("f() => a", "a + b", "b * a", "b;");
   }
 
   void test_replace_operator_oneForMany() {
+    // "f() => a + b;"
+    // "f() => a * c - b;"
     assertParse("f() => a ", "+", "* c -", " b;");
   }
 
   void test_replace_operator_oneForOne() {
+    // "f() => a + b;"
+    // "f() => a * b;"
     assertParse("f() => a ", "+", "*", " b;");
   }
 
@@ -9281,10 +9420,16 @@
    * @param suffix the unchanged text after the edit region
    */
   void assertParse(String prefix, String removed, String added, String suffix) {
+    //
+    // Compute the information needed to perform the test.
+    //
     String originalContents = "${prefix}${removed}${suffix}";
     String modifiedContents = "${prefix}${added}${suffix}";
     int replaceStart = prefix.length;
     Source source = new TestSource();
+    //
+    // Parse the original contents.
+    //
     GatheringErrorListener originalListener = new GatheringErrorListener();
     Scanner originalScanner = new Scanner(source, new CharSequenceReader(new CharSequence(originalContents)), originalListener);
     Token originalTokens = originalScanner.tokenize();
@@ -9292,6 +9437,9 @@
     Parser originalParser = new Parser(source, originalListener);
     CompilationUnit originalUnit = originalParser.parseCompilationUnit(originalTokens);
     JUnitTestCase.assertNotNull(originalUnit);
+    //
+    // Parse the modified contents.
+    //
     GatheringErrorListener modifiedListener = new GatheringErrorListener();
     Scanner modifiedScanner = new Scanner(source, new CharSequenceReader(new CharSequence(modifiedContents)), modifiedListener);
     Token modifiedTokens = modifiedScanner.tokenize();
@@ -9299,6 +9447,9 @@
     Parser modifiedParser = new Parser(source, modifiedListener);
     CompilationUnit modifiedUnit = modifiedParser.parseCompilationUnit(modifiedTokens);
     JUnitTestCase.assertNotNull(modifiedUnit);
+    //
+    // Incrementally parse the modified contents.
+    //
     GatheringErrorListener incrementalListener = new GatheringErrorListener();
     IncrementalScanner incrementalScanner = new IncrementalScanner(source, new CharSequenceReader(new CharSequence(modifiedContents)), incrementalListener);
     Token incrementalTokens = incrementalScanner.rescan(originalTokens, replaceStart, removed.length, added.length);
@@ -9306,6 +9457,10 @@
     IncrementalParser incrementalParser = new IncrementalParser(source, incrementalScanner.tokenMap, incrementalListener);
     CompilationUnit incrementalUnit = incrementalParser.reparse(originalUnit, incrementalScanner.leftToken, incrementalScanner.rightToken, replaceStart, prefix.length + removed.length);
     JUnitTestCase.assertNotNull(incrementalUnit);
+    //
+    // Validate that the results of the incremental parse are the same as the full parse of the
+    // modified source.
+    //
     JUnitTestCase.assertTrue(ASTComparator.equals4(modifiedUnit, incrementalUnit));
   }
 
@@ -9449,15 +9604,22 @@
  */
 class ErrorParserTest extends ParserTestCase {
   void fail_expectedListOrMapLiteral() {
+    // It isn't clear that this test can ever pass. The parser is currently create a synthetic list
+    // literal in this case, but isSynthetic() isn't overridden for ListLiteral. The problem is that
+    // the synthetic list literals that are being created are not always zero length (because they
+    // could have type parameters), which violates the contract of isSynthetic().
     TypedLiteral literal = ParserTestCase.parse4("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
     JUnitTestCase.assertTrue(literal.isSynthetic);
   }
 
   void fail_illegalAssignmentToNonAssignable_superAssigned() {
+    // TODO(brianwilkerson) When this test starts to pass, remove the test
+    // test_illegalAssignmentToNonAssignable_superAssigned.
     ParserTestCase.parseExpression("super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
 
   void fail_invalidCommentReference__new_nonIdentifier() {
+    // This test fails because the method parseCommentReference returns null.
     ParserTestCase.parse4("parseCommentReference", <Object> ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
 
@@ -9466,6 +9628,7 @@
   }
 
   void fail_invalidCommentReference__nonNew_nonIdentifier() {
+    // This test fails because the method parseCommentReference returns null.
     ParserTestCase.parse4("parseCommentReference", <Object> ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
 
@@ -9474,14 +9637,20 @@
   }
 
   void fail_missingClosingParenthesis() {
+    // It is possible that it is not possible to generate this error (that it's being reported in
+    // code that cannot actually be reached), but that hasn't been proven yet.
     ParserTestCase.parse5("parseFormalParameterList", "(int a, int b ;", [ParserErrorCode.MISSING_CLOSING_PARENTHESIS]);
   }
 
   void fail_missingFunctionParameters_local_nonVoid_block() {
+    // The parser does not recognize this as a function declaration, so it tries to parse it as an
+    // expression statement. It isn't clear what the best error message is in this case.
     ParserTestCase.parseStatement("int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
 
   void fail_missingFunctionParameters_local_nonVoid_expression() {
+    // The parser does not recognize this as a function declaration, so it tries to parse it as an
+    // expression statement. It isn't clear what the best error message is in this case.
     ParserTestCase.parseStatement("int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
 
@@ -9491,14 +9660,19 @@
   }
 
   void fail_unexpectedToken_invalidPostfixExpression() {
+    // Note: this might not be the right error to produce, but some error should be produced
     ParserTestCase.parseExpression("f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
 
   void fail_varAndType_local() {
+    // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but this would be a
+    // better error message.
     ParserTestCase.parseStatement("var int x;", [ParserErrorCode.VAR_AND_TYPE]);
   }
 
   void fail_varAndType_parameter() {
+    // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but this would be a
+    // better error message.
     ParserTestCase.parse5("parseFormalParameterList", "(var int x)", [ParserErrorCode.VAR_AND_TYPE]);
   }
 
@@ -9769,7 +9943,7 @@
 
   void test_expectedToken_semicolonAfterClass() {
     Token token = TokenFactory.token(Keyword.CLASS);
-    ParserTestCase.parse4("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), token], "A = B", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse4("parseClassTypeAlias", <Object> [emptyCommentAndMetadata(), null, token], "A = B", [ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_expectedToken_semicolonMissingAfterExpression() {
@@ -9913,6 +10087,9 @@
   }
 
   void test_illegalAssignmentToNonAssignable_superAssigned() {
+    // TODO(brianwilkerson) When the test fail_illegalAssignmentToNonAssignable_superAssigned starts
+    // to pass, remove this test (there should only be one error generated, but we're keeping this
+    // test until that time so that we can catch other forms of regressions).
     ParserTestCase.parseExpression("super = x;", [
         ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
         ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
@@ -11468,7 +11645,7 @@
   'parseCompilationUnit_0': new MethodTrampoline(0, (Parser target) => target.parseCompilationUnit2()),
   'parseConditionalExpression_0': new MethodTrampoline(0, (Parser target) => target.parseConditionalExpression()),
   'parseConstructorName_0': new MethodTrampoline(0, (Parser target) => target.parseConstructorName()),
-  'parseExpression_0': new MethodTrampoline(0, (Parser target) => target.parseExpression2()),
+  'parseExpression_0': new MethodTrampoline(0, (Parser target) => target.parseExpression3()),
   'parseExpressionWithoutCascade_0': new MethodTrampoline(0, (Parser target) => target.parseExpressionWithoutCascade()),
   'parseExtendsClause_0': new MethodTrampoline(0, (Parser target) => target.parseExtendsClause()),
   'parseFormalParameterList_0': new MethodTrampoline(0, (Parser target) => target.parseFormalParameterList()),
@@ -11531,7 +11708,7 @@
   'parseCascadeSection_0': new MethodTrampoline(0, (Parser target) => target.parseCascadeSection()),
   'parseClassDeclaration_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassDeclaration(arg0, arg1)),
   'parseClassMembers_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassMembers(arg0, arg1)),
-  'parseClassTypeAlias_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassTypeAlias(arg0, arg1)),
+  'parseClassTypeAlias_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.parseClassTypeAlias(arg0, arg1, arg2)),
   'parseCombinators_0': new MethodTrampoline(0, (Parser target) => target.parseCombinators()),
   'parseCommentAndMetadata_0': new MethodTrampoline(0, (Parser target) => target.parseCommentAndMetadata()),
   'parseCommentReference_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseCommentReference(arg0, arg1)),
@@ -11605,8 +11782,8 @@
   'peek_0': new MethodTrampoline(0, (Parser target) => target.peek()),
   'peek_1': new MethodTrampoline(1, (Parser target, arg0) => target.peek2(arg0)),
   'reportError_1': new MethodTrampoline(1, (Parser target, arg0) => target.reportError(arg0)),
-  'reportError_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.reportError9(arg0, arg1, arg2)),
-  'reportError_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.reportError10(arg0, arg1)),
+  'reportError_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.reportError10(arg0, arg1, arg2)),
+  'reportError_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.reportError11(arg0, arg1)),
   'skipBlock_0': new MethodTrampoline(0, (Parser target) => target.skipBlock()),
   'skipFinalConstVarOrType_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFinalConstVarOrType(arg0)),
   'skipFormalParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFormalParameterList(arg0)),
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index d77f200..7283b20 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -23,6 +27,7 @@
 
 class TypePropagationTest extends ResolverTestCase {
   void fail_propagatedReturnType_functionExpression() {
+    // TODO(scheglov) disabled because we don't resolve function expression
     String code = EngineTestCase.createSource(["main() {", "  var v = (() {return 42;})();", "}"]);
     check_propagatedReturnType(code, typeProvider.dynamicType, typeProvider.intType);
   }
@@ -112,10 +117,12 @@
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
     InterfaceType stringType = typeProvider.stringType;
+    // in the declaration
     {
       SimpleIdentifier identifier = EngineTestCase.findNode(unit, code, "e in", SimpleIdentifier);
       JUnitTestCase.assertSame(stringType, identifier.propagatedType);
     }
+    // in the loop body
     {
       SimpleIdentifier identifier = EngineTestCase.findNode(unit, code, "e;", SimpleIdentifier);
       JUnitTestCase.assertSame(stringType, identifier.propagatedType);
@@ -138,12 +145,14 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    // k
     Type2 intType = typeProvider.intType;
     FormalParameter kParameter = EngineTestCase.findNode(unit, code, "k, ", SimpleFormalParameter);
     JUnitTestCase.assertSame(intType, kParameter.identifier.propagatedType);
     SimpleIdentifier kIdentifier = EngineTestCase.findNode(unit, code, "k;", SimpleIdentifier);
     JUnitTestCase.assertSame(intType, kIdentifier.propagatedType);
     JUnitTestCase.assertSame(typeProvider.dynamicType, kIdentifier.staticType);
+    // v
     Type2 stringType = typeProvider.stringType;
     FormalParameter vParameter = EngineTestCase.findNode(unit, code, "v)", SimpleFormalParameter);
     JUnitTestCase.assertSame(stringType, vParameter.identifier.propagatedType);
@@ -166,9 +175,11 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    // k
     Type2 intType = typeProvider.intType;
     FormalParameter kParameter = EngineTestCase.findNode(unit, code, "k, ", SimpleFormalParameter);
     JUnitTestCase.assertSame(intType, kParameter.identifier.propagatedType);
+    // v
     Type2 stringType = typeProvider.stringType;
     FormalParameter vParameter = EngineTestCase.findNode(unit, code, "v)", SimpleFormalParameter);
     JUnitTestCase.assertSame(stringType, vParameter.identifier.propagatedType);
@@ -186,6 +197,7 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    // v
     Type2 dynamicType = typeProvider.dynamicType;
     Type2 stringType = typeProvider.stringType;
     FormalParameter vParameter = EngineTestCase.findNode(unit, code, "v)", FormalParameter);
@@ -211,6 +223,7 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    // v
     Type2 intType = typeProvider.intType;
     FormalParameter vParameter = EngineTestCase.findNode(unit, code, "v)", SimpleFormalParameter);
     JUnitTestCase.assertSame(null, vParameter.identifier.propagatedType);
@@ -235,6 +248,7 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    // v
     Type2 stringType = typeProvider.stringType;
     FormalParameter vParameter = EngineTestCase.findNode(unit, code, "v)", SimpleFormalParameter);
     JUnitTestCase.assertSame(stringType, vParameter.identifier.propagatedType);
@@ -259,10 +273,13 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    // p1
     FormalParameter p1 = EngineTestCase.findNode(unit, code, "p1) {", SimpleFormalParameter);
     JUnitTestCase.assertSame(typeProvider.intType, p1.identifier.propagatedType);
+    // p2
     FormalParameter p2 = EngineTestCase.findNode(unit, code, "p2) {", SimpleFormalParameter);
     JUnitTestCase.assertSame(typeProvider.doubleType, p2.identifier.propagatedType);
+    // p3
     FormalParameter p3 = EngineTestCase.findNode(unit, code, "p3) {", SimpleFormalParameter);
     JUnitTestCase.assertSame(typeProvider.stringType, p3.identifier.propagatedType);
   }
@@ -276,12 +293,14 @@
     FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
     BlockFunctionBody body = function.functionExpression.body as BlockFunctionBody;
     NodeList<Statement> statements = body.block.statements;
+    // Type of 'v' in declaration.
     {
       VariableDeclarationStatement statement = statements[0] as VariableDeclarationStatement;
       SimpleIdentifier variableName = statement.variables.variables[0].name;
       JUnitTestCase.assertSame(typeProvider.dynamicType, variableName.staticType);
       JUnitTestCase.assertSame(typeProvider.intType, variableName.propagatedType);
     }
+    // Type of 'v' in reference.
     {
       ReturnStatement statement = statements[1] as ReturnStatement;
       SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
@@ -359,6 +378,8 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    //    ClassDeclaration classA = (ClassDeclaration) unit.getDeclarations().get(0);
+    //    InterfaceType typeA = classA.getElement().getType();
     FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
     BlockFunctionBody body = function.functionExpression.body as BlockFunctionBody;
     IfStatement ifStatement = body.block.statements[0] as IfStatement;
@@ -445,6 +466,7 @@
         "  if (p is B) {",
         "    return p.m();",
         "  }",
+        "  return p;",
         "}"]));
     LibraryElement library = resolve(source);
     assertNoErrors(source);
@@ -464,6 +486,7 @@
         "  while (p is A) {",
         "    return p;",
         "  }",
+        "  return p;",
         "}"]));
     LibraryElement library = resolve(source);
     assertNoErrors(source);
@@ -762,6 +785,7 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = resolveCompilationUnit(source, library);
+    //
     SimpleIdentifier identifier = EngineTestCase.findNode(unit, code, "v = ", SimpleIdentifier);
     JUnitTestCase.assertSame(expectedStaticType, identifier.staticType);
     JUnitTestCase.assertSame(expectedPropagatedType, identifier.propagatedType);
@@ -1205,6 +1229,75 @@
     verify([source]);
   }
 
+  void test_commentReference_beforeConstructor() {
+    String code = EngineTestCase.createSource(["abstract class A {", "  /// [p]", "  A(int p) {}", "}"]);
+    Source source = addSource(code);
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisContext.parseCompilationUnit(source);
+    {
+      SimpleIdentifier ref = EngineTestCase.findNode(unit, code, "p]", SimpleIdentifier);
+      EngineTestCase.assertInstanceOf(ParameterElement, ref.staticElement);
+    }
+  }
+
+  void test_commentReference_beforeFunction_blockBody() {
+    String code = EngineTestCase.createSource(["/// [p]", "foo(int p) {", "}"]);
+    Source source = addSource(code);
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisContext.parseCompilationUnit(source);
+    SimpleIdentifier ref = EngineTestCase.findNode(unit, code, "p]", SimpleIdentifier);
+    EngineTestCase.assertInstanceOf(ParameterElement, ref.staticElement);
+  }
+
+  void test_commentReference_beforeFunction_expressionBody() {
+    String code = EngineTestCase.createSource(["/// [p]", "foo(int p) => null;"]);
+    Source source = addSource(code);
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisContext.parseCompilationUnit(source);
+    SimpleIdentifier ref = EngineTestCase.findNode(unit, code, "p]", SimpleIdentifier);
+    EngineTestCase.assertInstanceOf(ParameterElement, ref.staticElement);
+  }
+
+  void test_commentReference_beforeMethod() {
+    String code = EngineTestCase.createSource([
+        "abstract class A {",
+        "  /// [p1]",
+        "  ma(int p1) {}",
+        "  /// [p2]",
+        "  mb(int p2);",
+        "}"]);
+    Source source = addSource(code);
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisContext.parseCompilationUnit(source);
+    {
+      SimpleIdentifier ref = EngineTestCase.findNode(unit, code, "p1]", SimpleIdentifier);
+      EngineTestCase.assertInstanceOf(ParameterElement, ref.staticElement);
+    }
+    {
+      SimpleIdentifier ref = EngineTestCase.findNode(unit, code, "p2]", SimpleIdentifier);
+      EngineTestCase.assertInstanceOf(ParameterElement, ref.staticElement);
+    }
+  }
+
+  void test_commentReference_class() {
+    String code = EngineTestCase.createSource(["/// [foo]", "class A {", "  foo() {}", "}"]);
+    Source source = addSource(code);
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisContext.parseCompilationUnit(source);
+    SimpleIdentifier ref = EngineTestCase.findNode(unit, code, "foo]", SimpleIdentifier);
+    EngineTestCase.assertInstanceOf(MethodElement, ref.staticElement);
+  }
+
   void test_concreteClassWithAbstractMember() {
     Source source = addSource(EngineTestCase.createSource(["abstract class A {", "  m();", "}"]));
     resolve(source);
@@ -1532,6 +1625,8 @@
   }
 
   void test_duplicateDefinition_emptyName() {
+    // Note: This code has two FunctionElements '() {}' with an empty name, this tests that the
+    // empty string is not put into the scope (more than once).
     Source source = addSource(EngineTestCase.createSource([
         "Map _globalMap = {",
         "  'a' : () {},",
@@ -1751,7 +1846,7 @@
   }
 
   void test_functionDeclaration_scope_returnType() {
-    Source source = addSource(EngineTestCase.createSource(["int f(int) {}"]));
+    Source source = addSource(EngineTestCase.createSource(["int f(int) { return 0; }"]));
     resolve(source);
     assertNoErrors(source);
     verify([source]);
@@ -2010,8 +2105,7 @@
         "class B<E> {",
         "  E get x {return 1;}",
         "}",
-        "class C<E> extends A<E> implements B<E> {",
-        "}"]));
+        "class C<E> extends A<E> implements B<E> {}"]));
     resolve(source);
     assertNoErrors(source);
     verify([source]);
@@ -2160,7 +2254,7 @@
         "}"]));
     addSource2("/lib.dart", EngineTestCase.createSource(["library L;", "class A {", "  static _m() {}", "}"]));
     resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+    assertErrors(source, []);
     verify([source]);
   }
 
@@ -2230,7 +2324,7 @@
         "class byte {",
         "  int _value;",
         "  byte(this._value);",
-        "  byte operator +(int val) {}",
+        "  byte operator +(int val) { return this; }",
         "}",
         "",
         "void main() {",
@@ -2490,7 +2584,7 @@
         "  void m() {}",
         "}",
         "class B extends A {",
-        "  int m() {}",
+        "  int m() { return 0; }",
         "}"]));
     resolve(source);
     assertNoErrors(source);
@@ -2841,36 +2935,6 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  int get g => 0;",
-        "}",
-        "abstract class B extends A {",
-        "  int get g;",
-        "}",
-        "class C extends B {",
-        "}"]));
-    resolve(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  m(p) {}",
-        "}",
-        "abstract class B extends A {",
-        "  m(p);",
-        "}",
-        "class C extends B {",
-        "}"]));
-    resolve(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor() {
     Source source = addSource(EngineTestCase.createSource([
         "abstract class A {",
@@ -4434,6 +4498,26 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_caseExpressionTypeImplementsEquals_int);
       });
+      _ut.test('test_commentReference_beforeConstructor', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_commentReference_beforeConstructor);
+      });
+      _ut.test('test_commentReference_beforeFunction_blockBody', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_commentReference_beforeFunction_blockBody);
+      });
+      _ut.test('test_commentReference_beforeFunction_expressionBody', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_commentReference_beforeFunction_expressionBody);
+      });
+      _ut.test('test_commentReference_beforeMethod', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_commentReference_beforeMethod);
+      });
+      _ut.test('test_commentReference_class', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_commentReference_class);
+      });
       _ut.test('test_concreteClassWithAbstractMember', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_concreteClassWithAbstractMember);
@@ -5038,14 +5122,6 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_newWithUndefinedConstructorDefault);
       });
-      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor', () {
-        final __test = new NonErrorResolverTest();
-        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor);
-      });
-      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method', () {
-        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);
@@ -5985,7 +6061,7 @@
         "class byte {",
         "  int _value;",
         "  byte(this._value);",
-        "  int operator +(int val) {}",
+        "  int operator +(int val) { return 0; }",
         "}",
         "",
         "void main() {",
@@ -6206,6 +6282,7 @@
         "class A {",
         "  String m() {",
         "    int f() => '0';",
+        "    return '0';",
         "  }",
         "}"]));
     resolve(source);
@@ -6246,6 +6323,7 @@
         "class A {",
         "  String m() {",
         "    int f() { return '0'; }",
+        "    return '0';",
         "  }",
         "}"]));
     resolve(source);
@@ -6309,7 +6387,7 @@
         "class A {}",
         "class B {}",
         "class G<E extends A> {}",
-        "G<B> f() {}"]));
+        "G<B> f() { return null; }"]));
     resolve(source);
     assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
     verify([source]);
@@ -6365,7 +6443,7 @@
         "class B {}",
         "class G<E extends A> {}",
         "class C {",
-        "  G<B> m() {}",
+        "  G<B> m() { return null; }",
         "}"]));
     resolve(source);
     assertErrors(source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
@@ -7328,6 +7406,69 @@
     verify([source]);
   }
 
+  void fail_missingReturn_function() {
+    Source source = addSource(EngineTestCase.createSource(["int f() {}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.MISSING_RETURN]);
+    verify([source]);
+  }
+
+  void fail_missingReturn_method() {
+    Source source = addSource(EngineTestCase.createSource(["class A {", "  int m() {}", "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.MISSING_RETURN]);
+    verify([source]);
+  }
+
+  void fail_overriddingPrivateMember_getter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "import 'lib1.dart';",
+        "class B extends A {",
+        "  get _g => 0;",
+        "}"]));
+    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  get _g => 0;", "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+    verify([source, source2]);
+  }
+
+  void fail_overriddingPrivateMember_method() {
+    Source source = addSource(EngineTestCase.createSource([
+        "import 'lib1.dart';",
+        "class B extends A {",
+        "  _m(int x) => 0;",
+        "}"]));
+    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  _m(int x) => 0;", "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+    verify([source, source2]);
+  }
+
+  void fail_overriddingPrivateMember_method2() {
+    Source source = addSource(EngineTestCase.createSource([
+        "import 'lib1.dart';",
+        "class B extends A {}",
+        "class C extends B {",
+        "  _m(int x) => 0;",
+        "}"]));
+    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  _m(int x) => 0;", "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+    verify([source, source2]);
+  }
+
+  void fail_overriddingPrivateMember_setter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "import 'lib1.dart';",
+        "class B extends A {",
+        "  set _s(int x) {}",
+        "}"]));
+    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  set _s(int x) {}", "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
+    verify([source, source2]);
+  }
+
   void fail_overrideEqualsButNotHashCode() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  bool operator ==(x) {}", "}"]));
     resolve(source);
@@ -7343,6 +7484,7 @@
   }
 
   void test_deadCode_deadBlock_conditionalElse_nested() {
+    // test that a dead else-statement can't generate additional violations
     Source source = addSource(EngineTestCase.createSource(["f() {", "  true ? true : false && false;", "}"]));
     resolve(source);
     assertErrors(source, [HintCode.DEAD_CODE]);
@@ -7357,6 +7499,7 @@
   }
 
   void test_deadCode_deadBlock_conditionalIf_nested() {
+    // test that a dead then-statement can't generate additional violations
     Source source = addSource(EngineTestCase.createSource(["f() {", "  false ? false && false : true;", "}"]));
     resolve(source);
     assertErrors(source, [HintCode.DEAD_CODE]);
@@ -7371,6 +7514,7 @@
   }
 
   void test_deadCode_deadBlock_else_nested() {
+    // test that a dead else-statement can't generate additional violations
     Source source = addSource(EngineTestCase.createSource(["f() {", "  if(true) {} else {if (false) {}}", "}"]));
     resolve(source);
     assertErrors(source, [HintCode.DEAD_CODE]);
@@ -7385,6 +7529,7 @@
   }
 
   void test_deadCode_deadBlock_if_nested() {
+    // test that a dead then-statement can't generate additional violations
     Source source = addSource(EngineTestCase.createSource(["f() {", "  if(false) {if(false) {}}", "}"]));
     resolve(source);
     assertErrors(source, [HintCode.DEAD_CODE]);
@@ -7399,6 +7544,7 @@
   }
 
   void test_deadCode_deadBlock_while_nested() {
+    // test that a dead while body can't generate additional violations
     Source source = addSource(EngineTestCase.createSource(["f() {", "  while(false) {if(false) {}}", "}"]));
     resolve(source);
     assertErrors(source, [HintCode.DEAD_CODE]);
@@ -7417,6 +7563,7 @@
   }
 
   void test_deadCode_deadCatch_catchFollowingCatch_nested() {
+    // test that a dead catch clause can't generate additional violations
     Source source = addSource(EngineTestCase.createSource([
         "class A {}",
         "f() {",
@@ -7438,6 +7585,7 @@
   }
 
   void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
+    // test that a dead catch clause can't generate additional violations
     Source source = addSource(EngineTestCase.createSource([
         "f() {",
         "  try {} on Object catch (e) {} catch (e) {if(false) {}}",
@@ -7460,6 +7608,7 @@
   }
 
   void test_deadCode_deadCatch_onCatchSubtype_nested() {
+    // test that a dead catch clause can't generate additional violations
     Source source = addSource(EngineTestCase.createSource([
         "class A {}",
         "class B extends A {}",
@@ -7569,7 +7718,7 @@
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
         "  @deprecated",
-        "  A operator+(A a) {}",
+        "  A operator+(A a) { return a; }",
         "}",
         "f(A a) {",
         "  A b;",
@@ -7757,6 +7906,7 @@
   }
 
   void test_divisionOptimization_propagatedType() {
+    // Tests the propagated type information of the '/' method
     Source source = addSource(EngineTestCase.createSource([
         "f(x, y) {",
         "  x = 1;",
@@ -7829,55 +7979,6 @@
     verify([source]);
   }
 
-  void test_overriddingPrivateMember_getter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {",
-        "  get _g => 0;",
-        "}"]));
-    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  get _g => 0;", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  void test_overriddingPrivateMember_method() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {",
-        "  _m(int x) => 0;",
-        "}"]));
-    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  _m(int x) => 0;", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  void test_overriddingPrivateMember_method2() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {}",
-        "class C extends B {",
-        "  _m(int x) => 0;",
-        "}"]));
-    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  _m(int x) => 0;", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  void test_overriddingPrivateMember_setter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {",
-        "  set _s(int x) {}",
-        "}"]));
-    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  set _s(int x) {}", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
   void test_typeCheck_type_is_Null() {
     Source source = addSource(EngineTestCase.createSource(["m(i) {", "  bool b = i is Null;", "}"]));
     resolve(source);
@@ -8314,22 +8415,6 @@
         final __test = new HintCodeTest();
         runJUnitTest(__test, __test.test_isNotDouble);
       });
-      _ut.test('test_overriddingPrivateMember_getter', () {
-        final __test = new HintCodeTest();
-        runJUnitTest(__test, __test.test_overriddingPrivateMember_getter);
-      });
-      _ut.test('test_overriddingPrivateMember_method', () {
-        final __test = new HintCodeTest();
-        runJUnitTest(__test, __test.test_overriddingPrivateMember_method);
-      });
-      _ut.test('test_overriddingPrivateMember_method2', () {
-        final __test = new HintCodeTest();
-        runJUnitTest(__test, __test.test_overriddingPrivateMember_method2);
-      });
-      _ut.test('test_overriddingPrivateMember_setter', () {
-        final __test = new HintCodeTest();
-        runJUnitTest(__test, __test.test_overriddingPrivateMember_setter);
-      });
       _ut.test('test_typeCheck_type_is_Null', () {
         final __test = new HintCodeTest();
         runJUnitTest(__test, __test.test_typeCheck_type_is_Null);
@@ -8490,6 +8575,7 @@
     ClassElement type = ElementFactory.classElement2("A", []);
     VariableDeclaration node = ASTFactory.variableDeclaration("a");
     ASTFactory.variableDeclarationList(null, ASTFactory.typeName(type, []), [node]);
+    //resolve(node);
     JUnitTestCase.assertSame(type.type, node.name.staticType);
     _listener.assertNoErrors();
   }
@@ -8509,6 +8595,7 @@
   }
 
   void test_visitCatchClause_exception() {
+    // catch (e)
     CatchClause clause = ASTFactory.catchClause("e", []);
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement = new LocalVariableElementImpl(exceptionParameter);
@@ -8517,6 +8604,7 @@
   }
 
   void test_visitCatchClause_exception_stackTrace() {
+    // catch (e, s)
     CatchClause clause = ASTFactory.catchClause2("e", "s", []);
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement = new LocalVariableElementImpl(exceptionParameter);
@@ -8527,6 +8615,7 @@
   }
 
   void test_visitCatchClause_on_exception() {
+    // on E catch (e)
     ClassElement exceptionElement = ElementFactory.classElement2("E", []);
     TypeName exceptionType = ASTFactory.typeName(exceptionElement, []);
     CatchClause clause = ASTFactory.catchClause4(exceptionType, "e", []);
@@ -8537,6 +8626,7 @@
   }
 
   void test_visitCatchClause_on_exception_stackTrace() {
+    // on E catch (e, s)
     ClassElement exceptionElement = ElementFactory.classElement2("E", []);
     TypeName exceptionType = ASTFactory.typeName(exceptionElement, []);
     (exceptionType.name as SimpleIdentifier).staticElement = exceptionElement;
@@ -8550,6 +8640,7 @@
   }
 
   void test_visitClassDeclaration() {
+    // class A extends B with C implements D {}
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement2("B", []);
     ClassElement elementC = ElementFactory.classElement2("C", []);
@@ -8571,6 +8662,7 @@
   }
 
   void test_visitClassTypeAlias() {
+    // class A = B with C implements D;
     ClassElement elementA = ElementFactory.classElement2("A", []);
     ClassElement elementB = ElementFactory.classElement2("B", []);
     ClassElement elementC = ElementFactory.classElement2("C", []);
@@ -8626,6 +8718,7 @@
   }
 
   void test_visitSimpleFormalParameter_noType() {
+    // p
     FormalParameter node = ASTFactory.simpleFormalParameter3("p");
     node.identifier.staticElement = new ParameterElementImpl.con1(ASTFactory.identifier3("p"));
     JUnitTestCase.assertSame(_typeProvider.dynamicType, resolve6(node, []));
@@ -8633,6 +8726,7 @@
   }
 
   void test_visitSimpleFormalParameter_type() {
+    // int p
     InterfaceType intType = _typeProvider.intType;
     ClassElement intElement = intType.element;
     FormalParameter node = ASTFactory.simpleFormalParameter4(ASTFactory.typeName(intElement, []), "p");
@@ -9003,6 +9097,11 @@
 
 class TypeProviderImplTest extends EngineTestCase {
   void test_creation() {
+    //
+    // Create a mock library element with the types expected to be in dart:core. We cannot use
+    // either ElementFactory or TestTypeProvider (which uses ElementFactory) because we side-effect
+    // the elements in ways that would break other tests.
+    //
     InterfaceType objectType = classElement("Object", null, []).type;
     InterfaceType boolType = classElement("bool", objectType, []).type;
     InterfaceType numType = classElement("num", objectType, []).type;
@@ -9030,6 +9129,9 @@
         typeType.element];
     LibraryElementImpl library = new LibraryElementImpl(new AnalysisContextImpl(), ASTFactory.libraryIdentifier2(["lib"]));
     library.definingCompilationUnit = unit;
+    //
+    // Create a type provider and ensure that it can return the expected types.
+    //
     TypeProviderImpl provider = new TypeProviderImpl(library);
     JUnitTestCase.assertSame(boolType, provider.boolType);
     JUnitTestCase.assertNotNull(provider.bottomType);
@@ -9834,6 +9936,7 @@
   }
 
   void fail_mixinOfNonClass() {
+    // TODO(brianwilkerson) Compare with MIXIN_WITH_NON_CLASS_SUPERCLASS.
     Source source = addSource(EngineTestCase.createSource(["var A;", "class B extends Object mixin A {}"]));
     resolve(source);
     assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
@@ -10265,13 +10368,6 @@
     check_constEvalTypeNum_withParameter_binary("p % ''");
   }
 
-  void test_constEvalTypeNum_plus_String() {
-    Source source = addSource("const C = 'a' + 'b';");
-    resolve(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_TYPE_NUM]);
-    verify([source]);
-  }
-
   void test_constFormalParameter_fieldFormalParameter() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  var x;", "  A(const this.x) {}", "}"]));
     resolve(source);
@@ -10862,6 +10958,7 @@
   }
 
   void test_fieldInitializerOutsideConstructor() {
+    // TODO(brianwilkerson) Fix the duplicate error messages.
     Source source = addSource(EngineTestCase.createSource(["class A {", "  int x;", "  m(this.x) {}", "}"]));
     resolve(source);
     assertErrors(source, [
@@ -11133,6 +11230,10 @@
   void test_importInternalLibrary() {
     Source source = addSource(EngineTestCase.createSource(["import 'dart:_interceptors';"]));
     resolve(source);
+    // Note, in these error cases we may generate an UNUSED_IMPORT hint, while we could prevent
+    // the hint from being generated by testing the import directive for the error, this is such a
+    // minor corner case that we don't think we should add the additional computation time to figure
+    // out such cases.
     assertErrors(source, [
         CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
         HintCode.UNUSED_IMPORT]);
@@ -11140,8 +11241,12 @@
   }
 
   void test_importInternalLibrary_collection() {
-    Source source = addSource(EngineTestCase.createSource(["import 'dart:_collection-dev';"]));
+    Source source = addSource(EngineTestCase.createSource(["import 'dart:_internal';"]));
     resolve(source);
+    // Note, in these error cases we may generate an UNUSED_IMPORT hint, while we could prevent
+    // the hint from being generated by testing the import directive for the error, this is such a
+    // minor corner case that we don't think we should add the additional computation time to figure
+    // out such cases.
     assertErrors(source, [
         CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
         HintCode.UNUSED_IMPORT]);
@@ -11744,6 +11849,8 @@
   }
 
   void test_nativeClauseInNonSDKCode() {
+    // TODO(jwren) Move this test somewhere else: This test verifies a parser error code is generated
+    // through the ErrorVerifier, it is not a CompileTimeErrorCode.
     Source source = addSource(EngineTestCase.createSource(["class A native 'string' {}"]));
     resolve(source);
     assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
@@ -11751,6 +11858,8 @@
   }
 
   void test_nativeFunctionBodyInNonSDKCode_function() {
+    // TODO(jwren) Move this test somewhere else: This test verifies a parser error code is generated
+    // through the ErrorVerifier, it is not a CompileTimeErrorCode.
     Source source = addSource(EngineTestCase.createSource(["int m(a) native 'string';"]));
     resolve(source);
     assertErrors(source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
@@ -11758,6 +11867,8 @@
   }
 
   void test_nativeFunctionBodyInNonSDKCode_method() {
+    // TODO(jwren) Move this test somewhere else: This test verifies a parser error code is generated
+    // through the ErrorVerifier, it is not a CompileTimeErrorCode.
     Source source = addSource(EngineTestCase.createSource(["class A{", "  static int m(a) native 'string';", "}"]));
     resolve(source);
     assertErrors(source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
@@ -13102,10 +13213,6 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_constEvalTypeNum_binary);
       });
-      _ut.test('test_constEvalTypeNum_plus_String', () {
-        final __test = new CompileTimeErrorCodeTest();
-        runJUnitTest(__test, __test.test_constEvalTypeNum_plus_String);
-      });
       _ut.test('test_constEval_newInstance_constConstructor', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_constEval_newInstance_constConstructor);
@@ -14377,6 +14484,8 @@
   Object visitLibraryIdentifier(LibraryIdentifier node) => null;
 
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    // In cases where we have a prefixed identifier where the prefix is dynamic, we don't want to
+    // assert that the node will have a type.
     if (node.staticType == null && identical(node.prefix.staticType, DynamicTypeImpl.instance)) {
       return null;
     }
@@ -14384,24 +14493,29 @@
   }
 
   Object visitSimpleIdentifier(SimpleIdentifier node) {
+    // In cases where identifiers are being used for something other than an expressions,
+    // then they can be ignored.
     ASTNode parent = node.parent;
-    if (parent is MethodInvocation && identical(node, (parent as MethodInvocation).methodName)) {
+    if (parent is MethodInvocation && identical(node, parent.methodName)) {
       return null;
-    } else if (parent is RedirectingConstructorInvocation && identical(node, (parent as RedirectingConstructorInvocation).constructorName)) {
+    } else if (parent is RedirectingConstructorInvocation && identical(node, parent.constructorName)) {
       return null;
-    } else if (parent is SuperConstructorInvocation && identical(node, (parent as SuperConstructorInvocation).constructorName)) {
+    } else if (parent is SuperConstructorInvocation && identical(node, parent.constructorName)) {
       return null;
-    } else if (parent is ConstructorName && identical(node, (parent as ConstructorName).name)) {
+    } else if (parent is ConstructorName && identical(node, parent.name)) {
       return null;
-    } else if (parent is ConstructorFieldInitializer && identical(node, (parent as ConstructorFieldInitializer).fieldName)) {
+    } else if (parent is ConstructorFieldInitializer && identical(node, parent.fieldName)) {
       return null;
     } else if (node.staticElement is PrefixElement) {
+      // Prefixes don't have a type.
       return null;
     }
     return super.visitSimpleIdentifier(node);
   }
 
   Object visitTypeName(TypeName node) {
+    // Note: do not visit children from this node, the child SimpleIdentifier in TypeName
+    // (i.e. "String") does not have a static type defined.
     if (node.type == null) {
       _unresolvedTypes.add(node);
     } else {
@@ -14411,10 +14525,12 @@
   }
 
   String getFileName(ASTNode node) {
+    // TODO (jwren) there are two copies of this method, one here and one in ResolutionVerifier,
+    // they should be resolved into a single method
     if (node != null) {
       ASTNode root = node.root;
       if (root is CompilationUnit) {
-        CompilationUnit rootCU = root as CompilationUnit;
+        CompilationUnit rootCU = root;
         if (rootCU.element != null) {
           return rootCU.element.source.fullName;
         } else {
@@ -14660,6 +14776,7 @@
 
   void fail_visitExportDirective_combinators() {
     JUnitTestCase.fail("Not yet tested");
+    // Need to set up the exported library so that the identifier can be resolved
     ExportDirective directive = ASTFactory.exportDirective2(null, [ASTFactory.hideCombinator2(["A"])]);
     resolveNode(directive, []);
     _listener.assertNoErrors();
@@ -14672,6 +14789,7 @@
 
   void fail_visitImportDirective_combinators_noPrefix() {
     JUnitTestCase.fail("Not yet tested");
+    // Need to set up the imported library so that the identifier can be resolved
     ImportDirective directive = ASTFactory.importDirective2(null, null, [ASTFactory.showCombinator2(["A"])]);
     resolveNode(directive, []);
     _listener.assertNoErrors();
@@ -14679,6 +14797,7 @@
 
   void fail_visitImportDirective_combinators_prefix() {
     JUnitTestCase.fail("Not yet tested");
+    // Need to set up the imported library so that the identifiers can be resolved
     String prefixName = "p";
     _definingLibrary.imports = <ImportElement> [ElementFactory.importFor(null, ElementFactory.prefix(prefixName), [])];
     ImportDirective directive = ASTFactory.importDirective2(null, prefixName, [
@@ -14701,14 +14820,30 @@
 
   void test_lookUpMethodInInterfaces() {
     InterfaceType intType = _typeProvider.intType;
+    //
+    // abstract class A { int operator[](int index); }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     MethodElement operator = ElementFactory.methodElement("[]", intType, [intType]);
     classA.methods = <MethodElement> [operator];
+    //
+    // class B implements A {}
+    //
     ClassElementImpl classB = ElementFactory.classElement2("B", []);
     classB.interfaces = <InterfaceType> [classA.type];
+    //
+    // class C extends Object with B {}
+    //
     ClassElementImpl classC = ElementFactory.classElement2("C", []);
     classC.mixins = <InterfaceType> [classB.type];
+    //
+    // class D extends C {}
+    //
     ClassElementImpl classD = ElementFactory.classElement("D", classC.type, []);
+    //
+    // D a;
+    // a[i];
+    //
     SimpleIdentifier array = ASTFactory.identifier3("a");
     array.staticType = classD.type;
     IndexExpression expression = ASTFactory.indexExpression(array, ASTFactory.identifier3("i"));
@@ -14965,6 +15100,67 @@
     _listener.assertNoErrors();
   }
 
+  void test_visitPrefixedIdentifier_staticClassMember_getter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    // set accessors
+    String propName = "b";
+    PropertyAccessorElement getter = ElementFactory.getterElement(propName, false, _typeProvider.intType);
+    PropertyAccessorElement setter = ElementFactory.setterElement(propName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [getter, setter];
+    // prepare "A.m"
+    SimpleIdentifier target = ASTFactory.identifier3("A");
+    target.staticElement = classA;
+    target.staticType = classA.type;
+    PrefixedIdentifier identifier = ASTFactory.identifier(target, ASTFactory.identifier3(propName));
+    // resolve
+    resolveNode(identifier, []);
+    JUnitTestCase.assertSame(getter, identifier.staticElement);
+    JUnitTestCase.assertSame(getter, identifier.identifier.staticElement);
+    _listener.assertNoErrors();
+  }
+
+  void test_visitPrefixedIdentifier_staticClassMember_method() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    // set accessors
+    String propName = "m";
+    PropertyAccessorElement setter = ElementFactory.setterElement(propName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [setter];
+    // set methods
+    MethodElement method = ElementFactory.methodElement("m", _typeProvider.intType, []);
+    classA.methods = <MethodElement> [method];
+    // prepare "A.m"
+    SimpleIdentifier target = ASTFactory.identifier3("A");
+    target.staticElement = classA;
+    target.staticType = classA.type;
+    PrefixedIdentifier identifier = ASTFactory.identifier(target, ASTFactory.identifier3(propName));
+    ASTFactory.assignmentExpression(identifier, TokenType.EQ, ASTFactory.nullLiteral());
+    // resolve
+    resolveNode(identifier, []);
+    JUnitTestCase.assertSame(method, identifier.staticElement);
+    JUnitTestCase.assertSame(method, identifier.identifier.staticElement);
+    _listener.assertNoErrors();
+  }
+
+  void test_visitPrefixedIdentifier_staticClassMember_setter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A", []);
+    // set accessors
+    String propName = "b";
+    PropertyAccessorElement getter = ElementFactory.getterElement(propName, false, _typeProvider.intType);
+    PropertyAccessorElement setter = ElementFactory.setterElement(propName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement> [getter, setter];
+    // prepare "A.b = null"
+    SimpleIdentifier target = ASTFactory.identifier3("A");
+    target.staticElement = classA;
+    target.staticType = classA.type;
+    PrefixedIdentifier identifier = ASTFactory.identifier(target, ASTFactory.identifier3(propName));
+    ASTFactory.assignmentExpression(identifier, TokenType.EQ, ASTFactory.nullLiteral());
+    // resolve
+    resolveNode(identifier, []);
+    JUnitTestCase.assertSame(setter, identifier.staticElement);
+    JUnitTestCase.assertSame(setter, identifier.identifier.staticElement);
+    _listener.assertNoErrors();
+  }
+
   void test_visitPrefixExpression() {
     InterfaceType numType = _typeProvider.numType;
     SimpleIdentifier operand = ASTFactory.identifier3("i");
@@ -14989,6 +15185,14 @@
   }
 
   void test_visitPropertyAccess_getter_super() {
+    //
+    // class A {
+    //  int get b;
+    // }
+    // class B {
+    //   ... super.m ...
+    // }
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     String getterName = "b";
     PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, _typeProvider.intType);
@@ -15347,6 +15551,18 @@
         final __test = new ElementResolverTest();
         runJUnitTest(__test, __test.test_visitPrefixedIdentifier_nonDynamic);
       });
+      _ut.test('test_visitPrefixedIdentifier_staticClassMember_getter', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_staticClassMember_getter);
+      });
+      _ut.test('test_visitPrefixedIdentifier_staticClassMember_method', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_staticClassMember_method);
+      });
+      _ut.test('test_visitPrefixedIdentifier_staticClassMember_setter', () {
+        final __test = new ElementResolverTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier_staticClassMember_setter);
+      });
       _ut.test('test_visitPropertyAccess_getter_identifier', () {
         final __test = new ElementResolverTest();
         runJUnitTest(__test, __test.test_visitPropertyAccess_getter_identifier);
@@ -15724,9 +15940,10 @@
         "typedef N FT(N p);",
         "N f(N p) {",
         "  N v;",
+        "  return null;",
         "}",
         "class A {",
-        "  N m() {}",
+        "  N m() { return null; }",
         "}",
         "class B<T extends N> {}"]));
     addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
@@ -15747,7 +15964,7 @@
         "import 'lib1.dart';",
         "import 'lib2.dart';",
         "class A<T> {}",
-        "A<N> f() {}"]));
+        "A<N> f() { return null; }"]));
     addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class N {}"]));
     addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "class N {}"]));
     resolve(source);
@@ -15828,11 +16045,11 @@
     verify([source]);
   }
 
-  void test_argumentTypeNotAssignable_cascadeSEcond() {
+  void test_argumentTypeNotAssignable_cascadeSecond() {
     Source source = addSource(EngineTestCase.createSource([
         "// filler filler filler filler filler filler filler filler filler filler",
         "class A {",
-        "  B ma() {}",
+        "  B ma() { return new B(); }",
         "}",
         "class B {",
         "  mb(String p) {}",
@@ -16828,7 +17045,7 @@
   void test_invalidMethodOverrideReturnType_void() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
-        "  int m() {}",
+        "  int m() { return 0; }",
         "}",
         "class B extends A {",
         "  void m() {}",
@@ -17184,6 +17401,49 @@
     verify([source]);
   }
 
+  void test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  int get g => 0;",
+        "}",
+        "abstract class B extends A {",
+        "  int get g;",
+        "}",
+        "class C extends B {}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
+
+  void test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  m(p) {}",
+        "}",
+        "abstract class B extends A {",
+        "  m(p);",
+        "}",
+        "class C extends B {}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
+
+  void test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation() {
+    // bug 15028
+    Source source = addSource(EngineTestCase.createSource([
+        "class C {",
+        "  foo(int x) => x;",
+        "}",
+        "abstract class D {",
+        "  foo(x, [y]);",
+        "}",
+        "class E extends C implements D {}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
+
   void test_nonAbstractClassInheritsAbstractMemberOne_getter_fromInterface() {
     Source source = addSource(EngineTestCase.createSource([
         "class I {",
@@ -17233,6 +17493,7 @@
   }
 
   void test_nonAbstractClassInheritsAbstractMemberOne_method_optionalParamCount() {
+    // 7640
     Source source = addSource(EngineTestCase.createSource([
         "abstract class A {",
         "  int x(int a);",
@@ -17272,6 +17533,7 @@
   }
 
   void test_nonAbstractClassInheritsAbstractMemberOne_superclasses_interface() {
+    // bug 11154
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
         "  get a => 'a';",
@@ -17334,7 +17596,10 @@
   }
 
   void test_nonVoidReturnForOperator() {
-    Source source = addSource(EngineTestCase.createSource(["class A {", "  int operator []=(a, b) {}", "}"]));
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  int operator []=(a, b) { return a; }",
+        "}"]));
     resolve(source);
     assertErrors(source, [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]);
     verify([source]);
@@ -17547,7 +17812,7 @@
   }
 
   void test_typeParameterReferencedByStatic_methodReturn() {
-    Source source = addSource(EngineTestCase.createSource(["class A<K> {", "  static K m() {}", "}"]));
+    Source source = addSource(EngineTestCase.createSource(["class A<K> {", "  static K m() { return null; }", "}"]));
     resolve(source);
     assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
     verify([source]);
@@ -17809,9 +18074,9 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_argumentTypeNotAssignable_binary);
       });
-      _ut.test('test_argumentTypeNotAssignable_cascadeSEcond', () {
+      _ut.test('test_argumentTypeNotAssignable_cascadeSecond', () {
         final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_argumentTypeNotAssignable_cascadeSEcond);
+        runJUnitTest(__test, __test.test_argumentTypeNotAssignable_cascadeSecond);
       });
       _ut.test('test_argumentTypeNotAssignable_const', () {
         final __test = new StaticWarningCodeTest();
@@ -18285,6 +18550,18 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberFour);
       });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_accessor);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation);
+      });
       _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_getter_fromInterface', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_getter_fromInterface);
@@ -18525,6 +18802,45 @@
   }
 }
 
+/**
+ * Helper for creating and managing single [AnalysisContext].
+ */
+class AnalysisContextHelper {
+  AnalysisContext context;
+
+  SourceFactory _sourceFactory;
+
+  ContentCache _cache;
+
+  /**
+   * Creates new [AnalysisContext] using [AnalysisContextFactory#contextWithCore].
+   */
+  AnalysisContextHelper() {
+    context = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = context.sourceFactory;
+    _cache = _sourceFactory.contentCache;
+  }
+
+  Source addSource(String path, String code) {
+    Source source = new FileBasedSource.con1(_cache, FileUtilities2.createFile(path));
+    // add source
+    {
+      _sourceFactory.setContents(source, "");
+      ChangeSet changeSet = new ChangeSet();
+      changeSet.added(source);
+      context.applyChanges(changeSet);
+    }
+    // update source
+    context.setContents(source, code);
+    return source;
+  }
+
+  CompilationUnit resolveDefiningUnit(Source source) {
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    return context.resolveCompilationUnit(source, libraryElement);
+  }
+}
+
 class ErrorResolverTest extends ResolverTestCase {
   void test_breakLabelOnSwitchMember() {
     Source source = addSource(EngineTestCase.createSource([
@@ -18842,14 +19158,23 @@
    * hierarchy and (b) add members to them.
    */
   void initializeNumericTypes() {
+    //
+    // Create the type hierarchy.
+    //
     ClassElementImpl numElement = ElementFactory.classElement2("num", []);
     _numType = numElement.type;
     ClassElementImpl intElement = ElementFactory.classElement("int", _numType, []);
     _intType = intElement.type;
     ClassElementImpl doubleElement = ElementFactory.classElement("double", _numType, []);
     _doubleType = doubleElement.type;
+    //
+    // Force the referenced types to be cached.
+    //
     boolType;
     stringType;
+    //
+    // Add the methods.
+    //
     numElement.methods = <MethodElement> [
         ElementFactory.methodElement("+", _numType, [_numType]),
         ElementFactory.methodElement("-", _numType, [_numType]),
@@ -18965,6 +19290,9 @@
   static AnalysisContextImpl initContextWithCore(AnalysisContextImpl context) {
     AnalysisContext sdkContext = DirectoryBasedDartSdk.defaultSdk.context;
     SourceFactory sourceFactory = sdkContext.sourceFactory;
+    //
+    // dart:core
+    //
     TestTypeProvider provider = new TestTypeProvider();
     CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl("core.dart");
     Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
@@ -18996,6 +19324,9 @@
     coreUnit.topLevelVariables = <TopLevelVariableElement> [proxyTopLevelVariableElt, deprecatedTopLevelVariableElt];
     LibraryElementImpl coreLibrary = new LibraryElementImpl(sdkContext, ASTFactory.libraryIdentifier2(["dart", "core"]));
     coreLibrary.definingCompilationUnit = coreUnit;
+    //
+    // dart:html
+    //
     CompilationUnitElementImpl htmlUnit = new CompilationUnitElementImpl("html_dartium.dart");
     Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
     sdkContext.setContents(htmlSource, "");
@@ -19095,7 +19426,7 @@
     LibraryElement importedLibrary = createTestLibrary2(context, "imported", []);
     (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl).types = <ClassElement> [importedType];
     LibraryElementImpl definingLibrary = createTestLibrary2(context, "importing", []);
-    ImportElementImpl importElement = new ImportElementImpl();
+    ImportElementImpl importElement = new ImportElementImpl(0);
     importElement.importedLibrary = importedLibrary;
     definingLibrary.imports = <ImportElement> [importElement];
     GatheringErrorListener errorListener = new GatheringErrorListener();
@@ -19339,10 +19670,13 @@
 
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     node.visitChildren(this);
+    // TODO(brianwilkerson) If we start resolving function expressions, then conditionally check to
+    // see whether the node was resolved correctly.
     return null;
   }
 
   Object visitImportDirective(ImportDirective node) {
+    // Not sure how to test the combinators given that it isn't an error if the names are not defined.
     checkResolved2(node, node.element, ImportElement);
     SimpleIdentifier prefix = node.prefix;
     if (prefix == null) {
@@ -19418,7 +19752,7 @@
     }
     ASTNode parent = node.parent;
     if (parent is MethodInvocation) {
-      MethodInvocation invocation = parent as MethodInvocation;
+      MethodInvocation invocation = parent;
       if (identical(invocation.methodName, node)) {
         Expression target = invocation.realTarget;
         Type2 targetType = target == null ? null : target.staticType;
@@ -19446,10 +19780,12 @@
   }
 
   String getFileName(ASTNode node) {
+    // TODO (jwren) there are two copies of this method, one here and one in StaticTypeVerifier,
+    // they should be resolved into a single method
     if (node != null) {
       ASTNode root = node.root;
       if (root is CompilationUnit) {
-        CompilationUnit rootCU = root as CompilationUnit;
+        CompilationUnit rootCU = root;
         if (rootCU.element != null) {
           return rootCU.element.source.fullName;
         } else {
@@ -19551,7 +19887,7 @@
     LibraryElement importedLibrary = createTestLibrary2(context, "imported", []);
     (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl).types = <ClassElement> [importedType];
     LibraryElementImpl definingLibrary = createTestLibrary2(context, "importing", []);
-    ImportElementImpl importElement = new ImportElementImpl();
+    ImportElementImpl importElement = new ImportElementImpl(0);
     importElement.importedLibrary = importedLibrary;
     definingLibrary.imports = <ImportElement> [importElement];
     GatheringErrorListener errorListener = new GatheringErrorListener();
@@ -19627,18 +19963,22 @@
   }
 
   void test_visitAdjacentStrings() {
+    // "a" "b"
     Expression node = ASTFactory.adjacentStrings([resolvedString("a"), resolvedString("b")]);
     JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitArgumentDefinitionTest() {
+    // ?p
     Expression node = ASTFactory.argumentDefinitionTest("p");
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitAsExpression() {
+    // class A { ... this as B ... }
+    // class B extends A {}
     ClassElement superclass = ElementFactory.classElement2("A", []);
     InterfaceType superclassType = superclass.type;
     ClassElement subclass = ElementFactory.classElement("B", superclassType, []);
@@ -19648,6 +19988,7 @@
   }
 
   void test_visitAssignmentExpression_compound() {
+    // i += 1
     InterfaceType numType = _typeProvider.numType;
     SimpleIdentifier identifier = resolvedVariable(_typeProvider.intType, "i");
     AssignmentExpression node = ASTFactory.assignmentExpression(identifier, TokenType.PLUS_EQ, resolvedInteger(1));
@@ -19658,6 +19999,7 @@
   }
 
   void test_visitAssignmentExpression_simple() {
+    // i = 0
     InterfaceType intType = _typeProvider.intType;
     Expression node = ASTFactory.assignmentExpression(resolvedVariable(intType, "i"), TokenType.EQ, resolvedInteger(0));
     JUnitTestCase.assertSame(intType, analyze(node));
@@ -19665,30 +20007,35 @@
   }
 
   void test_visitBinaryExpression_equals() {
+    // 2 == 3
     Expression node = ASTFactory.binaryExpression(resolvedInteger(2), TokenType.EQ_EQ, resolvedInteger(3));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_logicalAnd() {
+    // false && true
     Expression node = ASTFactory.binaryExpression(ASTFactory.booleanLiteral(false), TokenType.AMPERSAND_AMPERSAND, ASTFactory.booleanLiteral(true));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_logicalOr() {
+    // false || true
     Expression node = ASTFactory.binaryExpression(ASTFactory.booleanLiteral(false), TokenType.BAR_BAR, ASTFactory.booleanLiteral(true));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_notEquals() {
+    // 2 != 3
     Expression node = ASTFactory.binaryExpression(resolvedInteger(2), TokenType.BANG_EQ, resolvedInteger(3));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_plusID() {
+    // 1 + 2.0
     BinaryExpression node = ASTFactory.binaryExpression(resolvedInteger(1), TokenType.PLUS, resolvedDouble(2.0));
     node.staticElement = getMethod(_typeProvider.numType, "+");
     JUnitTestCase.assertSame(_typeProvider.doubleType, analyze(node));
@@ -19696,6 +20043,7 @@
   }
 
   void test_visitBinaryExpression_plusII() {
+    // 1 + 2
     BinaryExpression node = ASTFactory.binaryExpression(resolvedInteger(1), TokenType.PLUS, resolvedInteger(2));
     node.staticElement = getMethod(_typeProvider.numType, "+");
     JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
@@ -19703,6 +20051,7 @@
   }
 
   void test_visitBinaryExpression_slash() {
+    // 2 / 2
     BinaryExpression node = ASTFactory.binaryExpression(resolvedInteger(2), TokenType.SLASH, resolvedInteger(2));
     node.staticElement = getMethod(_typeProvider.numType, "/");
     JUnitTestCase.assertSame(_typeProvider.doubleType, analyze(node));
@@ -19710,6 +20059,10 @@
   }
 
   void test_visitBinaryExpression_star_notSpecial() {
+    // class A {
+    //   A operator *(double value);
+    // }
+    // (a as A) * 2.0
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     InterfaceType typeA = classA.type;
     MethodElement operator = ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
@@ -19721,6 +20074,7 @@
   }
 
   void test_visitBinaryExpression_starID() {
+    // 1 * 2.0
     BinaryExpression node = ASTFactory.binaryExpression(resolvedInteger(1), TokenType.PLUS, resolvedDouble(2.0));
     node.staticElement = getMethod(_typeProvider.numType, "*");
     JUnitTestCase.assertSame(_typeProvider.doubleType, analyze(node));
@@ -19728,42 +20082,49 @@
   }
 
   void test_visitBooleanLiteral_false() {
+    // false
     Expression node = ASTFactory.booleanLiteral(false);
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitBooleanLiteral_true() {
+    // true
     Expression node = ASTFactory.booleanLiteral(true);
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitCascadeExpression() {
+    // a..length
     Expression node = ASTFactory.cascadeExpression(resolvedString("a"), [ASTFactory.propertyAccess2(null, "length")]);
     JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitConditionalExpression_differentTypes() {
+    // true ? 1.0 : 0
     Expression node = ASTFactory.conditionalExpression(ASTFactory.booleanLiteral(true), resolvedDouble(1.0), resolvedInteger(0));
     JUnitTestCase.assertSame(_typeProvider.numType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitConditionalExpression_sameTypes() {
+    // true ? 1 : 0
     Expression node = ASTFactory.conditionalExpression(ASTFactory.booleanLiteral(true), resolvedInteger(1), resolvedInteger(0));
     JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitDoubleLiteral() {
+    // 4.33
     Expression node = ASTFactory.doubleLiteral(4.33);
     JUnitTestCase.assertSame(_typeProvider.doubleType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitFunctionExpression_named_block() {
+    // ({p1 : 0, p2 : 0}) {}
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p1"), resolvedInteger(0));
     setType(p1, dynamicType);
@@ -19781,6 +20142,7 @@
   }
 
   void test_visitFunctionExpression_named_expression() {
+    // ({p : 0}) -> 0;
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p = ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p"), resolvedInteger(0));
     setType(p, dynamicType);
@@ -19794,6 +20156,7 @@
   }
 
   void test_visitFunctionExpression_normal_block() {
+    // (p1, p2) {}
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
     setType(p1, dynamicType);
@@ -19808,6 +20171,7 @@
   }
 
   void test_visitFunctionExpression_normal_expression() {
+    // (p1, p2) -> 0
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p = ASTFactory.simpleFormalParameter3("p");
     setType(p, dynamicType);
@@ -19819,6 +20183,7 @@
   }
 
   void test_visitFunctionExpression_normalAndNamed_block() {
+    // (p1, {p2 : 0}) {}
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
     setType(p1, dynamicType);
@@ -19834,6 +20199,7 @@
   }
 
   void test_visitFunctionExpression_normalAndNamed_expression() {
+    // (p1, {p2 : 0}) -> 0
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
     setType(p1, dynamicType);
@@ -19849,6 +20215,7 @@
   }
 
   void test_visitFunctionExpression_normalAndPositional_block() {
+    // (p1, [p2 = 0]) {}
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
     setType(p1, dynamicType);
@@ -19863,6 +20230,7 @@
   }
 
   void test_visitFunctionExpression_normalAndPositional_expression() {
+    // (p1, [p2 = 0]) -> 0
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.simpleFormalParameter3("p1");
     setType(p1, dynamicType);
@@ -19877,6 +20245,7 @@
   }
 
   void test_visitFunctionExpression_positional_block() {
+    // ([p1 = 0, p2 = 0]) {}
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p1 = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p1"), resolvedInteger(0));
     setType(p1, dynamicType);
@@ -19891,6 +20260,7 @@
   }
 
   void test_visitFunctionExpression_positional_expression() {
+    // ([p1 = 0, p2 = 0]) -> 0
     Type2 dynamicType = _typeProvider.dynamicType;
     FormalParameter p = ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p"), resolvedInteger(0));
     setType(p, dynamicType);
@@ -19902,6 +20272,8 @@
   }
 
   void test_visitIndexExpression_getter() {
+    // List a;
+    // a[2]
     InterfaceType listType = _typeProvider.listType;
     SimpleIdentifier identifier = resolvedVariable(listType, "a");
     IndexExpression node = ASTFactory.indexExpression(identifier, resolvedInteger(2));
@@ -19912,6 +20284,8 @@
   }
 
   void test_visitIndexExpression_setter() {
+    // List a;
+    // a[2] = 0
     InterfaceType listType = _typeProvider.listType;
     SimpleIdentifier identifier = resolvedVariable(listType, "a");
     IndexExpression node = ASTFactory.indexExpression(identifier, resolvedInteger(2));
@@ -19923,35 +20297,49 @@
   }
 
   void test_visitIndexExpression_typeParameters() {
+    // List<int> list = ...
+    // list[0]
     InterfaceType intType = _typeProvider.intType;
     InterfaceType listType = _typeProvider.listType;
+    // (int) -> E
     MethodElement methodElement = getMethod(listType, "[]");
+    // "list" has type List<int>
     SimpleIdentifier identifier = ASTFactory.identifier3("list");
     InterfaceType listOfIntType = listType.substitute4(<Type2> [intType]);
     identifier.staticType = listOfIntType;
+    // list[0] has MethodElement element (int) -> E
     IndexExpression indexExpression = ASTFactory.indexExpression(identifier, ASTFactory.integer(0));
     MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
     indexExpression.staticElement = indexMethod;
+    // analyze and assert result of the index expression
     JUnitTestCase.assertSame(intType, analyze(indexExpression));
     _listener.assertNoErrors();
   }
 
   void test_visitIndexExpression_typeParameters_inSetterContext() {
+    // List<int> list = ...
+    // list[0] = 0;
     InterfaceType intType = _typeProvider.intType;
     InterfaceType listType = _typeProvider.listType;
+    // (int, E) -> void
     MethodElement methodElement = getMethod(listType, "[]=");
+    // "list" has type List<int>
     SimpleIdentifier identifier = ASTFactory.identifier3("list");
     InterfaceType listOfIntType = listType.substitute4(<Type2> [intType]);
     identifier.staticType = listOfIntType;
+    // list[0] has MethodElement element (int) -> E
     IndexExpression indexExpression = ASTFactory.indexExpression(identifier, ASTFactory.integer(0));
     MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
     indexExpression.staticElement = indexMethod;
+    // list[0] should be in a setter context
     ASTFactory.assignmentExpression(indexExpression, TokenType.EQ, ASTFactory.integer(0));
+    // analyze and assert result of the index expression
     JUnitTestCase.assertSame(intType, analyze(indexExpression));
     _listener.assertNoErrors();
   }
 
   void test_visitInstanceCreationExpression_named() {
+    // new C.m()
     ClassElementImpl classElement = ElementFactory.classElement2("C", []);
     String constructorName = "m";
     ConstructorElementImpl constructor = ElementFactory.constructorElement2(classElement, constructorName, []);
@@ -19966,6 +20354,7 @@
   }
 
   void test_visitInstanceCreationExpression_typeParameters() {
+    // new C<I>()
     ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
     ClassElementImpl elementI = ElementFactory.classElement2("I", []);
     ConstructorElementImpl constructor = ElementFactory.constructorElement2(elementC, null, []);
@@ -19985,6 +20374,7 @@
   }
 
   void test_visitInstanceCreationExpression_unnamed() {
+    // new C()
     ClassElementImpl classElement = ElementFactory.classElement2("C", []);
     ConstructorElementImpl constructor = ElementFactory.constructorElement2(classElement, null, []);
     constructor.returnType = classElement.type;
@@ -19998,24 +20388,28 @@
   }
 
   void test_visitIntegerLiteral() {
+    // 42
     Expression node = resolvedInteger(42);
     JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitIsExpression_negated() {
+    // a is! String
     Expression node = ASTFactory.isExpression(resolvedString("a"), true, ASTFactory.typeName4("String", []));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitIsExpression_notNegated() {
+    // a is String
     Expression node = ASTFactory.isExpression(resolvedString("a"), false, ASTFactory.typeName4("String", []));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitListLiteral_empty() {
+    // []
     Expression node = ASTFactory.listLiteral([]);
     Type2 resultType = analyze(node);
     assertType2(_typeProvider.listType.substitute4(<Type2> [_typeProvider.dynamicType]), resultType);
@@ -20023,6 +20417,7 @@
   }
 
   void test_visitListLiteral_nonEmpty() {
+    // [0]
     Expression node = ASTFactory.listLiteral([resolvedInteger(0)]);
     Type2 resultType = analyze(node);
     assertType2(_typeProvider.listType.substitute4(<Type2> [_typeProvider.dynamicType]), resultType);
@@ -20030,6 +20425,7 @@
   }
 
   void test_visitMapLiteral_empty() {
+    // {}
     Expression node = ASTFactory.mapLiteral2([]);
     Type2 resultType = analyze(node);
     assertType2(_typeProvider.mapType.substitute4(<Type2> [_typeProvider.dynamicType, _typeProvider.dynamicType]), resultType);
@@ -20037,6 +20433,7 @@
   }
 
   void test_visitMapLiteral_nonEmpty() {
+    // {"k" : 0}
     Expression node = ASTFactory.mapLiteral2([ASTFactory.mapLiteralEntry("k", resolvedInteger(0))]);
     Type2 resultType = analyze(node);
     assertType2(_typeProvider.mapType.substitute4(<Type2> [_typeProvider.dynamicType, _typeProvider.dynamicType]), resultType);
@@ -20044,36 +20441,42 @@
   }
 
   void test_visitMethodInvocation_then() {
+    // then()
     Expression node = ASTFactory.methodInvocation(null, "then", []);
     analyze(node);
     _listener.assertNoErrors();
   }
 
   void test_visitNamedExpression() {
+    // n: a
     Expression node = ASTFactory.namedExpression2("n", resolvedString("a"));
     JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitNullLiteral() {
+    // null
     Expression node = ASTFactory.nullLiteral();
     JUnitTestCase.assertSame(_typeProvider.bottomType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitParenthesizedExpression() {
+    // (0)
     Expression node = ASTFactory.parenthesizedExpression(resolvedInteger(0));
     JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitPostfixExpression_minusMinus() {
+    // 0--
     PostfixExpression node = ASTFactory.postfixExpression(resolvedInteger(0), TokenType.MINUS_MINUS);
     JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitPostfixExpression_plusPlus() {
+    // 0++
     PostfixExpression node = ASTFactory.postfixExpression(resolvedInteger(0), TokenType.PLUS_PLUS);
     JUnitTestCase.assertSame(_typeProvider.intType, analyze(node));
     _listener.assertNoErrors();
@@ -20108,12 +20511,14 @@
   }
 
   void test_visitPrefixExpression_bang() {
+    // !0
     PrefixExpression node = ASTFactory.prefixExpression(TokenType.BANG, resolvedInteger(0));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitPrefixExpression_minus() {
+    // -0
     PrefixExpression node = ASTFactory.prefixExpression(TokenType.MINUS, resolvedInteger(0));
     MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
     node.staticElement = minusMethod;
@@ -20122,6 +20527,7 @@
   }
 
   void test_visitPrefixExpression_minusMinus() {
+    // --0
     PrefixExpression node = ASTFactory.prefixExpression(TokenType.MINUS_MINUS, resolvedInteger(0));
     MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
     node.staticElement = minusMethod;
@@ -20130,12 +20536,14 @@
   }
 
   void test_visitPrefixExpression_not() {
+    // !true
     Expression node = ASTFactory.prefixExpression(TokenType.BANG, ASTFactory.booleanLiteral(true));
     JUnitTestCase.assertSame(_typeProvider.boolType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitPrefixExpression_plusPlus() {
+    // ++0
     PrefixExpression node = ASTFactory.prefixExpression(TokenType.PLUS_PLUS, resolvedInteger(0));
     MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
     node.staticElement = plusMethod;
@@ -20144,6 +20552,7 @@
   }
 
   void test_visitPrefixExpression_tilde() {
+    // ~0
     PrefixExpression node = ASTFactory.prefixExpression(TokenType.TILDE, resolvedInteger(0));
     MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
     node.staticElement = tildeMethod;
@@ -20171,12 +20580,14 @@
   }
 
   void test_visitSimpleStringLiteral() {
+    // "a"
     Expression node = resolvedString("a");
     JUnitTestCase.assertSame(_typeProvider.stringType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitStringInterpolation() {
+    // "a${'b'}c"
     Expression node = ASTFactory.string([
         ASTFactory.interpolationString("a", "a"),
         ASTFactory.interpolationExpression(resolvedString("b")),
@@ -20186,6 +20597,7 @@
   }
 
   void test_visitSuperExpression() {
+    // super
     InterfaceType superType = ElementFactory.classElement2("A", []).type;
     InterfaceType thisType = ElementFactory.classElement("B", superType, []).type;
     Expression node = ASTFactory.superExpression();
@@ -20198,6 +20610,7 @@
   }
 
   void test_visitThisExpression() {
+    // this
     InterfaceType thisType = ElementFactory.classElement("B", ElementFactory.classElement2("A", []).type, []).type;
     Expression node = ASTFactory.thisExpression();
     JUnitTestCase.assertSame(thisType, analyze2(node, thisType));
@@ -20205,12 +20618,14 @@
   }
 
   void test_visitThrowExpression_withoutValue() {
+    // throw
     Expression node = ASTFactory.throwExpression();
     JUnitTestCase.assertSame(_typeProvider.bottomType, analyze(node));
     _listener.assertNoErrors();
   }
 
   void test_visitThrowExpression_withValue() {
+    // throw 0
     Expression node = ASTFactory.throwExpression2(resolvedInteger(0));
     JUnitTestCase.assertSame(_typeProvider.bottomType, analyze(node));
     _listener.assertNoErrors();
@@ -20314,7 +20729,7 @@
   void assertType2(Type2 expectedType, Type2 actualType) {
     if (expectedType is InterfaceTypeImpl) {
       EngineTestCase.assertInstanceOf(InterfaceTypeImpl, actualType);
-      assertType(expectedType as InterfaceTypeImpl, actualType as InterfaceTypeImpl);
+      assertType(expectedType, actualType as InterfaceTypeImpl);
     }
   }
 
@@ -20870,7 +21285,7 @@
   void test_divisionOptimization_supressIfDivisionOverridden() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
-        "  num operator /(x) {}",
+        "  num operator /(x) { return x; }",
         "}",
         "f(A x, A y) {",
         "  var v = (x / y).toInt();",
@@ -20919,6 +21334,34 @@
     verify([source]);
   }
 
+  void test_missingReturn_emptyFunctionBody() {
+    Source source = addSource(EngineTestCase.createSource(["abstract class A {", "  int m();", "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_missingReturn_expressionFunctionBody() {
+    Source source = addSource(EngineTestCase.createSource(["int f() => 0;"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_missingReturn_noReturnType() {
+    Source source = addSource(EngineTestCase.createSource(["f() {}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_missingReturn_voidReturnType() {
+    Source source = addSource(EngineTestCase.createSource(["void f() {}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_overriddingPrivateMember_sameLibrary() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -20935,7 +21378,7 @@
   void test_overrideEqualsButNotHashCode() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
-        "  bool operator ==(x) {}",
+        "  bool operator ==(x) { return x; }",
         "  get hashCode => 0;",
         "}"]));
     resolve(source);
@@ -21151,6 +21594,7 @@
   }
 
   void test_unnecessaryCast_13855_parameter_A() {
+    // dartbug.com/13855, dartbug.com/13732
     Source source = addSource(EngineTestCase.createSource([
         "class A{",
         "  a() {}",
@@ -21311,6 +21755,22 @@
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_duplicateImport_show);
       });
+      _ut.test('test_missingReturn_emptyFunctionBody', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_missingReturn_emptyFunctionBody);
+      });
+      _ut.test('test_missingReturn_expressionFunctionBody', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_missingReturn_expressionFunctionBody);
+      });
+      _ut.test('test_missingReturn_noReturnType', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_missingReturn_noReturnType);
+      });
+      _ut.test('test_missingReturn_voidReturnType', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_missingReturn_voidReturnType);
+      });
       _ut.test('test_overriddingPrivateMember_sameLibrary', () {
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_overriddingPrivateMember_sameLibrary);
@@ -21414,7 +21874,7 @@
 class EnclosedScopeTest extends ResolverTestCase {
   void test_define_duplicate() {
     GatheringErrorListener errorListener2 = new GatheringErrorListener();
-    Scope rootScope = new Scope_24(errorListener2);
+    Scope rootScope = new Scope_EnclosedScopeTest_test_define_duplicate(errorListener2);
     EnclosedScope scope = new EnclosedScope(rootScope);
     VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
     VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
@@ -21425,7 +21885,7 @@
 
   void test_define_normal() {
     GatheringErrorListener errorListener3 = new GatheringErrorListener();
-    Scope rootScope = new Scope_25(errorListener3);
+    Scope rootScope = new Scope_EnclosedScopeTest_test_define_normal(errorListener3);
     EnclosedScope outerScope = new EnclosedScope(rootScope);
     EnclosedScope innerScope = new EnclosedScope(outerScope);
     VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
@@ -21449,20 +21909,20 @@
   }
 }
 
-class Scope_24 extends Scope {
+class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
   GatheringErrorListener errorListener2;
 
-  Scope_24(this.errorListener2) : super();
+  Scope_EnclosedScopeTest_test_define_duplicate(this.errorListener2) : super();
 
   AnalysisErrorListener get errorListener => errorListener2;
 
   Element lookup3(Identifier identifier, String name, LibraryElement referencingLibrary) => null;
 }
 
-class Scope_25 extends Scope {
+class Scope_EnclosedScopeTest_test_define_normal extends Scope {
   GatheringErrorListener errorListener3;
 
-  Scope_25(this.errorListener3) : super();
+  Scope_EnclosedScopeTest_test_define_normal(this.errorListener3) : super();
 
   AnalysisErrorListener get errorListener => errorListener3;
 
@@ -21623,7 +22083,7 @@
         new FileUriResolver()]);
     LibraryResolver resolver = new LibraryResolver(context);
     LibraryElementBuilder builder = new LibraryElementBuilder(resolver);
-    Library library = resolver.createLibrary(librarySource) as Library;
+    Library library = resolver.createLibrary(librarySource);
     LibraryElement element = builder.buildLibrary(library);
     GatheringErrorListener listener = new GatheringErrorListener();
     listener.addAll(resolver.errorListener);
@@ -22194,7 +22654,7 @@
     JUnitTestCase.assertNotNull(unit);
     List<bool> found = [false];
     List<AnalysisException> thrownException = new List<AnalysisException>(1);
-    unit.accept(new RecursiveASTVisitor_28(this, found, thrownException));
+    unit.accept(new RecursiveASTVisitor_SimpleResolverTest_test_localVariable_types_invoked(this, found, thrownException));
     if (thrownException[0] != null) {
       throw new AnalysisException.con3(thrownException[0]);
     }
@@ -22320,6 +22780,7 @@
         "  }",
         "}"]));
     resolve(source);
+    // failing with error code: INVOCATION_OF_NON_FUNCTION
     assertNoErrors(source);
     verify([source]);
   }
@@ -22590,21 +23051,23 @@
   }
 }
 
-class RecursiveASTVisitor_28 extends RecursiveASTVisitor<Object> {
+class RecursiveASTVisitor_SimpleResolverTest_test_localVariable_types_invoked extends RecursiveASTVisitor<Object> {
   final SimpleResolverTest SimpleResolverTest_this;
 
   List<bool> found;
 
   List<AnalysisException> thrownException;
 
-  RecursiveASTVisitor_28(this.SimpleResolverTest_this, this.found, this.thrownException) : super();
+  RecursiveASTVisitor_SimpleResolverTest_test_localVariable_types_invoked(this.SimpleResolverTest_this, this.found, this.thrownException) : super();
 
   Object visitSimpleIdentifier(SimpleIdentifier node) {
     if (node.name == "myVar" && node.parent is MethodInvocation) {
       try {
         found[0] = true;
+        // check static type
         Type2 staticType = node.staticType;
         JUnitTestCase.assertSame(SimpleResolverTest_this.typeProvider.dynamicType, staticType);
+        // check propagated type
         FunctionType propagatedType = node.propagatedType as FunctionType;
         JUnitTestCase.assertEquals(SimpleResolverTest_this.typeProvider.stringType, propagatedType.returnType);
       } on AnalysisException catch (e) {
@@ -22627,6 +23090,10 @@
   CompilationUnitElementImpl _definingCompilationUnit;
 
   void test_computeAllSubtypes_infiniteLoop() {
+    //
+    // class A extends B
+    // class B extends A
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     classA.supertype = classB.type;
@@ -22638,6 +23105,13 @@
   }
 
   void test_computeAllSubtypes_manyRecursiveSubtypes() {
+    //
+    // class A
+    // class B extends A
+    // class C extends B
+    // class D extends B
+    // class E extends B
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     ClassElementImpl classC = ElementFactory.classElement("C", classB.type, []);
@@ -22655,6 +23129,9 @@
   }
 
   void test_computeAllSubtypes_noSubtypes() {
+    //
+    // class A
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     _definingCompilationUnit.types = <ClassElement> [classA];
     Set<ClassElement> subtypesOfA = _subtypeManager.computeAllSubtypes(classA);
@@ -22662,6 +23139,10 @@
   }
 
   void test_computeAllSubtypes_oneSubtype() {
+    //
+    // class A
+    // class B extends A
+    //
     ClassElementImpl classA = ElementFactory.classElement2("A", []);
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type, []);
     _definingCompilationUnit.types = <ClassElement> [classA, classB];
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 50ad8cb..4923566 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -14,6 +18,9 @@
 
 class KeywordStateTest extends JUnitTestCase {
   void test_KeywordState() {
+    //
+    // Generate the test data to be scanned.
+    //
     List<Keyword> keywords = Keyword.values;
     int keywordCount = keywords.length;
     List<String> textToTest = new List<String>(keywordCount * 3);
@@ -23,6 +30,9 @@
       textToTest[i + keywordCount] = "${syntax}x";
       textToTest[i + keywordCount * 2] = syntax.substring(0, syntax.length - 1);
     }
+    //
+    // Scan each of the identifiers.
+    //
     KeywordState firstState = KeywordState.KEYWORD_STATE;
     for (int i = 0; i < textToTest.length; i++) {
       String text = textToTest[i];
@@ -34,12 +44,15 @@
         index++;
       }
       if (i < keywordCount) {
+        // keyword
         JUnitTestCase.assertNotNull(state);
         JUnitTestCase.assertNotNull(state.keyword());
         JUnitTestCase.assertEquals(keywords[i], state.keyword());
       } else if (i < keywordCount * 2) {
+        // keyword + "x"
         JUnitTestCase.assertNull(state);
       } else {
+        // keyword.substring(0, keyword.length() - 1)
         JUnitTestCase.assertNotNull(state);
       }
     }
@@ -1039,6 +1052,9 @@
   }
 
   void assertComment(TokenType commentType, String source) {
+    //
+    // Test without a trailing end-of-line marker
+    //
     Token token = scan(source);
     JUnitTestCase.assertNotNull(token);
     JUnitTestCase.assertEquals(TokenType.EOF, token.type);
@@ -1048,6 +1064,9 @@
     JUnitTestCase.assertEquals(0, comment.offset);
     JUnitTestCase.assertEquals(source.length, comment.length);
     JUnitTestCase.assertEquals(source, comment.lexeme);
+    //
+    // Test with a trailing end-of-line marker
+    //
     token = scan("${source}\n");
     JUnitTestCase.assertNotNull(token);
     JUnitTestCase.assertEquals(TokenType.EOF, token.type);
@@ -1069,7 +1088,7 @@
   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])]);
+    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.codeUnitAt(expectedOffset)])]);
   }
 
   /**
@@ -1127,8 +1146,10 @@
     JUnitTestCase.assertEquals(source.length, originalToken.length);
     JUnitTestCase.assertEquals(source, originalToken.lexeme);
     if (identical(expectedType, TokenType.SCRIPT_TAG)) {
+      // Adding space before the script tag is not allowed, and adding text at the end changes nothing.
       return originalToken;
     } else if (identical(expectedType, TokenType.SINGLE_LINE_COMMENT)) {
+      // Adding space to an end-of-line comment changes the comment.
       Token tokenWithSpaces = scan(" ${source}");
       JUnitTestCase.assertNotNull(tokenWithSpaces);
       JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
@@ -1892,30 +1913,40 @@
   Token _incrementalTokens;
 
   void test_delete_identifier_beginning() {
+    // "abs + b;"
+    // "s + b;")
     scan("", "ab", "", "s + b;");
     assertTokens(-1, 1, ["s", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_delete_identifier_end() {
+    // "abs + b;"
+    // "a + b;")
     scan("a", "bs", "", " + b;");
     assertTokens(-1, 1, ["a", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_delete_identifier_middle() {
+    // "abs + b;"
+    // "as + b;")
     scan("a", "b", "", "s + b;");
     assertTokens(-1, 1, ["as", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_delete_mergeTokens() {
+    // "a + b + c;"
+    // "ac;")
     scan("a", " + b + ", "", "c;");
     assertTokens(-1, 1, ["ac", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_afterIdentifier1() {
+    // "a + b;"
+    // "abs + b;"
     scan("a", "", "bs", " + b;");
     assertTokens(-1, 1, ["abs", "+", "b", ";"]);
     assertReplaced(1, "+");
@@ -1923,48 +1954,64 @@
   }
 
   void test_insert_afterIdentifier2() {
+    // "a + b;"
+    // "a + by;"
     scan("a + b", "", "y", ";");
     assertTokens(1, 3, ["a", "+", "by", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_beforeIdentifier() {
+    // "a + b;"
+    // "a + xb;")
     scan("a + ", "", "x", "b;");
     assertTokens(1, 3, ["a", "+", "xb", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_beforeIdentifier_firstToken() {
+    // "a + b;"
+    // "xa + b;"
     scan("", "", "x", "a + b;");
     assertTokens(-1, 1, ["xa", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_convertOneFunctionToTwo() {
+    // "f() {}"
+    // "f() => 0; g() {}"
     scan("f()", "", " => 0; g()", " {}");
     assertTokens(2, 9, ["f", "(", ")", "=>", "0", ";", "g", "(", ")", "{", "}"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_end() {
+    // "class A {}"
+    // "class A {} class B {}"
     scan("class A {}", "", " class B {}", "");
     assertTokens(3, 8, ["class", "A", "{", "}", "class", "B", "{", "}"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_insideIdentifier() {
+    // "cob;"
+    // "cow.b;"
     scan("co", "", "w.", "b;");
     assertTokens(-1, 3, ["cow", ".", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_newIdentifier1() {
+    // "a;  c;"
+    // "a; b c;"
     scan("a; ", "", "b", " c;");
     assertTokens(1, 3, ["a", ";", "b", "c", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_newIdentifier2() {
+    // "a;  c;"
+    // "a;b  c;"
     scan("a;", "", "b", "  c;");
     assertTokens(1, 3, ["a", ";", "b", "c", ";"]);
     assertReplaced(1, ";");
@@ -1972,105 +2019,141 @@
   }
 
   void test_insert_period() {
+    // "a + b;"
+    // "a + b.;"
     scan("a + b", "", ".", ";");
     assertTokens(2, 4, ["a", "+", "b", ".", ";"]);
   }
 
   void test_insert_period_betweenIdentifiers1() {
+    // "a b;"
+    // "a. b;"
     scan("a", "", ".", " b;");
     assertTokens(0, 2, ["a", ".", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_period_betweenIdentifiers2() {
+    // "a b;"
+    // "a .b;"
     scan("a ", "", ".", "b;");
     assertTokens(0, 2, ["a", ".", "b", ";"]);
   }
 
   void test_insert_period_betweenIdentifiers3() {
+    // "a  b;"
+    // "a . b;"
     scan("a ", "", ".", " b;");
     assertTokens(0, 2, ["a", ".", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_period_insideExistingIdentifier() {
+    // "ab;"
+    // "a.b;"
     scan("a", "", ".", "b;");
     assertTokens(-1, 3, ["a", ".", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_periodAndIdentifier() {
+    // "a + b;"
+    // "a + b.x;"
     scan("a + b", "", ".x", ";");
     assertTokens(2, 5, ["a", "+", "b", ".", "x", ";"]);
   }
 
   void test_insert_whitespace_beginning_beforeToken() {
+    // "a + b;"
+    // " a + b;"
     scan("", "", " ", "a + b;");
     assertTokens(0, 1, ["a", "+", "b", ";"]);
     JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_whitespace_betweenTokens() {
+    // "a + b;"
+    // "a  + b;"
     scan("a ", "", " ", "+ b;");
     assertTokens(1, 2, ["a", "+", "b", ";"]);
     JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_whitespace_end_afterToken() {
+    // "a + b;"
+    // "a + b; "
     scan("a + b;", "", " ", "");
     assertTokens(3, 4, ["a", "+", "b", ";"]);
     JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_whitespace_end_afterWhitespace() {
+    // "a + b; "
+    // "a + b;  "
     scan("a + b; ", "", " ", "");
     assertTokens(3, 4, ["a", "+", "b", ";"]);
     JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_insert_whitespace_withMultipleComments() {
+    // "//comment", "//comment2", "a + b;"
+    // "//comment", "//comment2", "a  + b;"
     scan(EngineTestCase.createSource(["//comment", "//comment2", "a"]), "", " ", " + b;");
     assertTokens(1, 2, ["a", "+", "b", ";"]);
     JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_replace_identifier_beginning() {
+    // "bell + b;"
+    // "fell + b;")
     scan("", "b", "f", "ell + b;");
     assertTokens(-1, 1, ["fell", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_replace_identifier_end() {
+    // "bell + b;"
+    // "belt + b;")
     scan("bel", "l", "t", " + b;");
     assertTokens(-1, 1, ["belt", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_replace_identifier_middle() {
+    // "first + b;"
+    // "frost + b;")
     scan("f", "ir", "ro", "st + b;");
     assertTokens(-1, 1, ["frost", "+", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_replace_multiple_partialFirstAndLast() {
+    // "aa + bb;"
+    // "ab * ab;")
     scan("a", "a + b", "b * a", "b;");
     assertTokens(-1, 3, ["ab", "*", "ab", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_replace_operator_oneForMany() {
+    // "a + b;"
+    // "a * c - b;")
     scan("a ", "+", "* c -", " b;");
     assertTokens(0, 4, ["a", "*", "c", "-", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_replace_operator_oneForOne() {
+    // "a + b;"
+    // "a * b;")
     scan("a ", "+", "*", " b;");
     assertTokens(0, 2, ["a", "*", "b", ";"]);
     JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange());
   }
 
   void test_tokenMap() {
+    // "main() {a + b;}"
+    // "main() { a + b;}"
     scan("main() {", "", " ", "a + b;}");
     TokenMap tokenMap = _incrementalScanner.tokenMap;
     Token oldToken = _originalTokens;
@@ -2156,21 +2239,37 @@
    * @param suffix the unchanged text after the edit region
    */
   void scan(String prefix, String removed, String added, String suffix) {
+    //
+    // Compute the information needed to perform the test.
+    //
     String originalContents = "${prefix}${removed}${suffix}";
     String modifiedContents = "${prefix}${added}${suffix}";
     int replaceStart = prefix.length;
     Source source = new TestSource();
+    //
+    // Scan the original contents.
+    //
     GatheringErrorListener originalListener = new GatheringErrorListener();
     Scanner originalScanner = new Scanner(source, new CharSequenceReader(new CharSequence(originalContents)), originalListener);
     _originalTokens = originalScanner.tokenize();
     JUnitTestCase.assertNotNull(_originalTokens);
+    //
+    // Scan the modified contents.
+    //
     GatheringErrorListener modifiedListener = new GatheringErrorListener();
     Scanner modifiedScanner = new Scanner(source, new CharSequenceReader(new CharSequence(modifiedContents)), modifiedListener);
     Token modifiedTokens = modifiedScanner.tokenize();
     JUnitTestCase.assertNotNull(modifiedTokens);
+    //
+    // Incrementally scan the modified contents.
+    //
     GatheringErrorListener incrementalListener = new GatheringErrorListener();
     _incrementalScanner = new IncrementalScanner(source, new CharSequenceReader(new CharSequence(modifiedContents)), incrementalListener);
     _incrementalTokens = _incrementalScanner.rescan(_originalTokens, replaceStart, removed.length, added.length);
+    //
+    // Validate that the results of the incremental scan are the same as the full scan of the
+    // modified source.
+    //
     Token incrementalToken = _incrementalTokens;
     JUnitTestCase.assertNotNull(incrementalToken);
     while (incrementalToken.type != TokenType.EOF && modifiedTokens.type != TokenType.EOF) {
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 8186ce4..2e1b72b 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
@@ -103,9 +107,15 @@
    */
   void assertErrors2(List<ErrorCode> expectedErrorCodes) {
     JavaStringBuilder builder = new JavaStringBuilder();
+    //
+    // Verify that the expected error codes have a non-empty message.
+    //
     for (ErrorCode errorCode in expectedErrorCodes) {
       JUnitTestCase.assertFalseMsg("Empty error code message", errorCode.message.isEmpty);
     }
+    //
+    // Compute the expected number of each type of error.
+    //
     Map<ErrorCode, int> expectedCounts = new Map<ErrorCode, int>();
     for (ErrorCode code in expectedErrorCodes) {
       int count = expectedCounts[code];
@@ -116,6 +126,9 @@
       }
       expectedCounts[code] = count;
     }
+    //
+    // Compute the actual number of each type of error.
+    //
     Map<ErrorCode, List<AnalysisError>> errorsByCode = new Map<ErrorCode, List<AnalysisError>>();
     for (AnalysisError error in _errors) {
       ErrorCode code = error.errorCode;
@@ -126,6 +139,9 @@
       }
       list.add(error);
     }
+    //
+    // Compare the expected and actual number of each type of error.
+    //
     for (MapEntry<ErrorCode, int> entry in getMapEntrySet(expectedCounts)) {
       ErrorCode code = entry.getKey();
       int expectedCount = entry.getValue();
@@ -149,6 +165,9 @@
         builder.append(actualCount);
       }
     }
+    //
+    // Check that there are no more errors in the actual-errors map, otherwise, record message.
+    //
     for (MapEntry<ErrorCode, List<AnalysisError>> entry in getMapEntrySet(errorsByCode)) {
       ErrorCode code = entry.getKey();
       List<AnalysisError> actualErrors = entry.getValue();
@@ -421,6 +440,22 @@
   }
 
   /**
+   * Assert that the given collection is non-`null` and has the expected number of elements.
+   *
+   * @param expectedSize the expected number of elements
+   * @param c the collection being tested
+   * @throws AssertionFailedError if the list is `null` or does not have the expected number
+   *           of elements
+   */
+  static void assertCollectionSize(int expectedSize, Iterable c) {
+    if (c == null) {
+      JUnitTestCase.fail("Expected collection of size ${expectedSize}; found null");
+    } else if (c.length != expectedSize) {
+      JUnitTestCase.fail("Expected collection of size ${expectedSize}; contained ${c.length} elements");
+    }
+  }
+
+  /**
    * Assert that the given array is non-`null` and contains the expected elements. The
    * elements can appear in any order.
    *
@@ -496,6 +531,7 @@
       int diffAhead = Math.max(0, diffPos - _PRINT_RANGE);
       int diffAfter = Math.min(actual.length, diffPos + _PRINT_RANGE);
       String diffStr = "${actual.substring(diffAhead, diffPos)}^${actual.substring(diffPos, diffAfter)}";
+      // use detailed message
       String message = "Content not as expected: is\n${actual}\nDiffers at pos ${diffPos}: ${diffStr}\nexpected:\n${expected}";
       JUnitTestCase.assertEqualsMsg(message, expected, actual);
     }
@@ -519,7 +555,7 @@
     for (int i = 0; i < expectedSize; i++) {
       Object element = list[i];
       Object expectedElement = expectedElements[i];
-      if (!element == expectedElement) {
+      if (element != expectedElement) {
         JUnitTestCase.fail("Expected ${expectedElement} at [${i}]; found ${element}");
       }
     }
@@ -544,7 +580,7 @@
     for (int i = 0; i < expectedSize; i++) {
       Object element = array[i];
       Object expectedElement = expectedElements[i];
-      if (!element == expectedElement) {
+      if (element != expectedElement) {
         JUnitTestCase.fail("Expected ${expectedElement} at [${i}]; found ${element}");
       }
     }
@@ -585,7 +621,7 @@
     if (!isInstanceOf(object, expectedClass)) {
       JUnitTestCase.fail("Expected instance of ${expectedClass.toString()}, found ${(object == null ? "null" : object.runtimeType.toString())}");
     }
-    return object as Object;
+    return object;
   }
 
   /**
@@ -616,26 +652,10 @@
     JUnitTestCase.assertEquals(expectedToken.type, actualToken.type);
     if (expectedToken is KeywordToken) {
       assertInstanceOf(KeywordToken, actualToken);
-      JUnitTestCase.assertEquals((expectedToken as KeywordToken).keyword, (actualToken as KeywordToken).keyword);
+      JUnitTestCase.assertEquals(expectedToken.keyword, (actualToken as KeywordToken).keyword);
     } else if (expectedToken is StringToken) {
       assertInstanceOf(StringToken, actualToken);
-      JUnitTestCase.assertEquals((expectedToken as StringToken).lexeme, (actualToken as StringToken).lexeme);
-    }
-  }
-
-  /**
-   * Assert that the given collection is non-`null` and has the expected number of elements.
-   *
-   * @param expectedSize the expected number of elements
-   * @param c the collection being tested
-   * @throws AssertionFailedError if the list is `null` or does not have the expected number
-   *           of elements
-   */
-  static void assertCollectionSize(int expectedSize, Iterable c) {
-    if (c == null) {
-      JUnitTestCase.fail("Expected collection of size ${expectedSize}; found null");
-    } else if (c.length != expectedSize) {
-      JUnitTestCase.fail("Expected collection of size ${expectedSize}; contained ${c.length} elements");
+      JUnitTestCase.assertEquals(expectedToken.lexeme, (actualToken as StringToken).lexeme);
     }
   }
 
diff --git a/pkg/analyzer/test/services/data/cu_tests.data b/pkg/analyzer/test/services/data/cu_tests.data
index 6e1547a..2d77611 100644
--- a/pkg/analyzer/test/services/data/cu_tests.data
+++ b/pkg/analyzer/test/services/data/cu_tests.data
@@ -5,4 +5,166 @@
 }
 <<<
 class A {
-}
\ No newline at end of file
+}
+>>> dartbug.com/15876
+// fisk
+import "dart:typed_data";
+
+main() {
+  ByteData byteData = new ByteData(1);
+  print(byteData is ByteData);
+  print(byteData.elementSizeInBytes);
+}
+<<<
+// fisk
+import "dart:typed_data";
+
+main() {
+  ByteData byteData = new ByteData(1);
+  print(byteData is ByteData);
+  print(byteData.elementSizeInBytes);
+}
+>>>
+/**
+ * Y.
+ */
+abstract class Y = String;
+<<<
+/**
+ * Y.
+ */
+abstract class Y = String;
+>>>
+external void printToConsole(String line);
+<<<
+external void printToConsole(String line);
+>>>
+void set foo(int bar) {
+}
+
+int get baz => null;
+<<<
+void set foo(int bar) {
+}
+
+int get baz => null;
+>>>
+@deprecated
+library foo;
+
+@deprecated
+import 'dart:io';
+
+@deprecated
+export 'dart:io';
+
+class NoInline {
+  const NoInline();
+}
+
+@NoInline()
+int foo(@NoInline() bar) => bar + 42;
+
+class Z<@NoInline() Y> {
+
+}
+
+@NoInline()
+typedef void X(y);
+
+@NoInline()
+class Y = X;
+
+@NoInline()
+class X {
+
+  @NoInline()
+  var _x;
+
+  @NoInline()
+  X.y() {
+    @NoInline()
+    const y = null;
+  }
+
+  @NoInline()
+  factory X(@NoInline() x) => null;
+
+  @NoInline()
+  int x() => null;
+}
+<<<
+@deprecated
+library foo;
+
+@deprecated
+import 'dart:io';
+
+@deprecated
+export 'dart:io';
+
+class NoInline {
+  const NoInline();
+}
+
+@NoInline()
+int foo(@NoInline() bar) => bar + 42;
+
+class Z<@NoInline() Y> {
+
+}
+
+@NoInline()
+typedef void X(y);
+
+@NoInline()
+class Y = X;
+
+@NoInline()
+class X {
+
+  @NoInline()
+  var _x;
+
+  @NoInline()
+  X.y() {
+    @NoInline()
+    const y = null;
+  }
+
+  @NoInline()
+  factory X(@NoInline() x) => null;
+
+  @NoInline()
+  int x() => null;
+}
+>>>
+Object get _globalState => null;
+
+set _globalState(Object val) {
+}
+<<<
+Object get _globalState => null;
+
+set _globalState(Object val) {
+}
+>>>
+var x = #foo;
+var y=#foo.bar.baz;
+<<<
+var x = #foo;
+var y = #foo.bar.baz;
+>>>
+class Zounds extends Object native "Zapp" {
+}
+<<<
+class Zounds extends Object native "Zapp" {
+}
+>>>
+@DomName('DatabaseCallback')
+@Experimental() // deprecated
+typedef void DatabaseCallback(database);
+<<<
+@DomName('DatabaseCallback')
+@Experimental() // deprecated
+typedef void DatabaseCallback(database);
diff --git a/pkg/analyzer/test/services/data/stmt_tests.data b/pkg/analyzer/test/services/data/stmt_tests.data
index ca6096c..a01c7d5 100644
--- a/pkg/analyzer/test/services/data/stmt_tests.data
+++ b/pkg/analyzer/test/services/data/stmt_tests.data
@@ -24,4 +24,24 @@
 <<<
 for (var a = 0; a < 100; ++a) {
   print(a);
+}
+>>>
+for (x in xs) {
+  print(x);
+}
+<<<
+for (x in xs) {
+  print(x);
+}
+>>> TODO(pquitslund): FIX
+var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71];
+<<<
+var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71];
+>>> TODO(pquitslund): placeholder for when we turn the real line breaker on
+blah() {
+  print('blah blah blah blah blah blah blah blah blah blah blah blah blah blah $foo');
+}
+<<<<
+blah() {
+  print('blah blah blah blah blah blah blah blah blah blah blah blah blah blah $foo');
 }
\ No newline at end of file
diff --git a/pkg/analyzer/test/services/data/style_guide_tests.data b/pkg/analyzer/test/services/data/style_guide_tests.data
new file mode 100644
index 0000000..d0b49ef
--- /dev/null
+++ b/pkg/analyzer/test/services/data/style_guide_tests.data
@@ -0,0 +1,225 @@
+>>> DO use ; instead of {} for empty constructor bodies
+class Point {
+  int x, y;
+  Point(this.x, this.y) {}
+}
+<<<
+class Point {
+  int x, y;
+  Point(this.x, this.y);
+}
+>>> DO indent block bodies two spaces.
+hi() {
+if (condition) { print('hi'); }
+}
+<<<
+hi() {
+  if (condition) {
+    print('hi');
+  }
+}
+>>> DON'T indent lines that are continued with a function expression.
+var callback = new Future.delayed(const Duration(seconds: 1), () {
+      print('I am a callback');
+    });
+<<<
+var callback = new Future.delayed(const Duration(seconds: 1), () {
+  print('I am a callback');
+});
+>>> DO place the opening curly brace ({) on the same line as what it follows.
+class Foo {
+  method() 
+  {
+    if (true) 
+    {
+      print('true');
+    } else {
+      print('false');
+    }
+  }
+}
+<<<
+class Foo {
+  method() {
+    if (true) {
+      print('true');
+    } else {
+      print('false');
+    }
+  }
+}
+>>> DO use curly braces for all flow control structures.
+flow() {
+  if (true) print('sanity');
+  else
+    print('opposite day!');
+}
+<<<
+flow() {
+  if (true) {
+    print('sanity');
+  } else {
+    print('opposite day!');
+  }
+}
+>>> ... short if statements with no else may omit the braces ...
+except() {
+  if (arg == null) return defaultValue;
+}
+<<<
+except() {
+  if (arg == null) return defaultValue;
+}
+>>> DO indent switch cases two spaces and case bodies four spaces
+switches() {
+  switch (fruit) {
+    case 'apple':
+    print('delish');
+    break;
+
+    case 'durian':
+    print('stinky');
+    break;
+  }
+}
+<<<
+switches() {
+  switch (fruit) {
+    case 'apple':
+      print('delish');
+      break;
+
+    case 'durian':
+      print('stinky');
+      break;
+  }
+}
+>>> DO use spaces around binary and ternary operators, etc...
+spaces() {
+  a=1+2/(3* - b);
+  c= ! condition==a>b;
+  d= condition?b:object.method(a,b,c);
+  if (obj is !SomeType) print('not SomeType');
+}
+<<<
+spaces() {
+  a = 1 + 2 / (3 * -b);
+  c = !condition == a > b;
+  d = condition ? b : object.method(a, b, c);
+  if (obj is! SomeType) print('not SomeType');
+}
+>>> DO place spaces around in, and after each ; in a loop.
+loop() {
+  for (var i = 0;i<100;i++) {
+    print(i);
+  }
+  for (final item in  collection) {
+    print(item);
+  }
+}
+<<<
+loop() {
+  for (var i = 0; i < 100; i++) {
+    print(i);
+  }
+  for (final item in collection) {
+    print(item);
+  }
+}
+>>> DO use a space after flow-control keywords.
+flow() {
+  while(foo) {
+    print(foo);
+  }
+
+  try{
+    flow();
+  }catch(e) {
+    print(e);
+  }
+}
+<<<
+flow() {
+  while (foo) {
+    print(foo);
+  }
+
+  try {
+    flow();
+  } catch (e) {
+    print(e);
+  }
+}
+>>> DON'T use a space after (, [, and {, or before ), ], and }.
+spaces() {
+  var numbers = <int> [ 1, 2,( 3+4 ) ];
+}
+<<<
+spaces() {
+  var numbers = <int>[1, 2, (3 + 4)];
+}
+>>> DO use a space before { in function and method bodies.
+getEmptyFn(a){
+  return (){};
+}
+<<<
+getEmptyFn(a) {
+  return () {
+  };
+}
+>>> DO format constructor initialization lists with each field on its own line.
+class MyClass {
+  var firstField, secondField, thirdField;
+  MyClass() : firstField = "some value", secondField = "another",
+        thirdField = "last";
+}
+<<<
+class MyClass {
+  var firstField, secondField, thirdField;
+  MyClass()
+      : firstField = "some value",
+        secondField = "another",
+        thirdField = "last";
+}
+>>> DO use a space after : in named parameters and named arguments.
+class ListBox {
+  bool showScrollbars;
+
+  ListBox({this.showScrollbars: false});
+}
+
+main() {
+  new ListBox(showScrollbars:true);
+  new ListBox(showScrollbars : true);
+}
+<<<
+class ListBox {
+  bool showScrollbars;
+
+  ListBox({this.showScrollbars: false});
+}
+
+main() {
+  new ListBox(showScrollbars: true);
+  new ListBox(showScrollbars: true);
+}
+>>> DO use a spaces around = in optional positional parameters.
+class HttpServer {
+  static Future<HttpServer> listen([int port=80]) {
+    print('hi!');
+  }
+}
+<<<
+class HttpServer {
+  static Future<HttpServer> listen([int port = 80]) {
+    print('hi!');
+  }
+}
+>>> DO use four spaces for method cascades
+var list = new List()
+  ..addAll([1, 2, 3])
+  ..addAll([4, 5, 6]);
+<<<
+var list = new List()
+    ..addAll([1, 2, 3])
+    ..addAll([4, 5, 6]);
diff --git a/pkg/analyzer/test/services/formatter_test.dart b/pkg/analyzer/test/services/formatter_test.dart
index 3d26066..a710a4f 100644
--- a/pkg/analyzer/test/services/formatter_test.dart
+++ b/pkg/analyzer/test/services/formatter_test.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-//import 'dart:io';
+import 'dart:io';
 
+import 'package:path/path.dart';
 import 'package:unittest/unittest.dart';
 
 import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
@@ -11,23 +12,31 @@
 import 'package:analyzer/src/services/formatter_impl.dart';
 import 'package:analyzer/src/services/writer.dart';
 
+// Test data location ('pkg/analyzer/test/services/data')
+final TEST_DATA_DIR = join(dirname(fromUri(Platform.script)), 'data');
+
 main() {
 
-//TODO(pquitslund): disabled pending build investigation
+  /// Data-driven statement tests
+  group('stmt_tests.data', () {
+    runTests('stmt_tests.data', (input, expectedOutput) {
+      expect(formatStatement(input) + '\n', equals(expectedOutput));
+    });
+  });
 
-//  /// Data driven statement tests
-//  group('stmt_tests.data', () {
-//    runTests(new File('data/stmt_tests.data'), (input, expectedOutput) {
-//      expect(formatStatement(input) + '\n', equals(expectedOutput));
-//    });
-//  });
-//
-//  /// Data driven compilation unit tests
-//  group('cu_tests.data', () {
-//    runTests(new File('data/cu_tests.data'), (input, expectedOutput) {
-//      expectCUFormatsTo(input, expectedOutput);
-//    });
-//  });
+  /// Data-driven compilation unit tests
+  group('cu_tests.data', () {
+    runTests('cu_tests.data', (input, expectedOutput) {
+      expectCUFormatsTo(input, expectedOutput);
+    });
+  });
+
+  /// Data-driven Style Guide acceptance tests
+  group('style_guide_tests.data', () {
+    runTests('style_guide_tests.data', (input, expectedOutput) {
+      expectCUFormatsTo(input, expectedOutput);
+    });
+  });
 
   /// Formatter tests
   group('formatter', () {
@@ -1168,7 +1177,6 @@
 
   });
 
-
   /// Writer tests
   group('writer', () {
 
@@ -1208,13 +1216,109 @@
   });
 
 
+
+  /// Line breaker tests
+  group('linebreaker', () {
+
+    List<Chunk> breakLine(Line line, int maxLength) =>
+        new SimpleLineBreaker(maxLength).breakLine(line);
+
+    String printLine(Line line, int maxLength) =>
+        new SimpleLineBreaker(maxLength).printLine(line);
+
+    Line line(List tokens) {
+      var line = new Line();
+      tokens.forEach((t) =>
+          line.addToken(t is LineToken ? t : new LineToken(t)));
+      return line;
+    }
+
+    expectTextsEqual(List<Chunk> chunks, List<String> texts) {
+      expect(chunks.map((chunk) => chunk.toString()), orderedEquals(texts));
+    }
+
+    final SP_1 = new SpaceToken(1, breakWeight: 1);
+
+    // 'foo|1|bar|1|baz|1|foo|1|bar|1|baz'
+    final LINE_1 = line(['foo', SP_1, 'bar', SP_1, 'baz', SP_1,
+                         'foo', SP_1, 'bar', SP_1, 'baz']);
+
+    // '  foo|1|bar|1|baz|1|foo|1|bar|1|baz'
+    final LINE_2 = line(['  foo', SP_1, 'bar', SP_1, 'baz', SP_1,
+                         'foo', SP_1, 'bar', SP_1, 'baz']);
+
+    test('breakLine - 0', () {
+      var chunks = breakLine(line(['  foo']), 8);
+      expectTextsEqual(chunks, ['  foo']);
+    });
+
+    test('breakLine - 1', () {
+      var chunks = breakLine(LINE_1, 1);
+      expectTextsEqual(chunks, ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']);
+    });
+
+    test('breakLine - 2', () {
+      var chunks = breakLine(LINE_1, 4);
+      expectTextsEqual(chunks, ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']);
+    });
+
+    test('breakLine - 3', () {
+      var chunks = breakLine(LINE_1, 8);
+      expectTextsEqual(chunks, ['foo bar', 'baz foo', 'bar baz']);
+    });
+
+    test('breakLine - 4', () {
+      var chunks = breakLine(LINE_1, 12);
+      expectTextsEqual(chunks, ['foo bar baz', 'foo bar baz']);
+    });
+
+    test('breakLine - 5', () {
+      var chunks = breakLine(LINE_2, 16);
+      expectTextsEqual(chunks, ['  foo bar baz', 'foo bar baz']);
+    });
+
+    test('printLine - 1', () {
+      var line = printLine(LINE_1, 1);
+      expect(line, 'foo\nbar\nbaz\nfoo\nbar\nbaz');
+    });
+
+    test('printLine - 2', () {
+      var line = printLine(LINE_1, 4);
+      expect(line, 'foo\nbar\nbaz\nfoo\nbar\nbaz');
+    });
+
+    test('printLine - 3', () {
+      var line = printLine(LINE_1, 8);
+      expect(line, 'foo bar\nbaz foo\nbar baz');
+    });
+
+    test('printLine - 4', () {
+      var line = printLine(LINE_1, 12);
+      expect(line, 'foo bar baz\nfoo bar baz');
+    });
+
+    test('isWhitespace', () {
+      expect(isWhitespace('foo'), false);
+      expect(isWhitespace('  foo'), false);
+      expect(isWhitespace('foo  '), false);
+      expect(isWhitespace(' foo '), false);
+      expect(isWhitespace(' '), true);
+      expect(isWhitespace('  '), true);
+      expect(isWhitespace('\t'), true);
+      expect(isWhitespace('\t\t'), true);
+      expect(isWhitespace('\n'), true);
+      expect(isWhitespace('\r'), true);
+    });
+
+  });
+
   /// Helper method tests
   group('helpers', () {
 
     test('indentString', () {
       expect(getIndentString(0), '');
-      expect(getIndentString(1), ' ');
-      expect(getIndentString(4), '    ');
+      expect(getIndentString(1), '  ');
+      expect(getIndentString(4), '        ');
     });
 
     test('indentString (tabbed)', () {
@@ -1308,17 +1412,19 @@
     expect(formatStatement(src, options:
       new FormatterOptions(codeTransforms: transforms)), equals(expected));
 
-runTests(testFile, expectClause(input, output)) {
+
+runTests(testFileName, expectClause(input, output)) {
 
   var testIndex = 1;
+  var testFile = new File(join(TEST_DATA_DIR, testFileName));
   var lines = testFile.readAsLinesSync();
 
   for (var i = 1; i < lines.length; ++i) {
     var input = '', expectedOutput = '';
-    while(lines[i] != '<<<') {
+    while(!lines[i].startsWith('<<<')) {
       input += lines[i++] + '\n';
     }
-    while(++i < lines.length && lines[i] != '>>>') {
+    while(++i < lines.length && !lines[i].startsWith('>>>')) {
       expectedOutput += lines[i] + '\n';
     }
     test('test - (${testIndex++})', () {
diff --git a/pkg/args/LICENSE b/pkg/args/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/args/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/args/pubspec.yaml b/pkg/args/pubspec.yaml
index 771fdb1..ab3bbdd 100644
--- a/pkg/args/pubspec.yaml
+++ b/pkg/args/pubspec.yaml
@@ -1,5 +1,5 @@
 name: args
-version: 0.10.0
+version: 0.10.0+1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/args
diff --git a/pkg/async/pubspec.yaml b/pkg/async/pubspec.yaml
index 3603226..5c9a328 100644
--- a/pkg/async/pubspec.yaml
+++ b/pkg/async/pubspec.yaml
@@ -1,5 +1,5 @@
 name: async
-version: 0.9.0
+version: 0.9.1
 author: Dart Team <misc@dartlang.org>
 description: Utility functions and classes related to the 'dart:async' library.
 homepage: http://www.dartlang.org
diff --git a/pkg/async_helper/LICENSE b/pkg/async_helper/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/async_helper/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/barback/lib/barback.dart b/pkg/barback/lib/barback.dart
index 25bb386..e939436 100644
--- a/pkg/barback/lib/barback.dart
+++ b/pkg/barback/lib/barback.dart
@@ -4,6 +4,9 @@
 
 library barback;
 
+import 'src/transform.dart';
+import 'src/transformer.dart';
+
 export 'src/asset.dart';
 export 'src/asset_id.dart';
 export 'src/asset_set.dart';
diff --git a/pkg/barback/lib/src/stream_replayer.dart b/pkg/barback/lib/src/stream_replayer.dart
index 705f97a..66a056a 100644
--- a/pkg/barback/lib/src/stream_replayer.dart
+++ b/pkg/barback/lib/src/stream_replayer.dart
@@ -27,9 +27,9 @@
   /// The buffer of events or errors that have already been emitted by
   /// [_stream].
   ///
-  /// Each element is a [Either] that's either a value or an error sent through
-  /// the stream.
-  final _buffer = new Queue<Either<T, Pair<dynamic, StackTrace>>>();
+  /// Each element is a [Fallible] that's either a value or an error sent
+  /// through the stream.
+  final _buffer = new Queue<Fallible<T>>();
 
   /// The controllers that are listening for future events from [_stream].
   final _controllers = new Set<StreamController<T>>();
@@ -43,9 +43,11 @@
     var controller = new StreamController<T>(onListen: _subscribe);
 
     for (var eventOrError in _buffer) {
-      eventOrError.match(controller.add, (pair) {
-        controller.addError(pair.first, pair.second);
-      });
+      if (eventOrError.hasValue) {
+        controller.add(eventOrError.value);
+      } else {
+        controller.addError(eventOrError.error, eventOrError.stackTrace);
+      }
     }
     if (_isClosed) {
       controller.close();
@@ -61,13 +63,12 @@
     _isSubscribed = true;
 
     _stream.listen((data) {
-      _buffer.add(new Either<T, dynamic>.withFirst(data));
+      _buffer.add(new Fallible<T>.withValue(data));
       for (var controller in _controllers) {
         controller.add(data);
       }
     }, onError: (error, [stackTrace]) {
-      _buffer.add(new Either<T, Pair<dynamic, StackTrace>>.withSecond(
-          new Pair<dynamic, StackTrace>(error, stackTrace)));
+      _buffer.add(new Fallible<T>.withError(error, stackTrace));
       for (var controller in _controllers) {
         controller.addError(error, stackTrace);
       }
diff --git a/pkg/barback/lib/src/utils.dart b/pkg/barback/lib/src/utils.dart
index a4a5950..f1bcddd 100644
--- a/pkg/barback/lib/src/utils.dart
+++ b/pkg/barback/lib/src/utils.dart
@@ -9,67 +9,79 @@
 
 import 'package:stack_trace/stack_trace.dart';
 
-/// A pair of values.
-class Pair<E, F> {
-  E first;
-  F last;
+/// A class that represents a value or an error.
+class Fallible<E> {
+  /// Whether [this] has a [value], as opposed to an [error].
+  final bool hasValue;
 
-  Pair(this.first, this.last);
+  /// Whether [this] has an [error], as opposed to a [value].
+  bool get hasError => !hasValue;
 
-  String toString() => '($first, $last)';
-
-  bool operator==(other) {
-    if (other is! Pair) return false;
-    return other.first == first && other.last == last;
-  }
-
-  int get hashCode => first.hashCode ^ last.hashCode;
-}
-
-/// A class that represents one and only one of two types of values.
-class Either<E, F> {
-  /// Whether this is a value of type `E`.
-  final bool isFirst;
-
-  /// Whether this is a value of type `F`.
-  bool get isSecond => !isFirst;
-
-  /// The value, either of type `E` or `F`.
-  final _value;
-
-  /// The value of type `E`.
+  /// The value.
   ///
-  /// It's an error to access this is this is of type `F`.
-  E get first {
-    assert(isFirst);
-    return _value;
-  }
+  /// This will be `null` if [this] has an [error].
+  final E _value;
 
-  /// The value of type `F`.
+  /// The value.
   ///
-  /// It's an error to access this is this is of type `E`.
-  F get second {
-    assert(isSecond);
-    return _value;
+  /// This will throw a [StateError] if [this] has an [error].
+  E get value {
+    if (hasValue) return _value;
+    throw new StateError("Fallible has no value.\n"
+        "$_error$_stackTraceSuffix");
   }
 
-  /// Creates an [Either] with type `E`.
-  Either.withFirst(this._value)
-      : isFirst = true;
-
-  /// Creates an [Either] with type `F`.
-  Either.withSecond(this._value)
-      : isFirst = false;
-
-  /// Runs [whenFirst] or [whenSecond] depending on the type of [this].
+  /// The error.
   ///
-  /// Returns the result of whichvever function was run.
-  match(whenFirst(E value), whenSecond(F value)) {
-    if (isFirst) return whenFirst(first);
-    return whenSecond(second);
+  /// This will be `null` if [this] has a [value].
+  final _error;
+
+  /// The error.
+  ///
+  /// This will throw a [StateError] if [this] has a [value].
+  get error {
+    if (hasError) return _error;
+    throw new StateError("Fallible has no error.");
   }
 
-  String toString() => "$_value (${isFirst? 'first' : 'second'})";
+  /// The stack trace for [_error].
+  ///
+  /// This will be `null` if [this] has a [value], or if no stack trace was
+  /// provided.
+  final StackTrace _stackTrace;
+
+  /// The stack trace for [error].
+  ///
+  /// This will throw a [StateError] if [this] has a [value].
+  StackTrace get stackTrace {
+    if (hasError) return _stackTrace;
+    throw new StateError("Fallible has no error.");
+  }
+
+  Fallible.withValue(this._value)
+      : _error = null,
+        _stackTrace = null,
+        hasValue = true;
+
+  Fallible.withError(this._error, [this._stackTrace])
+      : _value = null,
+        hasValue = false;
+
+  /// Returns a completed Future with the same value or error as [this].
+  Future toFuture() {
+    if (hasValue) return new Future.value(value);
+    return new Future.error(error, stackTrace);
+  }
+
+  String toString() {
+    if (hasValue) return "Fallible value: $value";
+    return "Fallible error: $error$_stackTraceSuffix";
+  }
+
+  String get _stackTraceSuffix {
+    if (stackTrace == null) return "";
+    return "\nStack trace:\n${new Chain.forTrace(_stackTrace).terse}";
+  }
 }
 
 /// Converts a number in the range [0-255] to a two digit hex string.
diff --git a/pkg/barback/pubspec.yaml b/pkg/barback/pubspec.yaml
index c7e59ce..a0e29c2 100644
--- a/pkg/barback/pubspec.yaml
+++ b/pkg/barback/pubspec.yaml
@@ -8,7 +8,7 @@
 # When the minor version of this is upgraded, you *must* update that version
 # number in pub to stay in sync with this. New patch versions are considered
 # backwards compatible, and pub will allow later patch versions automatically.
-version: 0.11.0
+version: 0.11.0+1
 
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
diff --git a/pkg/browser/LICENSE b/pkg/browser/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/browser/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/browser/lib/dart.js b/pkg/browser/lib/dart.js
index 0fd6217..f8d686e 100644
--- a/pkg/browser/lib/dart.js
+++ b/pkg/browser/lib/dart.js
@@ -11,10 +11,7 @@
 
   // Fall back to compiled JS. Run through all the scripts and
   // replace them if they have a type that indicate that they source
-  // in Dart code.
-  //
-  //   <script type="application/dart" src="..."></script>
-  //
+  // in Dart code (type="application/dart").
   var scripts = document.getElementsByTagName("script");
   var length = scripts.length;
   for (var i = 0; i < length; ++i) {
diff --git a/pkg/browser/pubspec.yaml b/pkg/browser/pubspec.yaml
index 635ca17..88b59b9 100644
--- a/pkg/browser/pubspec.yaml
+++ b/pkg/browser/pubspec.yaml
@@ -1,5 +1,5 @@
 name: browser
-version: 0.9.0
+version: 0.9.1
 authors: ["Dart Team <misc@dartlang.org>"]
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/collection/README.md b/pkg/collection/README.md
index bb392fd..7ebd62a 100644
--- a/pkg/collection/README.md
+++ b/pkg/collection/README.md
@@ -8,14 +8,24 @@
 The `collection` package can be imported as separate libraries, or
 in totality:
 
-    import 'package:collection/equality.dart';
     import 'package:collection/algorithms.dart';
+    import 'package:collection/equality.dart';
+    import 'package:collection/iterable_zip.dart';
+    import 'package:collection/priority_queue.dart';
     import 'package:collection/wrappers.dart';
 
 or
 
     import 'package:collection/collection.dart';
 
+## Algorithms
+
+The algorithms library contains functions that operate on lists.
+
+It contains ways to shuffle a `List`, do binary search on a sorted `List`, and
+various sorting algorithms.
+
+
 ## Equality
 
 The equality library gives a way to specify equality of elements and
@@ -28,19 +38,23 @@
 case, for example, `const SetEquality(const IdentityEquality())` is an equality
 that considers two sets equal exactly if they contain identical elements.
 
-The library provides ways to define equalities on `Iterable`s, `List`s, `Set`s, and
-`Map`s, as well as combinations of these, such as:
+The library provides ways to define equalities on `Iterable`s, `List`s, `Set`s,
+and `Map`s, as well as combinations of these, such as:
 
     const MapEquality(const IdentityEquality(), const ListEquality());
 
-This equality considers maps equal if they have identical keys, and the corresponding values are lists with equal (`operator==`) values.
+This equality considers maps equal if they have identical keys, and the
+corresponding values are lists with equal (`operator==`) values.
 
-## Algorithms
 
-The algorithms library contains functions that operate on lists.
+## Iterable Zip
 
-It contains ways to shuffle a `List`, do binary search on a sorted `List`, and
-some different sorting algorithms.
+Utilities for "zipping" a list of iterables into an iterable of lists.
+
+
+## Priority Queue
+
+An interface and implemention of a priority queue.
 
 
 ## Wrappers
diff --git a/pkg/collection/lib/collection.dart b/pkg/collection/lib/collection.dart
index a6f192d..d640071 100644
--- a/pkg/collection/lib/collection.dart
+++ b/pkg/collection/lib/collection.dart
@@ -11,6 +11,7 @@
  *                      and various sorting algorithms).
  * - `equality.dart`: Different notions of equality of collections.
  * - `iterable_zip.dart`: Combining multiple iterables into one.
+ * - `priority_queue.dart`: Priority queue type and implementations.
  * - `wrappers.dart`: Wrapper classes that delegate to a collection object.
  *                    Includes unmodifiable views of collections.
  */
@@ -19,4 +20,5 @@
 export "algorithms.dart";
 export "equality.dart";
 export "iterable_zip.dart";
+export "priority_queue.dart";
 export "wrappers.dart";
diff --git a/pkg/collection/lib/priority_queue.dart b/pkg/collection/lib/priority_queue.dart
new file mode 100644
index 0000000..efb3239
--- /dev/null
+++ b/pkg/collection/lib/priority_queue.dart
@@ -0,0 +1,396 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart.pkg.collection.priority_queue;
+
+import "dart:collection" show SplayTreeSet;
+
+/**
+ * A priority queue is a priority based work-list of elements.
+ *
+ * The queue allows adding elements, and removing them again in priority order.
+ */
+abstract class PriorityQueue<E> {
+  /**
+   * Number of elements in the queue.
+   */
+  int get length;
+
+  /**
+   * Whether the queue is empty.
+   */
+  bool get isEmpty;
+
+  /**
+   * Whether the queue has any elements.
+   */
+  bool get isNotEmpty;
+
+  /**
+   * Checks if [object] is in the queue.
+   *
+   * Returns true if the element is found.
+   */
+  bool contains(E object);
+
+  /**
+   * Adds element to the queue.
+   *
+   * The element will become the next to be removed by [removeFirst]
+   * when all elements with higher priority have been removed.
+   */
+  void add(E element);
+
+  /**
+   * Adds all [elements] to the queue.
+   */
+  void addAll(Iterable<E> elements);
+
+  /**
+   * Returns the next element that will be returned by [removeFirst].
+   *
+   * The element is not removed from the queue.
+   *
+   * The queue must not be empty when this method is called.
+   */
+  E get first;
+
+  /**
+   * Removes and returns the element with the highest priority.
+   *
+   * Repeatedly calling this method, without adding element in between,
+   * is guaranteed to return elements in non-decreasing order as, specified by
+   * [comparison].
+   *
+   * The queue must not be empty when this method is called.
+   */
+  E removeFirst();
+
+  /**
+   * Removes an element that compares equal to [element] in the queue.
+   *
+   * Returns true if an element is found and removed,
+   * and false if no equal element is found.
+   */
+  bool remove(E element);
+
+  /**
+   * Removes all the elements from this queue and returns them.
+   *
+   * The returned iterable has no specified order.
+   */
+  Iterable<E> removeAll();
+
+  /**
+   * Removes all the elements from this queue.
+   */
+  void clear();
+
+  /**
+   * Returns a list of the elements of this queue in priority order.
+   *
+   * The queue is not modified.
+   *
+   * The order is the order that the elements would be in if they were
+   * removed from this queue using [removeFirst].
+   */
+  List<E> toList();
+
+  /**
+   * Return a comparator based set using the comparator of this queue.
+   *
+   * The queue is not modified.
+   *
+   * The returned [Set] is currently a [SplayTreeSet],
+   * but this may change as other ordered sets are implemented.
+   *
+   * The set contains all the elements of this queue.
+   * If an element occurs more than once in the queue,
+   * the set will contain it only once.
+   */
+  Set<E> toSet();
+}
+
+/**
+ * Heap based priority queue.
+ *
+ * The elements are kept in a heap structure,
+ * where the element with the highest priority is immediately accessible,
+ * and modifying a single element takes
+ * logarithmic time in the number of elements on average.
+ *
+ * * The [add] and [removeFirst] operations take amortized logarithmic time,
+ *   O(log(n)), but may occasionally take linear time when growing the capacity
+ *   of the heap.
+ * * The [addAll] operation works as doing repeated [add] operations.
+ * * The [first] getter takes constant time, O(1).
+ * * The [clear] and [removeAll] methods also take constant time, O(1).
+ * * The [contains] and [remove] operations may need to search the entire
+ *   queue for the elements, taking O(n) time.
+ * * The [toList] operation effectively sorts the elements, taking O(n*log(n))
+ *   time.
+ * * The [toSet] operation effectively adds each element to the new set, taking
+ *   an expected O(n*log(n)) time.
+ */
+class HeapPriorityQueue<E> implements PriorityQueue<E> {
+  /**
+   * Initial capacity of a queue when created, or when added to after a [clear].
+   *
+   * Number can be any positive value. Picking a size that gives a whole
+   * number of "tree levels" in the heap is only done for aesthetic reasons.
+   */
+  static const int _INITIAL_CAPACITY = 7;
+
+  /**
+   * The comparison being used to compare the priority of elements.
+   */
+  final Comparator comparison;
+
+  /**
+   * List implementation of a heap.
+   */
+  List<E> _queue = new List<E>(_INITIAL_CAPACITY);
+
+  /**
+   * Number of elements in queue.
+   *
+   * The heap is implemented in the first [_length] entries of [_queue].
+   */
+  int _length = 0;
+
+  /**
+   * Create a new priority queue.
+   *
+   * The [comparison] is a [Comparator] used to compare the priority of
+   * elements. An element that compares as less than another element has
+   * a higher priority.
+   *
+   * If [comparison] is omitted, it defaults to [Comparable.compare].
+   */
+  HeapPriorityQueue([int comparison(E e1, E e2)])
+      : comparison = (comparison != null) ? comparison : Comparable.compare;
+
+  void add(E element) {
+    _add(element);
+  }
+
+  void addAll(Iterable<E> elements) {
+    for (E element in elements) {
+      _add(element);
+    }
+  }
+
+  void clear() {
+    _queue = const [];
+    _length = 0;
+  }
+
+  bool contains(E object) {
+    return _locate(object) >= 0;
+  }
+
+  E get first {
+    if (_length == 0) throw new StateError("No such element");
+    return _queue[0];
+  }
+
+  bool get isEmpty => _length == 0;
+
+  bool get isNotEmpty => _length != 0;
+
+  int get length => _length;
+
+  bool remove(E element) {
+    int index = _locate(element);
+    if (index < 0) return false;
+    E last = _removeLast();
+    if (index < _length) {
+      int comp = comparison(last, element);
+      if (comp <= 0) {
+        _bubbleUp(last, index);
+      } else {
+        _bubbleDown(last, index);
+      }
+    }
+    return true;
+  }
+
+  Iterable<E> removeAll() {
+    List<E> result = _queue;
+    int length = _length;
+    _queue = const [];
+    _length = 0;
+    return result.take(length);
+  }
+
+  E removeFirst() {
+    if (_length == 0) throw new StateError("No such element");
+    E result = _queue[0];
+    E last = _removeLast();
+    if (_length > 0) {
+      _bubbleDown(last, 0);
+    }
+    return result;
+  }
+
+  List<E> toList() {
+    List<E> list = new List<E>()..length = _length;
+    list.setRange(0, _length, _queue);
+    list.sort(comparison);
+    return list;
+  }
+
+  Set<E> toSet() {
+    Set<E> set = new SplayTreeSet<E>(comparison);
+    for (int i = 0; i < _length; i++) {
+      set.add(_queue[i]);
+    }
+    return set;
+  }
+
+  /**
+   * Returns some representation of the queue.
+   *
+   * The format isn't significant, and may change in the future.
+   */
+  String toString() {
+    return _queue.take(_length).toString();
+  }
+
+  /**
+   * Add element to the queue.
+   *
+   * Grows the capacity if the backing list is full.
+   */
+  void _add(E element) {
+    if (_length == _queue.length) _grow();
+    _bubbleUp(element, _length++);
+  }
+
+  /**
+   * Find the index of an object in the heap.
+   *
+   * Returns -1 if the object is not found.
+   */
+  int _locate(E object) {
+    if (_length == 0) return -1;
+    // Count positions from one instad of zero. This gives the numbers
+    // some nice properties. For example, all right children are odd,
+    // their left sibling is even, and the parent is found by shifting
+    // right by one.
+    // Valid range for position is [1.._length], inclusive.
+    int position = 1;
+    // Pre-order depth first search, omit child nodes if the current
+    // node has lower priority than [object], because all nodes lower
+    // in the heap will also have lower priority.
+    do {
+      int index = position - 1;
+      E element = _queue[index];
+      int comp = comparison(element, object);
+      if (comp == 0) return index;
+      if (comp < 0) {
+        // Element may be in subtree.
+        // Continue with the left child, if it is there.
+        int leftChildPosition = position * 2;
+        if (leftChildPosition <= _length) {
+          position = leftChildPosition;
+          continue;
+        }
+      }
+      // Find the next right sibling or right ancestor sibling.
+      do {
+        while (position.isOdd) {
+          // While position is a right child, go to the parent.
+          position >>= 1;
+        }
+        // Then go to the right sibling of the left-child.
+        position += 1;
+      } while (position > _length);  // Happens if last element is a left child.
+    } while (position != 1);  // At root again. Happens for right-most element.
+    return -1;
+  }
+
+  E _removeLast() {
+    int newLength = _length - 1;
+    E last = _queue[newLength];
+    _queue[newLength] = null;
+    _length = newLength;
+    return last;
+  }
+
+  /**
+   * Place [element] in heap at [index] or above.
+   *
+   * Put element into the empty cell at `index`.
+   * While the `element` has higher priority than the
+   * parent, swap it with the parent.
+   */
+  void _bubbleUp(E element, int index) {
+    while (index > 0) {
+      int parentIndex = (index - 1) ~/ 2;
+      E parent = _queue[parentIndex];
+      if (comparison(element, parent) > 0) break;
+      _queue[index] = parent;
+      index = parentIndex;
+    }
+    _queue[index] = element;
+  }
+
+  /**
+   * Place [element] in heap at [index] or above.
+   *
+   * Put element into the empty cell at `index`.
+   * While the `element` has lower priority than either child,
+   * swap it with the highest priority child.
+   */
+  void _bubbleDown(E element, int index) {
+    int rightChildIndex = index * 2 + 2;
+    while (rightChildIndex < _length) {
+      int leftChildIndex = rightChildIndex - 1;
+      E leftChild = _queue[leftChildIndex];
+      E rightChild = _queue[rightChildIndex];
+      int comp = comparison(leftChild, rightChild);
+      int minChildIndex;
+      E minChild;
+      if (comp < 0) {
+        minChild = leftChild;
+        minChildIndex = leftChildIndex;
+      } else {
+        minChild = rightChild;
+        minChildIndex = rightChildIndex;
+      }
+      comp = comparison(element, minChild);
+      if (comp <= 0) {
+        _queue[index] = element;
+        return;
+      }
+      _queue[index] = minChild;
+      index = minChildIndex;
+      rightChildIndex = index * 2 + 2;
+    }
+    int leftChildIndex = rightChildIndex - 1;
+    if (leftChildIndex < _length) {
+      E child = _queue[leftChildIndex];
+      int comp = comparison(element, child);
+      if (comp > 0) {
+        _queue[index] = child;
+        index = leftChildIndex;
+      }
+    }
+    _queue[index] = element;
+  }
+
+  /**
+   * Grows the capacity of the list holding the heap.
+   *
+   * Called when the list is full.
+   */
+  void _grow() {
+    int newCapacity = _queue.length * 2 + 1;
+    if (newCapacity < _INITIAL_CAPACITY) newCapacity = _INITIAL_CAPACITY;
+    List<E> newQueue = new List<E>(newCapacity);
+    newQueue.setRange(0, _length, _queue);
+    _queue = newQueue;
+  }
+}
diff --git a/pkg/collection/pubspec.yaml b/pkg/collection/pubspec.yaml
index 0fec04b..6f9d290 100644
--- a/pkg/collection/pubspec.yaml
+++ b/pkg/collection/pubspec.yaml
@@ -1,5 +1,5 @@
 name: collection
-version: 0.9.0
+version: 0.9.1
 author: Dart Team <misc@dartlang.org>
 description: Collections and utilities functions and classes related to collections.
 homepage: http://www.dartlang.org
diff --git a/pkg/collection/test/priority_queue_test.dart b/pkg/collection/test/priority_queue_test.dart
new file mode 100644
index 0000000..1040e1a
--- /dev/null
+++ b/pkg/collection/test/priority_queue_test.dart
@@ -0,0 +1,167 @@
+// 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.
+
+/// Tests priority queue implementations utilities.
+
+import "dart:collection";
+import "package:collection/priority_queue.dart";
+import "package:unittest/unittest.dart";
+
+void main() {
+  testInt(() => new HeapPriorityQueue<int>());
+  testCustom((comparator) => new HeapPriorityQueue<C>(comparator));
+}
+
+void testInt(PriorityQueue<int> create()) {
+  for (int count in [1, 5, 127, 128]) {
+    testQueue("int:$count",
+              create,
+              new List<int>.generate(count, (x) => x),
+              count);
+  }
+}
+
+void testCustom(PriorityQueue<C> create(comparator)) {
+  for (int count in [1, 5, 127, 128]) {
+    testQueue("Custom:$count/null",
+              () => create(null),
+              new List<C>.generate(count, (x) => new C(x)),
+              new C(count));
+    testQueue("Custom:$count/compare",
+              () => create(compare),
+              new List<C>.generate(count, (x) => new C(x)),
+              new C(count));
+    testQueue("Custom:$count/compareNeg",
+              () => create(compareNeg),
+              new List<C>.generate(count, (x) => new C(count - x)),
+              new C(0));
+  }
+}
+
+/**
+ * Test that a queue behaves correctly.
+ *
+ * The elements must be in priority order, from highest to lowest.
+ */
+void testQueue(String name, PriorityQueue create(), List elements, notElement) {
+  test(name, () => testQueueBody(create, elements, notElement));
+}
+
+void testQueueBody(PriorityQueue create(), List elements, notElement) {
+  PriorityQueue q = create();
+  expect(q.isEmpty, isTrue);
+  expect(q, hasLength(0));
+  expect(() { q.first; }, throwsStateError);
+  expect(() { q.removeFirst(); }, throwsStateError);
+
+  // Tests removeFirst, first, contains, toList and toSet.
+  void testElements() {
+    expect(q.isNotEmpty, isTrue);
+    expect(q, hasLength(elements.length));
+
+    expect(q.toList(), equals(elements));
+    expect(q.toSet().toList(), equals(elements));
+
+    for (int i = 0; i < elements.length; i++) {
+      expect(q.contains(elements[i]), isTrue);
+    }
+    expect(q.contains(notElement), isFalse);
+
+    List all = [];
+    while (!q.isEmpty) {
+      var expected = q.first;
+      var actual = q.removeFirst();
+      expect(actual, same(expected));
+      all.add(actual);
+    }
+
+    expect(all.length, elements.length);
+    for (int i = 0; i < all.length; i++) {
+      expect(all[i], same(elements[i]));
+    }
+
+    expect(q.isEmpty, isTrue);
+  }
+
+  q.addAll(elements);
+  testElements();
+
+  q.addAll(elements.reversed);
+  testElements();
+
+  // Add elements in a non-linear order (gray order).
+  for (int i = 0, j = 0; i < elements.length; i++) {
+    int gray;
+    do {
+      gray = j ^ (j >> 1);
+      j++;
+    } while (gray >= elements.length);
+    q.add(elements[gray]);
+  }
+  testElements();
+
+  // Add elements by picking the middle element first, and then recursing
+  // on each side.
+  void addRec(int min, int max) {
+    int mid = min + ((max - min) >> 1);
+    q.add(elements[mid]);
+    if (mid + 1 < max) addRec(mid + 1, max);
+    if (mid > min) addRec(min, mid);
+  }
+  addRec(0, elements.length);
+  testElements();
+
+  // Test removeAll.
+  q.addAll(elements);
+  expect(q, hasLength(elements.length));
+  Iterable all = q.removeAll();
+  expect(q.isEmpty, isTrue);
+  expect(all, hasLength(elements.length));
+  for (int i = 0; i < elements.length; i++) {
+    expect(all, contains(elements[i]));
+  }
+
+  // Test the same element more than once in queue.
+  q.addAll(elements);
+  q.addAll(elements.reversed);
+  expect(q, hasLength(elements.length * 2));
+  for (int i = 0; i < elements.length; i++) {
+    var element = elements[i];
+    expect(q.contains(element), isTrue);
+    expect(q.removeFirst(), element);
+    expect(q.removeFirst(), element);
+  }
+
+  // Test queue with all same element.
+  var a = elements[0];
+  for (int i = 0; i < elements.length; i++) {
+    q.add(a);
+  }
+  expect(q, hasLength(elements.length));
+  expect(q.contains(a), isTrue);
+  expect(q.contains(notElement), isFalse);
+  q.removeAll().forEach((x) => expect(x, same(a)));
+
+  // Test remove.
+  q.addAll(elements);
+  for (var element in elements.reversed) {
+    expect(q.remove(element), isTrue);
+  }
+  expect(q.isEmpty, isTrue);
+}
+
+
+// Custom class.
+// Class is comparable, comparators match normal and inverse order.
+int compare(C c1, C c2) => c1.value - c2.value;
+int compareNeg(C c1, C c2) => c2.value - c1.value;
+
+class C implements Comparable {
+  final int value;
+  const C(this.value);
+  int get hashCode => value;
+  bool operator==(Object other) => other is C && value == other.value;
+  int compareTo(C other) => value - other.value;
+  String toString() => "C($value)";
+}
diff --git a/pkg/compiler_unsupported/.gitignore b/pkg/compiler_unsupported/.gitignore
new file mode 100644
index 0000000..c3af857
--- /dev/null
+++ b/pkg/compiler_unsupported/.gitignore
@@ -0,0 +1 @@
+lib/
diff --git a/pkg/compiler_unsupported/LICENSE b/pkg/compiler_unsupported/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/compiler_unsupported/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/compiler_unsupported/README.md b/pkg/compiler_unsupported/README.md
new file mode 100644
index 0000000..4b8e6cc
--- /dev/null
+++ b/pkg/compiler_unsupported/README.md
@@ -0,0 +1,8 @@
+# compiler_unsupported
+
+An unsupported copy of the dart2js compiler.
+
+### About
+
+This is a copy of the dart2js source available as a package. The API of this
+package can and will change in unpredictable and incompatible ways.
diff --git a/pkg/compiler_unsupported/pubspec.yaml b/pkg/compiler_unsupported/pubspec.yaml
new file mode 100644
index 0000000..e7d65b1
--- /dev/null
+++ b/pkg/compiler_unsupported/pubspec.yaml
@@ -0,0 +1,9 @@
+name: compiler_unsupported
+version: 0.7.0
+author: Dart2js Team <compiler-dev@dartlang.org>
+homepage: http://www.dartlang.org
+description: >
+  This is an unsupported copy of the dart2js source. The API of this package
+  can and will change in unpredictable and incompatible ways.
+environment:
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/compiler_unsupported/tool/create_library.py b/pkg/compiler_unsupported/tool/create_library.py
new file mode 100755
index 0000000..5ff330b
--- /dev/null
+++ b/pkg/compiler_unsupported/tool/create_library.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Create the compiler_unsupported package. This will copy the
+# sdk/lib/_internal/compiler directory and the libraries.dart file into lib/.
+#
+# Usage: create_library.py
+
+import os
+import re
+import shutil
+import sys
+
+from os.path import dirname, join
+
+
+def ReplaceInFiles(paths, subs):
+  '''Reads a series of files, applies a series of substitutions to each, and
+     saves them back out. subs should be a list of (pattern, replace) tuples.'''
+  for path in paths:
+    contents = open(path).read()
+    for pattern, replace in subs:
+      contents = re.sub(pattern, replace, contents)
+    dest = open(path, 'w')
+    dest.write(contents)
+    dest.close()
+
+
+def RemoveFile(f):
+  if os.path.exists(f):
+    os.remove(f)
+
+
+def Main(argv):
+  # pkg/compiler_unsupported
+  HOME = dirname(dirname(os.path.realpath(__file__)))
+
+  # pkg/compiler_unsupported/lib
+  TARGET = join(HOME, 'lib')
+
+  # sdk/lib/_internal
+  SOURCE = join(dirname(dirname(HOME)), 'sdk', 'lib', '_internal')
+
+  # clean compiler_unsupported/lib
+  if not os.path.exists(TARGET):
+    os.mkdir(TARGET)
+  shutil.rmtree(join(TARGET, 'implementation'), True)
+  RemoveFile(join(TARGET, 'compiler.dart'))
+  RemoveFile(join(TARGET, 'libraries.dart'))
+
+  # copy dart2js code
+  shutil.copy(join(SOURCE, 'compiler', 'compiler.dart'), TARGET)
+  shutil.copy(join(SOURCE, 'libraries.dart'), TARGET)
+  shutil.copytree(
+      join(SOURCE, 'compiler', 'implementation'),
+      join(TARGET, 'implementation'))
+
+  # patch up the libraries.dart references
+  replace = [(r'\.\./\.\./libraries\.dart', r'\.\./libraries\.dart')]
+
+  for root, dirs, files in os.walk(join(TARGET, 'implementation')):
+    for name in files:
+      if name.endswith('.dart'):
+        ReplaceInFiles([join(root, name)], replace)
+
+
+if __name__ == '__main__':
+  sys.exit(Main(sys.argv))
diff --git a/pkg/crypto/LICENSE b/pkg/crypto/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/crypto/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/csslib/lib/parser.dart b/pkg/csslib/lib/parser.dart
index 840b9f23..ba8cd13 100644
--- a/pkg/csslib/lib/parser.dart
+++ b/pkg/csslib/lib/parser.dart
@@ -1494,6 +1494,9 @@
           value = double.parse(termToken.text);
           break;
         case TokenKind.SINGLE_QUOTE:
+          value = processQuotedString(false);
+          value = "'${_escapeString(value, single: true)}'";
+          return new LiteralTerm(value, value, _makeSpan(start));
         case TokenKind.DOUBLE_QUOTE:
           value = processQuotedString(false);
           value = '"${_escapeString(value)}"';
@@ -2129,6 +2132,9 @@
       value = double.parse("${unary}${t.text}");
       break;
     case TokenKind.SINGLE_QUOTE:
+      value = processQuotedString(false);
+      value = "'${_escapeString(value, single: true)}'";
+      return new LiteralTerm(value, value, _makeSpan(start));
     case TokenKind.DOUBLE_QUOTE:
       value = processQuotedString(false);
       value = '"${_escapeString(value)}"';
diff --git a/pkg/csslib/pubspec.yaml b/pkg/csslib/pubspec.yaml
index 8ec9421..2762231 100644
--- a/pkg/csslib/pubspec.yaml
+++ b/pkg/csslib/pubspec.yaml
@@ -1,5 +1,5 @@
 name: csslib
-version: 0.9.1
+version: 0.9.2
 author: "Polymer.dart Team <web-ui-dev@dartlang.org>"
 description: A library for parsing CSS.
 homepage: https://www.dartlang.org
diff --git a/pkg/csslib/test/compiler_test.dart b/pkg/csslib/test/compiler_test.dart
index f545a6d..8d63f8b 100644
--- a/pkg/csslib/test/compiler_test.dart
+++ b/pkg/csslib/test/compiler_test.dart
@@ -591,7 +591,7 @@
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), r'''
 html:lang(fr-ca) {
-  quotes: "\" " " \"";
+  quotes: '" ' ' "';
 }
 zoom {
 }
diff --git a/pkg/csslib/test/declaration_test.dart b/pkg/csslib/test/declaration_test.dart
index fa14ed3..ce46f5d 100644
--- a/pkg/csslib/test/declaration_test.dart
+++ b/pkg/csslib/test/declaration_test.dart
@@ -258,7 +258,7 @@
 
   final String generated = r'''
 .toggle:after {
-  content: "✔";
+  content: '✔';
   line-height: 43px;
   font-size: 20px;
   color: #d9d9d9;
diff --git a/pkg/docgen/LICENSE b/pkg/docgen/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/docgen/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/docgen/bin/docgen.dart b/pkg/docgen/bin/docgen.dart
index 7a19f65..2a116de 100644
--- a/pkg/docgen/bin/docgen.dart
+++ b/pkg/docgen/bin/docgen.dart
@@ -17,14 +17,11 @@
  * classes, and members.
  */
 void main(List<String> arguments) {
-  logger.onRecord.listen((record) => print(record.message));
   var results = _initArgParser().parse(arguments);
 
   var includeSdk = results['parse-sdk'] || results['include-sdk'];
   var scriptDir = path.dirname(Platform.script.toFilePath());
-  var introFile =
-      path.join(path.dirname(scriptDir), 'doc', 'sdk-introduction.md');
-  var introduction = includeSdk ? introFile : results['introduction'];
+  var introduction = includeSdk ? '' : results['introduction'];
   docgen(results.rest.map(path.normalize).toList(),
       packageRoot: results['package-root'],
       outputToYaml: !results['json'],
@@ -32,7 +29,7 @@
       includeSdk: includeSdk,
       parseSdk: results['parse-sdk'],
       append: results['append'] && new Directory(results['out']).existsSync(),
-      introduction: introduction,
+      introFileName: introduction,
       out: results['out'],
       excludeLibraries: excludedLibraries,
       includeDependentPackages: results['include-dependent-packages']);
@@ -48,8 +45,8 @@
       negatable: false,
       callback: (help) {
         if (help) {
-          logger.info(parser.getUsage());
-          logger.info(USAGE);
+          print(parser.getUsage());
+          print('Usage: dart docgen.dart [OPTIONS] fooDir/barFile');
           exit(0);
         }
       });
@@ -77,7 +74,7 @@
       defaultsTo: false, negatable: false);
   parser.addOption('introduction',
       help: 'Adds the provided markdown text file as the introduction'
-        ' for the outputted documentation.', defaultsTo: '');
+        ' for the generated documentation.', defaultsTo: '');
   parser.addOption('out',
       help: 'The name of the output directory.',
       defaultsTo: 'docs');
diff --git a/pkg/docgen/doc/README.txt b/pkg/docgen/doc/README.txt
new file mode 100644
index 0000000..e2af2a6
--- /dev/null
+++ b/pkg/docgen/doc/README.txt
@@ -0,0 +1,4 @@
+The sdk-introduction.md file formerly in this directory has been moved 
+into the code in lib/docgen.dart so that it isn't dependent on this 
+directory struture. Any edits should be done to the DEFAULT_SDK_INTRODUCTION
+constant in that file.
diff --git a/pkg/docgen/doc/sdk-introduction.md b/pkg/docgen/doc/sdk-introduction.md
deleted file mode 100644
index 4cd292f..0000000
--- a/pkg/docgen/doc/sdk-introduction.md
+++ /dev/null
@@ -1,44 +0,0 @@
-Welcome to the Dart API reference documentation,
-covering the official Dart API libraries.
-Some of the most fundamental Dart libraries include:
-
-* [dart:core](#dart:core):
-  Core functionality such as strings, numbers, collections, errors,
-  dates, and URIs.
-* [dart:html](#dart:html):
-  DOM manipulation for web apps.
-* [dart:io](#dart:io):
-  I/O for command-line apps.
-
-Except for dart:core, you must import a library before you can use it.
-Here's an example of importing dart:html, dart:math, and a
-third popular library called
-[polymer.dart](http://www.dartlang.org/polymer-dart/):
-
-    import 'dart:html';
-    import 'dart:math';
-    import 'package:polymer/polymer.dart';
-
-Polymer.dart is an example of a library that isn't
-included in the Dart download,
-but is easy to get and update using the _pub package manager_.
-For information on finding, using, and publishing libraries (and more)
-with pub, see
-[pub.dartlang.org](http://pub.dartlang.org).
-
-The main site for learning and using Dart is
-[www.dartlang.org](http://www.dartlang.org).
-Check out these pages:
-
-  * [Dart homepage](http://www.dartlang.org)
-  * [Tutorials](http://www.dartlang.org/docs/tutorials/)
-  * [Programmer's Guide](http://www.dartlang.org/docs/)
-  * [Samples](http://www.dartlang.org/samples/)
-  * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)
-  
-This API reference is automatically generated from the source code in the
-[Dart project](https://code.google.com/p/dart/).
-If you'd like to contribute to this documentation, see
-[Contributing](https://code.google.com/p/dart/wiki/Contributing)
-and
-[Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocumentation).
diff --git a/pkg/docgen/lib/dart2yaml.dart b/pkg/docgen/lib/dart2yaml.dart
index 343b61f..b86cbb4 100644
--- a/pkg/docgen/lib/dart2yaml.dart
+++ b/pkg/docgen/lib/dart2yaml.dart
@@ -7,8 +7,6 @@
  */
 library dart2yaml;
 
-import 'dart:collection';
-
 /**
  * Gets a String representing the input Map in YAML format.
  */
@@ -28,7 +26,7 @@
  */
 void _addLevel(StringBuffer yaml, Map documentData, int level,
                {bool isList: false}) {
-  // The order of the keys could be nondeterministic, but it is insufficient 
+  // The order of the keys could be nondeterministic, but it is insufficient
   // to just sort the keys no matter what, as their order could be significant
   // (i.e. parameters to a method). The order of the keys should be enforced
   // by the caller of this function.
@@ -36,7 +34,7 @@
   keys.forEach((key) {
     _calcSpaces(level, yaml);
     // Only the first entry of the map should be preceeded with a '-' since
-    // the map is a member of an outer list and the map as a whole must be 
+    // the map is a member of an outer list and the map as a whole must be
     // marked as a single member of that list. See example 2.4 at
     // http://www.yaml.org/spec/1.2/spec.html#id2759963
     if (isList && key == keys.first) {
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index d75b60f..fb4238f 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -34,51 +34,194 @@
 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart';
 import '../../../sdk/lib/_internal/libraries.dart';
 
-var logger = new Logger('Docgen');
+const _DEFAULT_OUTPUT_DIRECTORY = 'docs';
 
-const DEFAULT_OUTPUT_DIRECTORY = 'docs';
-
-var _outputDirectory;
-
-const String USAGE = 'Usage: dart docgen.dart [OPTIONS] fooDir/barFile';
-
-
-List<String> skippedAnnotations = const [
+/// Annotations that we do not display in the viewer.
+const List<String> _SKIPPED_ANNOTATIONS = const [
     'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates',
     '_js_helper.Returns'];
 
-/// Set of libraries declared in the SDK, so libraries that can be accessed
-/// when running dart by default.
-Iterable<LibraryMirror> _sdkLibraries;
-
-/// The dart:core library, which contains all types that are always available
-/// without import.
-LibraryMirror _coreLibrary;
-
 /// Support for [:foo:]-style code comments to the markdown parser.
-List<markdown.InlineSyntax> markdownSyntaxes =
+List<markdown.InlineSyntax> _MARKDOWN_SYNTAXES =
   [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
 
+/// If we can't find the SDK introduction text, which will happen if running
+/// from a snapshot and using --parse-sdk or --include-sdk, then use this
+/// hard-coded version. This should be updated to be consistent with the text
+/// in docgen/doc/sdk-introduction.md
+const _DEFAULT_SDK_INTRODUCTION = """
+Welcome to the Dart API reference documentation,
+covering the official Dart API libraries.
+Some of the most fundamental Dart libraries include:
+
+* [dart:core](#dart:core):
+  Core functionality such as strings, numbers, collections, errors,
+  dates, and URIs.
+* [dart:html](#dart:html):
+  DOM manipulation for web apps.
+* [dart:io](#dart:io):
+  I/O for command-line apps.
+
+Except for dart:core, you must import a library before you can use it.
+Here's an example of importing dart:html, dart:math, and a
+third popular library called
+[polymer.dart](http://www.dartlang.org/polymer-dart/):
+
+    import 'dart:html';
+    import 'dart:math';
+    import 'package:polymer/polymer.dart';
+
+Polymer.dart is an example of a library that isn't
+included in the Dart download,
+but is easy to get and update using the _pub package manager_.
+For information on finding, using, and publishing libraries (and more)
+with pub, see
+[pub.dartlang.org](http://pub.dartlang.org).
+
+The main site for learning and using Dart is
+[www.dartlang.org](http://www.dartlang.org).
+Check out these pages:
+
+  * [Dart homepage](http://www.dartlang.org)
+  * [Tutorials](http://www.dartlang.org/docs/tutorials/)
+  * [Programmer's Guide](http://www.dartlang.org/docs/)
+  * [Samples](http://www.dartlang.org/samples/)
+  * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn
+ing/contents/ch03.html)
+
+This API reference is automatically generated from the source code in the
+[Dart project](https://code.google.com/p/dart/).
+If you'd like to contribute to this documentation, see
+[Contributing](https://code.google.com/p/dart/wiki/Contributing)
+and
+[Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume
+ntation).
+""";
+
+// TODO(efortuna): The use of this field is odd (this is based on how it was
+// originally used. Try to cleanup.
 /// Index of all indexable items. This also ensures that no class is
 /// created more than once.
 Map<String, Indexable> entityMap = new Map<String, Indexable>();
 
-/// This is set from the command line arguments flag --include-private
-bool _includePrivate = false;
-
-/// This is set from the command line flag --include-dependent-packages
-bool _includeDependentPackages = false;
-
-/// Library names to explicitly exclude.
+/// Index of all the dart2js mirrors examined to corresponding MirrorBased
+/// docgen objects.
 ///
-///   Set from the command line option
-/// --exclude-lib.
-List<String> _excluded;
+/// Used for lookup because of the dart2js mirrors exports
+/// issue. The second level map is indexed by owner docName for faster lookup.
+/// Why two levels of lookup? Speed, man. Speed.
+Map<String, Map<String, Set<MirrorBased>>> mirrorToDocgen =
+    new Map<String, Map<String, Set<MirrorBased>>>();
 
-// TODO(janicejl): Make MDN content generic or pluggable. Maybe move
-// MDN-specific code to its own library that is imported into the default impl?
-/// Map of all the comments for dom elements from MDN.
-Map _mdn;
+/// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object.
+///
+/// We have this global lookup function to avoid re-implementing looking up the
+/// scoping rules for comment resolution here (it is currently done in mirrors).
+/// If no corresponding MirrorBased object is found, we return a [DummyMirror]
+/// that simply returns the original mirror's qualifiedName while behaving like
+/// a MirrorBased object.
+MirrorBased getDocgenObject(DeclarationMirror mirror, [Indexable owner]) {
+  Map<String, Set<MirrorBased>> docgenObj =
+      mirrorToDocgen[mirror.qualifiedName];
+  if (docgenObj == null) {
+    return new DummyMirror(mirror, owner);
+  }
+
+  Set<MirrorBased> results = new Set<MirrorBased>();
+  var setToExamine = new Set();
+  if (owner != null) {
+    var firstSet = docgenObj[owner.docName];
+    if (firstSet != null) setToExamine.addAll(firstSet);
+    if (Indexable._coreLibrary != null &&
+        docgenObj[Indexable._coreLibrary.docName] != null) {
+      setToExamine.addAll(docgenObj[Indexable._coreLibrary.docName]);
+    }
+  } else {
+    for (var value in docgenObj.values) {
+      setToExamine.addAll(value);
+    }
+  }
+
+  for(MirrorBased mirrorBased in setToExamine) {
+    // This check makes me sad, but Dart doesn't seem to be dynamic enough to
+    // write this another way. Dart2js and the editor didn't like the Type
+    // lookup in a map.
+    if (mirrorBased.mirror.qualifiedName == mirror.qualifiedName &&
+        ((mirror is ClassMirror && mirrorBased is Class)
+        || (mirror is LibraryMirror && mirrorBased is Library)
+        || (mirror is MethodMirror && mirrorBased is Method)
+        || (mirror is VariableMirror && mirrorBased is Variable)
+        || (mirror is TypedefMirror && mirrorBased is Typedef)
+        || (mirror is TypeMirror && mirrorBased is Type)
+        || (mirror is InstanceMirror && mirrorBased is Annotation))) {
+      results.add(mirrorBased);
+    }
+  }
+
+  if (results.length > 0) {
+    return results.first; // This might occur if we didn't specify an "owner."
+  }
+  return new DummyMirror(mirror, owner);
+}
+
+/// For types that we do not explicitly create or have not yet created in our
+/// entity map (like core types).
+class DummyMirror implements MirrorBased {
+  DeclarationMirror mirror;
+  /// The library that contains this element, if any. Used as a hint to help
+  /// determine which object we're referring to when looking up this mirror in
+  /// our map.
+  Indexable owner;
+  DummyMirror(this.mirror, [this.owner]);
+
+  String get docName {
+    if (mirror == null) return '';
+    if (mirror is LibraryMirror) {
+      return mirror.qualifiedName.replaceAll('.','-');
+    }
+    var mirrorOwner = mirror.owner;
+    if (mirrorOwner == null) return mirror.qualifiedName;
+    var simpleName = mirror.simpleName;
+    if (mirror is MethodMirror && (mirror as MethodMirror).isConstructor) {
+      // We name constructors specially -- including the class name again and a
+      // "-" to separate the constructor from its name (if any).
+      simpleName = '${mirrorOwner.simpleName}-$simpleName';
+    }
+    return getDocgenObject(mirrorOwner, owner).docName + '.' + simpleName;
+  }
+  List<Annotation> _createAnnotations(DeclarationMirror mirror,
+      Library owningLibrary) => null;
+
+  bool get isPrivate => mirror == null? false : mirror.isPrivate;
+}
+
+abstract class MirrorBased {
+  DeclarationMirror get mirror;
+  MirrorBased owner;
+
+  /// Returns this object's qualified name, but following the conventions
+  /// we're using in Dartdoc, which is that library names with dots in them
+  /// have them replaced with hyphens.
+  String get docName => owner.docName + '.' + mirror.simpleName;
+
+  /// Returns a list of meta annotations assocated with a mirror.
+  List<Annotation> _createAnnotations(DeclarationMirror mirror,
+      Library owningLibrary) {
+    var annotationMirrors = mirror.metadata.where((e) =>
+        e is dart2js.Dart2JsConstructedConstantMirror);
+    var annotations = [];
+    annotationMirrors.forEach((annotation) {
+      var docgenAnnotation = new Annotation(annotation, owningLibrary);
+      if (!_SKIPPED_ANNOTATIONS.contains(
+          docgenAnnotation.mirror.qualifiedName)) {
+        annotations.add(docgenAnnotation);
+      }
+    });
+    return annotations;
+  }
+
+  bool get isPrivate => false;
+}
 
 /// Docgen constructor initializes the link resolver for markdown parsing.
 /// Also initializes the command line arguments.
@@ -92,193 +235,15 @@
 /// Returned Future completes with true if document generation is successful.
 Future<bool> docgen(List<String> files, {String packageRoot,
     bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
-    bool parseSdk: false, bool append: false, String introduction: '',
-    out: DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries,
-    bool includeDependentPackages}) {
-  _excluded = excludeLibraries;
-  _includePrivate = includePrivate;
-  _outputDirectory = out;
-  _includeDependentPackages = includeDependentPackages;
-  if (!append) {
-    var dir = new Directory(_outputDirectory);
-    if (dir.existsSync()) dir.deleteSync(recursive: true);
-  }
-
-  if (packageRoot == null && !parseSdk) {
-    var type = FileSystemEntity.typeSync(files.first);
-    if (type == FileSystemEntityType.DIRECTORY) {
-      packageRoot = _findPackageRoot(files.first);
-    } else if (type == FileSystemEntityType.FILE) {
-      logger.warning('WARNING: No package root defined. If Docgen fails, try '
-          'again by setting the --package-root option.');
-    }
-  }
-  logger.info('Package Root: ${packageRoot}');
-  if (_includeDependentPackages) {
-    files.addAll(allDependentPackageDirs(files.first));
-  }
-  var requestedLibraries = _listLibraries(files);
-  var allLibraries = []..addAll(requestedLibraries);
-  if (includeSdk) {
-    allLibraries.addAll(_listSdk());
-  }
-
-  return getMirrorSystem(allLibraries, packageRoot: packageRoot,
-      parseSdk: parseSdk)
-    .then((MirrorSystem mirrorSystem) {
-      if (mirrorSystem.libraries.isEmpty) {
-        throw new StateError('No library mirrors were created.');
-      }
-      var availableLibraries = mirrorSystem.libraries.values.where(
-          (each) => each.uri.scheme == 'file');
-      _sdkLibraries = mirrorSystem.libraries.values.where(
-          (each) => each.uri.scheme == 'dart');
-      _coreLibrary = _sdkLibraries.singleWhere((lib) =>
-          lib.uri.toString().startsWith('dart:core'));
-      var availableLibrariesByPath = new Map.fromIterables(
-          availableLibraries.map((each) => each.uri),
-          availableLibraries);
-      var librariesToDocument = requestedLibraries.map(
-          (each) => availableLibrariesByPath.putIfAbsent(each,
-              () => throw "Missing library $each")).toList();
-      librariesToDocument.addAll((includeSdk || parseSdk) ? _sdkLibraries : []);
-      librariesToDocument.removeWhere((x) => _excluded.contains(x.simpleName));
-      _documentLibraries(librariesToDocument, includeSdk: includeSdk,
-          outputToYaml: outputToYaml, append: append, parseSdk: parseSdk,
-          introduction: introduction);
-      return true;
-    });
-}
-
-/// All of the directories for our dependent packages
-List<String> allDependentPackageDirs(String packageDirectory) {
-  var dependentsJson = Process.runSync('pub', ['list-package-dirs'],
-      workingDirectory: packageDirectory, runInShell: true);
-  if (dependentsJson.exitCode != 0) {
-    print(dependentsJson.stderr);
-  }
-  var dependents = JSON.decode(dependentsJson.stdout)['packages'];
-  return dependents.values.toList();
-}
-
-/// For a library's [mirror], determine the name of the package (if any) we
-/// believe it came from (because of its file URI).
-///
-/// If [library] is specified, we set the packageName field. If no package could
-/// be determined, we return an empty string.
-String _findPackage(LibraryMirror mirror, [Library library]) {
-  if (mirror == null) return '';
-  if (library == null) {
-    library = entityMap[docName(mirror)];
-  }
-  if (library != null) {
-    if (library.hasBeenCheckedForPackage) return library.packageName;
-    library.hasBeenCheckedForPackage = true;
-  }
-  if (mirror.uri.scheme != 'file') return '';
-  var filePath = mirror.uri.toFilePath();
-  // We assume that we are documenting only libraries under package/lib
-  var rootdir = path.dirname((path.dirname(filePath)));
-  var pubspec = path.join(rootdir, 'pubspec.yaml');
-  var packageName = _packageName(pubspec);
-  if (library != null) {
-    library.packageName = packageName;
-    // Associate the package readme with all the libraries. This is a bit
-    // wasteful, but easier than trying to figure out which partial match
-    // is best.
-    library.packageIntro = _packageIntro(rootdir);
-  }
-  return packageName;
-}
-
-String _packageIntro(packageDir) {
-  var dir = new Directory(packageDir);
-  var files = dir.listSync();
-  var readmes = files.where((FileSystemEntity each) => (each is File &&
-      each.path.substring(packageDir.length + 1, each.path.length)
-          .startsWith('README'))).toList();
-  if (readmes.isEmpty) return '';
-  // If there are multiples, pick the shortest name.
-  readmes.sort((a, b) => a.path.length.compareTo(b.path.length));
-  var readme = readmes.first;
-  var linkResolver = (name) => fixReference(name, null, null, null);
-  var contents = markdown.markdownToHtml(readme
-    .readAsStringSync(), linkResolver: linkResolver,
-    inlineSyntaxes: markdownSyntaxes);
-  return contents;
-}
-
-List<Uri> _listLibraries(List<String> args) {
-  var libraries = new List<Uri>();
-  for (var arg in args) {
-    var type = FileSystemEntity.typeSync(arg);
-
-    if (type == FileSystemEntityType.FILE) {
-      if (arg.endsWith('.dart')) {
-        libraries.add(new Uri.file(path.absolute(arg)));
-        logger.info('Added to libraries: ${libraries.last}');
-      }
-    } else {
-      libraries.addAll(_listDartFromDir(arg));
-    }
-  }
-  return libraries;
-}
-
-List<Uri> _listDartFromDir(String args) {
-  var libraries = [];
-  // To avoid anaylzing package files twice, only files with paths not
-  // containing '/packages' will be added. The only exception is if the file to
-  // analyze already has a '/package' in its path.
-  var files = listDir(args, recursive: true).where((f) => f.endsWith('.dart') &&
-      (!f.contains('${path.separator}packages') ||
-          args.contains('${path.separator}packages'))).toList();
-
-  files.forEach((String f) {
-    // Only include libraries at the top level of "lib"
-    if (path.basename(path.dirname(f)) == 'lib') {
-      // Only add the file if it does not contain 'part of'
-      // TODO(janicejl): Remove when Issue(12406) is resolved.
-      var contents = new File(f).readAsStringSync();
-      if (!(contents.contains(new RegExp('\npart of ')) ||
-          contents.startsWith(new RegExp('part of ')))) {
-        libraries.add(new Uri.file(path.normalize(path.absolute(f))));
-        logger.info('Added to libraries: $f');
-      }
-    }
-  });
-  return libraries;
-}
-
-String _findPackageRoot(String directory) {
-  var files = listDir(directory, recursive: true);
-  // Return '' means that there was no pubspec.yaml and therefor no packageRoot.
-  String packageRoot = files.firstWhere((f) =>
-      f.endsWith('${path.separator}pubspec.yaml'), orElse: () => '');
-  if (packageRoot != '') {
-    packageRoot = path.join(path.dirname(packageRoot), 'packages');
-  }
-  return packageRoot;
-}
-
-/// Read a pubspec and return the library name.
-String _packageName(String pubspecName) {
-  File pubspec = new File(pubspecName);
-  if (!pubspec.existsSync()) return '';
-  var contents = pubspec.readAsStringSync();
-  var spec = loadYaml(contents);
-  return spec["name"];
-}
-
-List<Uri> _listSdk() {
-  var sdk = new List<Uri>();
-  LIBRARIES.forEach((String name, LibraryInfo info) {
-    if (info.documented) {
-      sdk.add(Uri.parse('dart:$name'));
-      logger.info('Add to SDK: ${sdk.last}');
-    }
-  });
-  return sdk;
+    bool parseSdk: false, bool append: false, String introFileName: '',
+    out: _DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries : const [],
+    bool includeDependentPackages: false}) {
+  return _Generator.generateDocumentation(files, packageRoot: packageRoot,
+      outputToYaml: outputToYaml, includePrivate: includePrivate,
+      includeSdk: includeSdk, parseSdk: parseSdk, append: append,
+      introFileName: introFileName, out: out,
+      excludeLibraries: excludeLibraries,
+      includeDependentPackages: includeDependentPackages);
 }
 
 /// Analyzes set of libraries by getting a mirror system and triggers the
@@ -288,437 +253,480 @@
   if (libraries.isEmpty) throw new StateError('No Libraries.');
   // Finds the root of SDK library based off the location of docgen.
 
-  var root = findRootDirectory();
+  var root = _Generator._rootDirectory;
   var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
-  logger.info('SDK Root: ${sdkRoot}');
-  return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot);
+  _Generator.logger.info('SDK Root: ${sdkRoot}');
+  return _Generator._analyzeLibraries(libraries, sdkRoot,
+      packageRoot: packageRoot);
 }
 
-String findRootDirectory() {
-  var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
-  var root = scriptDir;
-  while(path.basename(root) != 'dart') {
-    root = path.dirname(root);
-  }
-  return root;
-}
+class _Generator {
+  static var _outputDirectory;
 
-/// Analyzes set of libraries and provides a mirror system which can be used
-/// for static inspection of the source code.
-Future<MirrorSystem> _analyzeLibraries(List<Uri> libraries,
-      String libraryRoot, {String packageRoot}) {
-  SourceFileProvider provider = new CompilerSourceFileProvider();
-  api.DiagnosticHandler diagnosticHandler =
-      (new FormattingDiagnosticHandler(provider)
-        ..showHints = false
-        ..showWarnings = false)
-          .diagnosticHandler;
-  Uri libraryUri = new Uri.file(appendSlash(libraryRoot));
-  Uri packageUri = null;
-  if (packageRoot != null) {
-    packageUri = new Uri.file(appendSlash(packageRoot));
-  }
-  return dart2js.analyze(libraries, libraryUri, packageUri,
-      provider.readStringFromUri, diagnosticHandler,
-      ['--preserve-comments', '--categories=Client,Server'])
-      ..catchError((error) {
-        logger.severe('Error: Failed to create mirror system. ');
-        // TODO(janicejl): Use the stack trace package when bug is resolved.
-        // Currently, a string is thrown when it fails to create a mirror
-        // system, and it is not possible to use the stack trace. BUG(#11622)
-        // To avoid printing the stack trace.
-        exit(1);
+  /// This is set from the command line arguments flag --include-private
+  static bool _includePrivate = false;
+
+  /// Library names to explicitly exclude.
+  ///
+  ///   Set from the command line option
+  /// --exclude-lib.
+  static List<String> _excluded;
+
+  static Logger logger = new Logger('Docgen');
+
+  /// Docgen constructor initializes the link resolver for markdown parsing.
+  /// Also initializes the command line arguments.
+  ///
+  /// [packageRoot] is the packages directory of the directory being analyzed.
+  /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
+  /// also be documented.
+  /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
+  /// This option is useful when only the SDK libraries are needed.
+  ///
+  /// Returned Future completes with true if document generation is successful.
+  static Future<bool> generateDocumentation(List<String> files,
+      {String packageRoot, bool outputToYaml: true, bool includePrivate: false,
+       bool includeSdk: false, bool parseSdk: false, bool append: false,
+       String introFileName: '', out: _DEFAULT_OUTPUT_DIRECTORY,
+       List<String> excludeLibraries : const [],
+       bool includeDependentPackages: false}) {
+    _excluded = excludeLibraries;
+    _includePrivate = includePrivate;
+    logger.onRecord.listen((record) => print(record.message));
+
+    _ensureOutputDirectory(out, append);
+    var updatedPackageRoot = _obtainPackageRoot(packageRoot, parseSdk, files);
+
+    var requestedLibraries = _findLibrariesToDocument(files,
+        includeDependentPackages);
+
+    var allLibraries = []..addAll(requestedLibraries);
+    if (includeSdk) {
+      allLibraries.addAll(_listSdk());
+    }
+
+    return getMirrorSystem(allLibraries, packageRoot: updatedPackageRoot,
+        parseSdk: parseSdk)
+      .then((MirrorSystem mirrorSystem) {
+        if (mirrorSystem.libraries.isEmpty) {
+          throw new StateError('No library mirrors were created.');
+        }
+        Indexable.initializeTopLevelLibraries(mirrorSystem);
+
+        var availableLibraries = mirrorSystem.libraries.values.where(
+            (each) => each.uri.scheme == 'file');
+        var availableLibrariesByPath = new Map.fromIterables(
+            availableLibraries.map((each) => each.uri),
+            availableLibraries);
+        var librariesToDocument = requestedLibraries.map(
+            (each) => availableLibrariesByPath.putIfAbsent(each,
+                () => throw "Missing library $each")).toList();
+        librariesToDocument.addAll(
+            (includeSdk || parseSdk) ? Indexable._sdkLibraries : []);
+        librariesToDocument.removeWhere(
+            (x) => _excluded.contains(x.simpleName));
+        _documentLibraries(librariesToDocument, includeSdk: includeSdk,
+            outputToYaml: outputToYaml, append: append, parseSdk: parseSdk,
+            introFileName: introFileName);
+        return true;
       });
-}
+  }
 
-/// Creates documentation for filtered libraries.
-void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false,
-    bool outputToYaml: true, bool append: false, bool parseSdk: false,
-    String introduction: ''}) {
-  libs.forEach((lib) {
-    // Files belonging to the SDK have a uri that begins with 'dart:'.
-    if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
-      var library = generateLibrary(lib);
-      entityMap[library.name] = library;
+  /// Writes text to a file in the output directory.
+  static void _writeToFile(String text, String filename, {bool append: false}) {
+    if (text == null) return;
+    Directory dir = new Directory(_outputDirectory);
+    if (!dir.existsSync()) {
+      dir.createSync();
     }
-  });
-  // After everything is created, do a pass through all classes to make sure no
-  // intermediate classes created by mixins are included, all the links to
-  // exported members point to the new library.
-  entityMap.values.where((e) => e is Class).forEach(
-      (c) => c.updateLinksAndRemoveIntermediaryClasses());
-  // Everything is a subclass of Object, therefore empty the list to avoid a
-  // giant list of subclasses to be printed out.
-  if (includeSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear();
-
-  var filteredEntities = entityMap.values.where(_isVisible);
-
-  // Outputs a JSON file with all libraries and their preview comments.
-  // This will help the viewer know what libraries are available to read in.
-  var libraryMap;
-  var linkResolver = (name) => fixReference(name, null, null, null);
-  if (append) {
-    var docsDir = listDir(_outputDirectory);
-    if (!docsDir.contains('$_outputDirectory/library_list.json')) {
-      throw new StateError('No library_list.json');
+    if (path.split(filename).length > 1) {
+      var splitList = path.split(filename);
+      for (int i = 0; i < splitList.length; i++) {
+        var level = splitList[i];
+      }
+      for (var level in path.split(filename)) {
+        var subdir = new Directory(path.join(_outputDirectory,
+                                             path.dirname(filename)));
+        if (!subdir.existsSync()) {
+          subdir.createSync();
+        }
+      }
     }
-    libraryMap =
-        JSON.decode(new File(
-            '$_outputDirectory/library_list.json').readAsStringSync());
-    libraryMap['libraries'].addAll(filteredEntities
-        .where((e) => e is Library)
-        .map((e) => e.previewMap));
-    if (introduction.isNotEmpty) {
+    File file = new File(path.join(_outputDirectory, filename));
+    file.writeAsStringSync(text,
+        mode: append ? FileMode.APPEND : FileMode.WRITE);
+  }
+
+  /// Creates documentation for filtered libraries.
+  static void _documentLibraries(List<LibraryMirror> libs,
+      {bool includeSdk: false, bool outputToYaml: true, bool append: false,
+       bool parseSdk: false, String introFileName: ''}) {
+    libs.forEach((lib) {
+      // Files belonging to the SDK have a uri that begins with 'dart:'.
+      if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
+        var library = generateLibrary(lib);
+        entityMap[library.name] = library;
+      }
+    });
+
+    var filteredEntities = entityMap.values.where(_isFullChainVisible);
+
+    /*var filteredEntities2 = new Set<MirrorBased>();
+    for (Map<String, Set<MirrorBased>> firstLevel in mirrorToDocgen.values) {
+      for (Set<MirrorBased> items in firstLevel.values) {
+        for (MirrorBased item in items) {
+          if (_isFullChainVisible(item)) {
+            filteredEntities2.add(item);
+          }
+        }
+      }
+    }*/
+
+    /*print('THHHHHEEE DIFFERENCE IS');
+    var set1 = new Set.from(filteredEntities);
+    var set2 = new Set.from(filteredEntities2);
+    var aResult = set2.difference(set1);
+    for (MirrorBased r in aResult) {
+      print('     a result is $r and ${r.docName}');
+    }*/
+    //print(set1.difference(set2));
+
+    // Outputs a JSON file with all libraries and their preview comments.
+    // This will help the viewer know what libraries are available to read in.
+    var libraryMap;
+    var linkResolver = (name) => Indexable.globalFixReference(name);
+
+    String readIntroductionFile(String fileName, includeSdk) {
+      var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
+      var introText = defaultText;
+      if (fileName.isNotEmpty) {
+        var introFile = new File(fileName);
+        introText = introFile.existsSync() ? introFile.readAsStringSync() :
+            defaultText;
+      }
+      return markdown.markdownToHtml(introText,
+          linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
+    }
+
+    if (append) {
+      var docsDir = listDir(_outputDirectory);
+      if (!docsDir.contains('$_outputDirectory/library_list.json')) {
+        throw new StateError('No library_list.json');
+      }
+      libraryMap =
+          JSON.decode(new File(
+              '$_outputDirectory/library_list.json').readAsStringSync());
+      libraryMap['libraries'].addAll(filteredEntities
+          .where((e) => e is Library)
+          .map((e) => e.previewMap));
       var intro = libraryMap['introduction'];
-      if (intro.isNotEmpty) intro += '<br/><br/>';
-      intro += markdown.markdownToHtml(
-          new File(introduction).readAsStringSync(),
-              linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes);
-      libraryMap['introduction'] = intro;
-    }
-    outputToYaml = libraryMap['filetype'] == 'yaml';
-  } else {
-    libraryMap = {
-      'libraries' : filteredEntities.where((e) =>
-          e is Library).map((e) => e.previewMap).toList(),
-      'introduction' : introduction == '' ?
-          '' : markdown.markdownToHtml(new File(introduction)
-              .readAsStringSync(), linkResolver: linkResolver,
-                  inlineSyntaxes: markdownSyntaxes),
-      'filetype' : outputToYaml ? 'yaml' : 'json'
-    };
-  }
-  _writeToFile(JSON.encode(libraryMap), 'library_list.json');
-
-  // Output libraries and classes to file after all information is generated.
-  filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
-    _writeIndexableToFile(output, outputToYaml);
-  });
-
-  // Outputs all the qualified names documented with their type.
-  // This will help generate search results.
-  _writeToFile(filteredEntities.map((e) =>
-      '${e.qualifiedName} ${e.typeName}').join('\n') + '\n',
-      'index.txt', append: append);
-  var index = new Map.fromIterables(
-      filteredEntities.map((e) => e.qualifiedName),
-      filteredEntities.map((e) => e.typeName));
-  if (append) {
-    var previousIndex =
-        JSON.decode(new File('$_outputDirectory/index.json').readAsStringSync());
-    index.addAll(previousIndex);
-  }
-  _writeToFile(JSON.encode(index), 'index.json');
-}
-
-Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
-  var result = new Library(library);
-  _findPackage(library, result);
-  logger.fine('Generated library for ${result.name}');
-  return result;
-}
-
-void _writeIndexableToFile(Indexable result, bool outputToYaml) {
-  var outputFile = result.fileName;
-  var output;
-  if (outputToYaml) {
-    output = getYamlString(result.toMap());
-    outputFile = outputFile + '.yaml';
-  } else {
-    output = JSON.encode(result.toMap());
-    outputFile = outputFile + '.json';
-  }
-  _writeToFile(output, outputFile);
-}
-
-/// Returns true if a library name starts with an underscore, and false
-/// otherwise.
-///
-/// An example that starts with _ is _js_helper.
-/// An example that contains ._ is dart._collection.dev
-// This is because LibraryMirror.isPrivate returns `false` all the time.
-bool _isLibraryPrivate(LibraryMirror mirror) {
-  var sdkLibrary = LIBRARIES[mirror.simpleName];
-  if (sdkLibrary != null) {
-    return !sdkLibrary.documented;
-  } else if (mirror.simpleName.startsWith('_') ||
-      mirror.simpleName.contains('._')) {
-    return true;
-  }
-  return false;
-}
-
-/// A declaration is private if itself is private, or the owner is private.
-// Issue(12202) - A declaration is public even if it's owner is private.
-bool _isHidden(DeclarationMirror mirror) {
-  if (mirror is LibraryMirror) {
-    return _isLibraryPrivate(mirror);
-  } else if (mirror.owner is LibraryMirror) {
-    return (mirror.isPrivate || _isLibraryPrivate(mirror.owner));
-  } else {
-    return (mirror.isPrivate || _isHidden(mirror.owner));
-  }
-}
-
-bool _isVisible(Indexable item) {
-  return _includePrivate || !item.isPrivate;
-}
-
-/// Generates MDN comments from database.json.
-void _mdnComment(Indexable item) {
-  //Check if MDN is loaded.
-  if (_mdn == null) {
-    // Reading in MDN related json file.
-    var root = findRootDirectory();
-    var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
-    _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
-  }
-  if (item is Library) return;
-  var domAnnotation = item.annotations.firstWhere(
-      (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null);
-  if (domAnnotation == null) return;
-  var domName = domAnnotation.parameters.single;
-  var parts = domName.split('.');
-  if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]);
-  if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]);
-}
-
-/// Generates the MDN Comment for variables and method DOM elements.
-String _mdnMemberComment(String type, String member) {
-  var mdnType = _mdn[type];
-  if (mdnType == null) return '';
-  var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member,
-      orElse: () => null);
-  if (mdnMember == null) return '';
-  if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
-  if (mdnMember['url'] == null) return '';
-  return _htmlMdn(mdnMember['help'], mdnMember['url']);
-}
-
-/// Generates the MDN Comment for class DOM elements.
-String _mdnTypeComment(String type) {
-  var mdnType = _mdn[type];
-  if (mdnType == null) return '';
-  if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
-  if (mdnType['srcUrl'] == null) return '';
-  return _htmlMdn(mdnType['summary'], mdnType['srcUrl']);
-}
-
-String _htmlMdn(String content, String url) {
-  return '<div class="mdn">' + content.trim() + '<p class="mdn-note">'
-      '<a href="' + url.trim() + '">from Mdn</a></p></div>';
-}
-
-/// Look for the specified name starting with the current member, and
-/// progressively working outward to the current library scope.
-String findElementInScope(String name, LibraryMirror currentLibrary,
-    ClassMirror currentClass, MemberMirror currentMember) {
-  var packagePrefix = _findPackage(currentLibrary);
-  if (packagePrefix != '') packagePrefix += '/';
-
-  determineLookupFunc(name) => name.contains('.') ?
-      dart2js_util.lookupQualifiedInScope :
-      (mirror, name) => mirror.lookupInScope(name);
-  var lookupFunc = determineLookupFunc(name);
-
-  var memberScope = currentMember == null ?
-      null : lookupFunc(currentMember, name);
-  if (memberScope != null) return packagePrefix + docName(memberScope);
-
-  var classScope = currentClass;
-  while (classScope != null) {
-    var classFunc = lookupFunc(currentClass, name);
-    if (classFunc != null) return packagePrefix + docName(classFunc);
-    classScope = classScope.superclass;
-  }
-
-  var libraryScope = currentLibrary == null ?
-      null : lookupFunc(currentLibrary, name);
-  if (libraryScope != null) return packagePrefix + docName(libraryScope);
-
-  // Look in the dart core library scope.
-  var coreScope = _coreLibrary == null? null : lookupFunc(_coreLibrary, name);
-  if (coreScope != null) return packagePrefix + docName(_coreLibrary);
-
-  // If it's a reference that starts with a another library name, then it
-  // looks for a match of that library name in the other sdk libraries.
-  if(name.contains('.')) {
-    var index = name.indexOf('.');
-    var libraryName = name.substring(0, index);
-    var remainingName = name.substring(index + 1);
-    foundLibraryName(library) => library.uri.pathSegments[0] == libraryName;
-
-    if (_sdkLibraries.any(foundLibraryName)) {
-      var library = _sdkLibraries.singleWhere(foundLibraryName);
-      // Look to see if it's a fully qualified library name.
-      var scope = determineLookupFunc(remainingName)(library, remainingName);
-      if (scope != null) return packagePrefix + docName(scope);
-    }
-  }
-  return null;
-}
-
-// HTML escaped version of '<' character.
-final _LESS_THAN = '&lt;';
-
-/// Chunk the provided name into individual parts to be resolved. We take a
-/// simplistic approach to chunking, though, we break at " ", ",", "&lt;"
-/// and ">". All other characters are grouped into the name to be resolved.
-/// As a result, these characters will all be treated as part of the item to be
-/// resolved (aka the * is interpreted literally as a *, not as an indicator for
-/// bold <em>.
-List<String> _tokenizeComplexReference(String name) {
-  var tokens = [];
-  var append = false;
-  var index = 0;
-  while(index < name.length) {
-    if (name.indexOf(_LESS_THAN, index) == index) {
-      tokens.add(_LESS_THAN);
-      append = false;
-      index += _LESS_THAN.length;
-    } else if (name[index] == ' ' || name[index] == ',' ||
-        name[index] == '>') {
-      tokens.add(name[index]);
-      append = false;
-      index++;
+      var spacing = intro.isEmpty ? '' : '<br/><br/>';
+      libraryMap['introduction'] =
+          "$intro$spacing${readIntroductionFile(introFileName, includeSdk)}";
+      outputToYaml = libraryMap['filetype'] == 'yaml';
     } else {
-      if (append) {
-        tokens[tokens.length - 1] = tokens.last + name[index];
+      libraryMap = {
+        'libraries' : filteredEntities.where((e) =>
+            e is Library).map((e) => e.previewMap).toList(),
+        'introduction' : readIntroductionFile(introFileName, includeSdk),
+        'filetype' : outputToYaml ? 'yaml' : 'json'
+      };
+    }
+    _writeToFile(JSON.encode(libraryMap), 'library_list.json');
+
+    // Output libraries and classes to file after all information is generated.
+    filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
+      _writeIndexableToFile(output, outputToYaml);
+    });
+
+    // Outputs all the qualified names documented with their type.
+    // This will help generate search results.
+    _writeToFile(filteredEntities.map((e) =>
+        '${e.qualifiedName} ${e.typeName}').join('\n') + '\n',
+        'index.txt', append: append);
+    var index = new Map.fromIterables(
+        filteredEntities.map((e) => e.qualifiedName),
+        filteredEntities.map((e) => e.typeName));
+    if (append) {
+      var previousIndex =
+          JSON.decode(new File(
+              '$_outputDirectory/index.json').readAsStringSync());
+      index.addAll(previousIndex);
+    }
+    _writeToFile(JSON.encode(index), 'index.json');
+  }
+
+  static void _writeIndexableToFile(Indexable result, bool outputToYaml) {
+    var outputFile = result.fileName;
+    var output;
+    if (outputToYaml) {
+      output = getYamlString(result.toMap());
+      outputFile = outputFile + '.yaml';
+    } else {
+      output = JSON.encode(result.toMap());
+      outputFile = outputFile + '.json';
+    }
+    _writeToFile(output, outputFile);
+  }
+
+  /// Set the location of the ouput directory, and ensure that the location is
+  /// available on the file system.
+  static void _ensureOutputDirectory(String outputDirectory, bool append) {
+    _outputDirectory = outputDirectory;
+    if (!append) {
+      var dir = new Directory(_outputDirectory);
+      if (dir.existsSync()) dir.deleteSync(recursive: true);
+     }
+  }
+
+
+  static String get _rootDirectory {
+    var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
+    var root = scriptDir;
+    while(path.basename(root) != 'dart') {
+      root = path.dirname(root);
+    }
+    return root;
+  }
+
+  /// Analyzes set of libraries and provides a mirror system which can be used
+  /// for static inspection of the source code.
+  static Future<MirrorSystem> _analyzeLibraries(List<Uri> libraries,
+        String libraryRoot, {String packageRoot}) {
+    SourceFileProvider provider = new CompilerSourceFileProvider();
+    api.DiagnosticHandler diagnosticHandler =
+        (new FormattingDiagnosticHandler(provider)
+          ..showHints = false
+          ..showWarnings = false)
+            .diagnosticHandler;
+    Uri libraryUri = new Uri.file(appendSlash(libraryRoot));
+    Uri packageUri = null;
+    if (packageRoot != null) {
+      packageUri = new Uri.file(appendSlash(packageRoot));
+    }
+    return dart2js.analyze(libraries, libraryUri, packageUri,
+        provider.readStringFromUri, diagnosticHandler,
+        ['--preserve-comments', '--categories=Client,Server'])
+        ..catchError((error) {
+          logger.severe('Error: Failed to create mirror system. ');
+          // TODO(janicejl): Use the stack trace package when bug is resolved.
+          // Currently, a string is thrown when it fails to create a mirror
+          // system, and it is not possible to use the stack trace. BUG(#11622)
+          // To avoid printing the stack trace.
+          exit(1);
+        });
+  }
+
+  /// For this run of docgen, determine the packageRoot value.
+  ///
+  /// If packageRoot is not explicitly passed, we examine the files we're
+  /// documenting to attempt to find a package root.
+  static String _obtainPackageRoot(String packageRoot, bool parseSdk,
+      List<String> files) {
+    if (packageRoot == null && !parseSdk) {
+      // TODO(efortuna): This logic seems not very robust, but it's from the
+      // original version of the code, pre-refactor, so I'm leavingt it for now.
+      // Revisit to make more robust.
+      // TODO(efortuna): See lines 303-311 in
+      // https://codereview.chromium.org/116043013/diff/390001/pkg/docgen/lib/docgen.dart
+      var type = FileSystemEntity.typeSync(files.first);
+      if (type == FileSystemEntityType.DIRECTORY) {
+        var files2 = listDir(files.first, recursive: true);
+        // Return '' means that there was no pubspec.yaml and therefor no p
+        // ackageRoot.
+        packageRoot = files2.firstWhere((f) =>
+            f.endsWith('${path.separator}pubspec.yaml'), orElse: () => '');
+        if (packageRoot != '') {
+          packageRoot = path.join(path.dirname(packageRoot), 'packages');
+        }
+      } else if (type == FileSystemEntityType.FILE) {
+        logger.warning('WARNING: No package root defined. If Docgen fails, try '
+            'again by setting the --package-root option.');
+      }
+     }
+    logger.info('Package Root: ${packageRoot}');
+    return path.normalize(path.absolute(packageRoot));
+  }
+
+  /// Given the user provided list of items to document, expand all directories
+  /// to document out into specific files and add any dependent packages for
+  /// documentation if desired.
+  static List<Uri> _findLibrariesToDocument(List<String> args,
+      bool includeDependentPackages) {
+    if (includeDependentPackages) {
+      args.addAll(_allDependentPackageDirs(args.first));
+    }
+
+    var libraries = new List<Uri>();
+    for (var arg in args) {
+      if (FileSystemEntity.typeSync(arg) == FileSystemEntityType.FILE) {
+        if (arg.endsWith('.dart')) {
+          libraries.add(new Uri.file(path.absolute(arg)));
+          logger.info('Added to libraries: ${libraries.last}');
+        }
       } else {
-        tokens.add(name[index]);
-        append = true;
+        libraries.addAll(_findFilesToDocumentInPackage(arg));
       }
-      index++;
     }
+    return libraries;
   }
-  return tokens;
+
+  /// Given a package name, explore the directory and pull out all top level
+  /// library files in the "lib" directory to document.
+  static List<Uri> _findFilesToDocumentInPackage(String packageName) {
+    var libraries = [];
+    // To avoid anaylzing package files twice, only files with paths not
+    // containing '/packages' will be added. The only exception is if the file
+    // to analyze already has a '/package' in its path.
+    var files = listDir(packageName, recursive: true).where(
+        (f) => f.endsWith('.dart') && (!f.contains('${path.separator}packages')
+            || packageName.contains('${path.separator}packages'))).toList();
+
+    files.forEach((String f) {
+      // Only include libraries at the top level of "lib"
+      if (path.basename(path.dirname(f)) == 'lib') {
+        // Only add the file if it does not contain 'part of'
+        // TODO(janicejl): Remove when Issue(12406) is resolved.
+        var contents = new File(f).readAsStringSync();
+        if (!(contents.contains(new RegExp('\npart of ')) ||
+            contents.startsWith(new RegExp('part of ')))) {
+          libraries.add(new Uri.file(path.normalize(path.absolute(f))));
+          logger.info('Added to libraries: $f');
+        }
+      }
+    });
+    return libraries;
+  }
+
+  /// All of the directories for our dependent packages
+  static List<String> _allDependentPackageDirs(String packageDirectory) {
+    var dependentsJson = Process.runSync('pub', ['list-package-dirs'],
+        workingDirectory: packageDirectory, runInShell: true);
+    if (dependentsJson.exitCode != 0) {
+      print(dependentsJson.stderr);
+     }
+    var dependents = JSON.decode(dependentsJson.stdout)['packages'];
+    return dependents.values.toList();
+  }
+
+  /// For all the libraries, return a list of the libraries that are part of
+  /// the SDK.
+  static List<Uri> _listSdk() {
+    var sdk = new List<Uri>();
+    LIBRARIES.forEach((String name, LibraryInfo info) {
+      if (info.documented) {
+        sdk.add(Uri.parse('dart:$name'));
+        logger.info('Add to SDK: ${sdk.last}');
+      }
+    });
+    return sdk;
+  }
+
+  static bool _isFullChainVisible(MirrorBased item) {
+    // TODO: reconcile with isVisible
+    var result = _includePrivate || (!item.isPrivate && (item.owner != null ?
+        _isFullChainVisible(item.owner) : true));
+    return result;
+  }
+
+  /// Currently left public for testing purposes. :-/
+  static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
+    var result = new Library(library);
+    result._findPackage(library);
+    logger.fine('Generated library for ${result.name}');
+    return result;
+  }
 }
 
-/// This is a more complex reference. Try to break up if its of the form A<B>
-/// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"),
-/// or of the form A<B>. Note: unlike other the other markdown-style links, all
-/// text inside the square brackets is treated as part of the link (aka the * is
-/// interpreted literally as a *, not as a indicator for bold <em>.
+/// An item that is categorized in our mirrorToDocgen map, as a distinct,
+/// searchable element.
 ///
-/// Example: [foo&lt;_bar_>] will produce
-/// <a>resolvedFoo</a>&lt;<a>resolved_bar_</a>> rather than an italicized
-/// version of resolvedBar.
-markdown.Node _fixComplexReference(String name, LibraryMirror currentLibrary,
-    ClassMirror currentClass, MemberMirror currentMember) {
-  // Parse into multiple elements we can try to resolve.
-  var tokens = _tokenizeComplexReference(name);
+/// These are items that refer to concrete entities (a Class, for example,
+/// but not a Type, which is a "pointer" to a class) that we wish to be
+/// globally resolvable. This includes things such as class methods and
+/// variables, but parameters for methods are not "Indexable" as we do not want
+/// the user to be able to search for a method based on its parameter names!
+/// The set of indexable items also includes Typedefs, since the user can refer
+/// to them as concrete entities in a particular scope.
+class Indexable extends MirrorBased {
+  /// The dart:core library, which contains all types that are always available
+  /// without import.
+  static Library _coreLibrary;
 
-  // Produce an html representation of our elements. Group unresolved and plain
-  // text are grouped into "link" elements so they display as code.
-  final textElements = [' ', ',', '>', _LESS_THAN];
-  var accumulatedHtml = '';
+  /// Set of libraries declared in the SDK, so libraries that can be accessed
+  /// when running dart by default.
+  static Iterable<LibraryMirror> _sdkLibraries;
 
-  for (var token in tokens) {
-    bool added = false;
-    if (!textElements.contains(token)) {
-      String elementName = findElementInScope(token, currentLibrary,
-          currentClass, currentMember);
-      if (elementName != null) {
-        accumulatedHtml += markdown.renderToHtml([new markdown.Element.text(
-            'a', elementName)]);
-        added = true;
-      }
-    }
-    if (!added) {
-      accumulatedHtml += token;
-    }
-  }
-  return new markdown.Text(accumulatedHtml);
-}
-
-/// Converts all [foo] references in comments to <a>libraryName.foo</a>.
-markdown.Node fixReference(String name, LibraryMirror currentLibrary,
-    ClassMirror currentClass, MemberMirror currentMember) {
-  // Attempt the look up the whole name up in the scope.
-  String elementName =
-      findElementInScope(name, currentLibrary, currentClass, currentMember);
-  if (elementName != null) {
-    return new markdown.Element.text('a', elementName);
-  }
-  return _fixComplexReference(name, currentLibrary, currentClass,
-      currentMember);
-}
-
-markdown.Node fixReferenceWithScope(String name, DeclarationMirror scope) {
-  if (scope is LibraryMirror) return fixReference(name, scope, null, null);
-  if (scope is ClassMirror)
-      return fixReference(name, scope.library, scope, null);
-  if (scope is MemberMirror) {
-    var owner = scope.owner;
-    if (owner is ClassMirror) {
-        return fixReference(name, owner.library, owner, scope);
-    } else {
-      return fixReference(name, owner, null, scope);
-    }
-  }
-  return null;
-}
-
-/// Writes text to a file in the output directory.
-void _writeToFile(String text, String filename, {bool append: false}) {
-  if (text == null) return;
-  Directory dir = new Directory(_outputDirectory);
-  if (!dir.existsSync()) {
-    dir.createSync();
-  }
-  if (path.split(filename).length > 1) {
-    var splitList = path.split(filename);
-    for (int i = 0; i < splitList.length; i++) {
-      var level = splitList[i];
-    }
-    for (var level in path.split(filename)) {
-      var subdir = new Directory(path.join(_outputDirectory,
-                                           path.dirname(filename)));
-      if (!subdir.existsSync()) {
-        subdir.createSync();
-      }
-    }
-  }
-  File file = new File(path.join(_outputDirectory, filename));
-  file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE);
-}
-
-/// Transforms the map by calling toMap on each value in it.
-Map recurseMap(Map inputMap) {
-  var outputMap = {};
-  inputMap.forEach((key, value) {
-    if (value is Map) {
-      outputMap[key] = recurseMap(value);
-    } else {
-      outputMap[key] = value.toMap();
-    }
-  });
-  return outputMap;
-}
-
-/// A type for the function that generates a comment from a mirror.
-typedef String CommentGenerator(Mirror m);
-
-/// A class representing all programming constructs, like library or class.
-class Indexable {
   String get qualifiedName => fileName;
   bool isPrivate;
   DeclarationMirror mirror;
+  /// The comment text pre-resolution. We keep this around because inherited
+  /// methods need to resolve links differently from the superclass.
+  String _unresolvedComment = '';
+
+  // TODO(janicejl): Make MDN content generic or pluggable. Maybe move
+  // MDN-specific code to its own library that is imported into the default
+  // impl?
+  /// Map of all the comments for dom elements from MDN.
+  static Map _mdn;
 
   Indexable(this.mirror) {
     this.isPrivate = _isHidden(mirror);
+
+    var map = mirrorToDocgen[this.mirror.qualifiedName];
+    if (map == null) map = new Map<String, Set<MirrorBased>>();
+
+    var set = map[owner.docName];
+    if (set == null) set = new Set<MirrorBased>();
+    set.add(this);
+    map[owner.docName] = set;
+    mirrorToDocgen[this.mirror.qualifiedName] = map;
   }
 
+  /** Walk up the owner chain to find the owning library. */
+  Library _getOwningLibrary(Indexable indexable) {
+    if (indexable is Library) return indexable;
+    // TODO: is this needed?
+    if (indexable is DummyMirror) return getDocgenObject(indexable.mirror.library);
+    return _getOwningLibrary(indexable.owner);
+  }
+
+  static initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
+    _sdkLibraries = mirrorSystem.libraries.values.where(
+        (each) => each.uri.scheme == 'dart');
+    _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) =>
+        lib.uri.toString().startsWith('dart:core')));
+  }
+
+  markdown.Node fixReferenceWithScope(String name) => null;
+
+  /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
+  markdown.Node fixReference(String name) {
+    // Attempt the look up the whole name up in the scope.
+    String elementName = findElementInScope(name);
+    if (elementName != null) {
+      return new markdown.Element.text('a', elementName);
+    }
+    return _fixComplexReference(name);
+  }
+
+  /// Look for the specified name starting with the current member, and
+  /// progressively working outward to the current library scope.
+  String findElementInScope(String name) =>
+      _findElementInScope(name, packagePrefix);
+
+  static determineLookupFunc(name) => name.contains('.') ?
+      dart2js_util.lookupQualifiedInScope :
+        (mirror, name) => mirror.lookupInScope(name);
+
   // The qualified name (for URL purposes) and the file name are the same,
   // of the form packageName/ClassName or packageName/ClassName.methodName.
   // This defines both the URL and the directory structure.
-  String get fileName => packagePrefix + ownerPrefix + name;
+  String get fileName {
+    return packagePrefix + ownerPrefix + name;
+  }
 
-  Indexable get owningEntity => entityMap[owner];
-
-  String get ownerPrefix => owningEntity == null ?
-      (owner == null || owner.isEmpty ? '' : owner + '.') :
-      owningEntity.qualifiedName + '.';
+  String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : '';
 
   String get packagePrefix => '';
 
@@ -727,9 +735,10 @@
 
   String get comment {
     if (_comment != null) return _comment;
-    _comment = _commentToHtml(mirror);
+
+    _comment = _commentToHtml();
     if (_comment.isEmpty) {
-      _mdnComment(this);
+      _comment = _mdnComment();
     }
     return _comment;
   }
@@ -738,8 +747,54 @@
 
   String get name => mirror.simpleName;
 
-  /// Qualified Name of the owner of this Indexable Item.
-  String get owner => docName(mirror.owner);
+  MirrorBased get owner => new DummyMirror(mirror.owner);
+
+  /// Generates MDN comments from database.json.
+  String _mdnComment() {
+    //Check if MDN is loaded.
+    if (_mdn == null) {
+      // Reading in MDN related json file.
+      var root = _Generator._rootDirectory;
+      var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
+      _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
+    }
+    // TODO: refactor OOP
+    if (this is Library) return '';
+    var domAnnotation = this.annotations.firstWhere(
+        (e) => e.mirror.qualifiedName == 'metadata.DomName',
+        orElse: () => null);
+    if (domAnnotation == null) return '';
+    var domName = domAnnotation.parameters.single;
+    var parts = domName.split('.');
+    if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
+    if (parts.length == 1) return _mdnTypeComment(parts[0]);
+  }
+
+  /// Generates the MDN Comment for variables and method DOM elements.
+  String _mdnMemberComment(String type, String member) {
+    var mdnType = _mdn[type];
+    if (mdnType == null) return '';
+    var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member,
+        orElse: () => null);
+    if (mdnMember == null) return '';
+    if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
+    if (mdnMember['url'] == null) return '';
+    return _htmlMdn(mdnMember['help'], mdnMember['url']);
+  }
+
+  /// Generates the MDN Comment for class DOM elements.
+  String _mdnTypeComment(String type) {
+    var mdnType = _mdn[type];
+    if (mdnType == null) return '';
+    if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
+    if (mdnType['srcUrl'] == null) return '';
+    return _htmlMdn(mdnType['summary'], mdnType['srcUrl']);
+  }
+
+  String _htmlMdn(String content, String url) {
+    return '<div class="mdn">' + content.trim() + '<p class="mdn-note">'
+        '<a href="' + url.trim() + '">from Mdn</a></p></div>';
+  }
 
   /// The type of this member to be used in index.txt.
   String get typeName => '';
@@ -754,12 +809,7 @@
     return finalMap;
   }
 
-  /// Returns any documentation comments associated with a mirror with
-  /// simple markdown converted to html.
-  ///
-  /// It's possible to have a comment that comes from one mirror applied to
-  /// another, in the case of an inherited comment.
-  String _commentToHtml(itemToDocument) {
+  String _getCommentText() {
     String commentText;
     mirror.metadata.forEach((metadata) {
       if (metadata is CommentInstanceMirror) {
@@ -773,11 +823,24 @@
         }
       }
     });
+    return commentText;
+  }
 
-    var linkResolver = (name) => fixReferenceWithScope(name, itemToDocument);
+  /// Returns any documentation comments associated with a mirror with
+  /// simple markdown converted to html.
+  ///
+  /// By default we resolve any comment references within our own scope.
+  /// However, if a method is inherited, we want the inherited comments, but
+  /// links to the subclasses's version of the methods.
+  String _commentToHtml([Indexable resolvingScope]) {
+    if (resolvingScope == null) resolvingScope = this;
+    var commentText = _getCommentText();
+    _unresolvedComment = commentText;
+
+    var linkResolver = (name) => resolvingScope.fixReferenceWithScope(name);
     commentText = commentText == null ? '' :
         markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver,
-            inlineSyntaxes: markdownSyntaxes);
+            inlineSyntaxes: _MARKDOWN_SYNTAXES);
     return commentText;
   }
 
@@ -785,21 +848,16 @@
   /// The optional parameter [containingLibrary] is contains data for variables
   /// defined at the top level of a library (potentially for exporting
   /// purposes).
-  Map<String, Variable> _createVariables(Map<String,
-      VariableMirror> mirrorMap, [Library containingLibrary]) {
+  Map<String, Variable> _createVariables(Map<String, VariableMirror> mirrorMap,
+      Indexable owner) {
     var data = {};
     // TODO(janicejl): When map to map feature is created, replace the below
     // with a filter. Issue(#9590).
     mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
-      if (_includePrivate || !_isHidden(mirror)) {
-        if (containingLibrary != null && mirror.owner.qualifiedName !=
-            containingLibrary.mirror.qualifiedName) {
-          entityMap[docName(mirror)] = new ExportedVariable(mirrorName, mirror,
-              containingLibrary);
-        } else {
-          entityMap[docName(mirror)] = new Variable(mirrorName, mirror);
-        }
-        data[mirrorName] = entityMap[docName(mirror)];
+      if (_Generator._includePrivate || !_isHidden(mirror)) {
+        var variable = new Variable(mirrorName, mirror, owner);
+        entityMap[variable.docName] = variable;
+        data[mirrorName] = entityMap[variable.docName];
       }
     });
     return data;
@@ -809,25 +867,25 @@
   /// The optional parameter [containingLibrary] is contains data for variables
   /// defined at the top level of a library (potentially for exporting
   /// purposes).
-  MethodGroup _createMethods(Map<String, MethodMirror> mirrorMap,
-      [Library containingLibrary]) {
-    var group = new MethodGroup();
+  Map<String, Method> _createMethods(Map<String, MethodMirror> mirrorMap,
+      Indexable owner) {
+    var group = new Map<String, Method>();
     mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
-      if (_includePrivate || !mirror.isPrivate) {
-        group.addMethod(mirror, containingLibrary);
+      if (_Generator._includePrivate || !mirror.isPrivate) {
+        var method = new Method(mirror, owner);
+        entityMap[method.docName] = method;
+        group[mirror.simpleName] = method;
       }
     });
     return group;
   }
 
   /// Returns a map of [Parameter] objects constructed from [mirrorList].
-  Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList) {
+  Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList,
+      Indexable owner) {
     var data = {};
     mirrorList.forEach((ParameterMirror mirror) {
-      data[mirror.simpleName] = new Parameter(mirror.simpleName,
-          mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
-          _createType(mirror.type), mirror.defaultValue,
-          _createAnnotations(mirror));
+      data[mirror.simpleName] = new Parameter(mirror, _getOwningLibrary(owner));
     });
     return data;
   }
@@ -836,44 +894,7 @@
   Map<String, Generic> _createGenerics(ClassMirror mirror) {
     return new Map.fromIterable(mirror.typeVariables,
         key: (e) => e.toString(),
-        value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
-  }
-
-  /// Returns a single [Type] object constructed from the Method.returnType
-  /// Type mirror.
-  Type _createType(TypeMirror mirror) {
-    return new Type(docName(mirror), _createTypeGenerics(mirror));
-  }
-
-  /// Returns a list of [Type] objects constructed from TypeMirrors.
-  List<Type> _createTypeGenerics(TypeMirror mirror) {
-    if (mirror is ClassMirror && !mirror.isTypedef) {
-      var innerList = [];
-      mirror.typeArguments.forEach((e) {
-        innerList.add(new Type(docName(e), _createTypeGenerics(e)));
-      });
-      return innerList;
-    }
-    return [];
-  }
-
-  /// Returns a list of meta annotations assocated with a mirror.
-  List<Annotation> _createAnnotations(DeclarationMirror mirror) {
-    var annotationMirrors = mirror.metadata.where((e) =>
-        e is dart2js.Dart2JsConstructedConstantMirror);
-    var annotations = [];
-    annotationMirrors.forEach((annotation) {
-      var parameterList = annotation.type.variables.values
-        .where((e) => e.isFinal)
-        .map((e) => annotation.getField(e.simpleName).reflectee)
-        .where((e) => e != null)
-        .toList();
-      if (!skippedAnnotations.contains(docName(annotation.type))) {
-        annotations.add(new Annotation(docName(annotation.type),
-            parameterList));
-      }
-    });
-    return annotations;
+        value: (e) => new Generic(e));
   }
 
   /// Return an informative [Object.toString] for debugging.
@@ -881,6 +902,188 @@
 
   /// Return a map representation of this type.
   Map toMap() {}
+
+
+  /// A declaration is private if itself is private, or the owner is private.
+  // Issue(12202) - A declaration is public even if it's owner is private.
+  bool _isHidden(DeclarationMirror mirror) {
+    if (mirror is LibraryMirror) {
+      return _isLibraryPrivate(mirror);
+    } else if (mirror.owner is LibraryMirror) {
+      return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)
+          || mirror.isNameSynthetic);
+    } else {
+      return (mirror.isPrivate || _isHidden(mirror.owner)
+          || owner.mirror.isNameSynthetic);
+    }
+  }
+
+  /// Returns true if a library name starts with an underscore, and false
+  /// otherwise.
+  ///
+  /// An example that starts with _ is _js_helper.
+  /// An example that contains ._ is dart._collection.dev
+  // This is because LibraryMirror.isPrivate returns `false` all the time.
+  bool _isLibraryPrivate(LibraryMirror mirror) {
+    var sdkLibrary = LIBRARIES[mirror.simpleName];
+    if (sdkLibrary != null) {
+      return !sdkLibrary.documented;
+    } else if (mirror.simpleName.startsWith('_') ||
+        mirror.simpleName.contains('._')) {
+      return true;
+    }
+    return false;
+  }
+
+  ////// Top level resolution functions
+  /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
+  static markdown.Node globalFixReference(String name) {
+    // Attempt the look up the whole name up in the scope.
+    String elementName = _findElementInScope(name, '');
+    if (elementName != null) {
+      return new markdown.Element.text('a', elementName);
+    }
+    return _fixComplexReference(name);
+  }
+
+  /// This is a more complex reference. Try to break up if its of the form A<B>
+  /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"),
+  /// or of the form A<B>. Note: unlike other the other markdown-style links,
+  /// all text inside the square brackets is treated as part of the link (aka
+  /// the * is interpreted literally as a *, not as a indicator for bold <em>.
+  ///
+  /// Example: [foo&lt;_bar_>] will produce
+  /// <a>resolvedFoo</a>&lt;<a>resolved_bar_</a>> rather than an italicized
+  /// version of resolvedBar.
+  static markdown.Node _fixComplexReference(String name) {
+    // Parse into multiple elements we can try to resolve.
+    var tokens = _tokenizeComplexReference(name);
+
+    // Produce an html representation of our elements. Group unresolved and
+    // plain text are grouped into "link" elements so they display as code.
+    final textElements = [' ', ',', '>', _LESS_THAN];
+    var accumulatedHtml = '';
+
+    for (var token in tokens) {
+      bool added = false;
+      if (!textElements.contains(token)) {
+        String elementName = _findElementInScope(token, '');
+        if (elementName != null) {
+          accumulatedHtml += markdown.renderToHtml([new markdown.Element.text(
+              'a', elementName)]);
+          added = true;
+        }
+      }
+      if (!added) {
+        accumulatedHtml += token;
+       }
+     }
+    return new markdown.Text(accumulatedHtml);
+  }
+
+
+  // HTML escaped version of '<' character.
+  static final _LESS_THAN = '&lt;';
+
+  /// Chunk the provided name into individual parts to be resolved. We take a
+  /// simplistic approach to chunking, though, we break at " ", ",", "&lt;"
+  /// and ">". All other characters are grouped into the name to be resolved.
+  /// As a result, these characters will all be treated as part of the item to
+  /// be resolved (aka the * is interpreted literally as a *, not as an
+  /// indicator for bold <em>.
+  static List<String> _tokenizeComplexReference(String name) {
+    var tokens = [];
+    var append = false;
+    var index = 0;
+    while(index < name.length) {
+      if (name.indexOf(_LESS_THAN, index) == index) {
+        tokens.add(_LESS_THAN);
+        append = false;
+        index += _LESS_THAN.length;
+      } else if (name[index] == ' ' || name[index] == ',' ||
+          name[index] == '>') {
+        tokens.add(name[index]);
+        append = false;
+        index++;
+      } else {
+        if (append) {
+          tokens[tokens.length - 1] = tokens.last + name[index];
+        } else {
+          tokens.add(name[index]);
+          append = true;
+        }
+        index++;
+      }
+    }
+    return tokens;
+  }
+
+  static String _findElementInScope(String name, String packagePrefix) {
+    var lookupFunc = determineLookupFunc(name);
+    // Look in the dart core library scope.
+    var coreScope = _coreLibrary == null? null :
+        lookupFunc(_coreLibrary.mirror, name);
+    if (coreScope != null) return packagePrefix + _coreLibrary.docName;
+
+    // If it's a reference that starts with a another library name, then it
+    // looks for a match of that library name in the other sdk libraries.
+    if(name.contains('.')) {
+      var index = name.indexOf('.');
+      var libraryName = name.substring(0, index);
+      var remainingName = name.substring(index + 1);
+      foundLibraryName(library) => library.uri.pathSegments[0] == libraryName;
+
+      if (_sdkLibraries.any(foundLibraryName)) {
+        var library = _sdkLibraries.singleWhere(foundLibraryName);
+        // Look to see if it's a fully qualified library name.
+        var scope = determineLookupFunc(remainingName)(library, remainingName);
+        if (scope != null) {
+          var result = getDocgenObject(scope);
+          if (result is DummyMirror) {
+            return packagePrefix + result.docName;
+          } else {
+            return result.packagePrefix + result.docName;
+          }
+        }
+      }
+     }
+    return null;
+  }
+
+  Map expandMethodMap(Map<String, Method> mapToExpand) => {
+    'setters': recurseMap(_filterMap(new Map(), mapToExpand,
+        (key, val) => val.mirror.isSetter)),
+    'getters': recurseMap(_filterMap(new Map(), mapToExpand,
+        (key, val) => val.mirror.isGetter)),
+    'constructors': recurseMap(_filterMap(new Map(), mapToExpand,
+        (key, val) => val.mirror.isConstructor)),
+    'operators': recurseMap(_filterMap(new Map(), mapToExpand,
+        (key, val) => val.mirror.isOperator)),
+    'methods': recurseMap(_filterMap(new Map(), mapToExpand,
+        (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator))
+  };
+
+  /// Transforms the map by calling toMap on each value in it.
+  Map recurseMap(Map inputMap) {
+    var outputMap = {};
+    inputMap.forEach((key, value) {
+      if (value is Map) {
+        outputMap[key] = recurseMap(value);
+      } else {
+        outputMap[key] = value.toMap();
+      }
+    });
+    return outputMap;
+  }
+
+  Map _filterMap(exported, map, test) {
+    map.forEach((key, value) {
+      if (test(key, value)) exported[key] = value;
+    });
+    return exported;
+  }
+
+  bool get _isVisible => _Generator._includePrivate || !isPrivate;
 }
 
 /// A class containing contents of a Dart library.
@@ -890,36 +1093,125 @@
   Map<String, Variable> variables;
 
   /// Top-level functions in the library.
-  MethodGroup functions;
+  Map<String, Method> functions;
 
-  /// Classes defined within the library
-  ClassGroup classes;
+  Map<String, Class> classes = {};
+  Map<String, Typedef> typedefs = {};
+  Map<String, Class> errors = {};
 
   String packageName = '';
   bool hasBeenCheckedForPackage = false;
   String packageIntro;
 
-  Map<String, Exported> _exportedMembers;
-
-  Library(LibraryMirror libraryMirror) : super(libraryMirror) {
-    var exported = _calcExportedItems(libraryMirror);
-    _createClasses(exported['classes']..addAll(libraryMirror.classes));
-    this.functions = _createMethods(
-        exported['methods']..addAll(libraryMirror.functions), this);
-    this.variables = _createVariables(
-        exported['variables']..addAll(libraryMirror.variables), this);
-
-    var exportedVariables = {};
-    variables.forEach((key, value) {
-      if (value is ExportedVariable) {
-        exportedVariables[key] = value;
-      }
-    });
-    _exportedMembers = new Map.from(this.classes.exported)
-        ..addAll(this.functions.exported)
-        ..addAll(exportedVariables);
+  /// Returns the [Library] for the given [mirror] if it has already been
+  /// created, else creates it.
+  factory Library(LibraryMirror mirror) {
+    var library = getDocgenObject(mirror);
+    if (library is DummyMirror) {
+      library = new Library._(mirror);
+    }
+    return library;
   }
 
+  Library._(LibraryMirror libraryMirror) : super(libraryMirror) {
+    var exported = _calcExportedItems(libraryMirror);
+    var exportedClasses = exported['classes']..addAll(libraryMirror.classes);
+    _findPackage(mirror);
+    classes = {};
+    typedefs = {};
+    errors = {};
+    exportedClasses.forEach((String mirrorName, ClassMirror classMirror) {
+        if (classMirror.isTypedef) {
+          // This is actually a Dart2jsTypedefMirror, and it does define value,
+          // but we don't have visibility to that type.
+          var mirror = classMirror;
+          if (_Generator._includePrivate || !mirror.isPrivate) {
+            entityMap[getDocgenObject(mirror).docName] =
+                new Typedef(mirror, this);
+            typedefs[mirror.simpleName] =
+                entityMap[getDocgenObject(mirror).docName];
+          }
+        } else {
+          var clazz = new Class(classMirror, this);
+
+          if (clazz.isError()) {
+            errors[classMirror.simpleName] = clazz;
+          } else if (classMirror.isClass) {
+            classes[classMirror.simpleName] = clazz;
+          } else {
+            throw new ArgumentError(
+                '${classMirror.simpleName} - no class type match. ');
+          }
+        }
+    });
+    this.functions =  _createMethods(exported['methods']
+      ..addAll(libraryMirror.functions), this);
+    this.variables = _createVariables(exported['variables']
+      ..addAll(libraryMirror.variables), this);
+  }
+
+  /// Look for the specified name starting with the current member, and
+  /// progressively working outward to the current library scope.
+  String findElementInScope(String name) {
+    var lookupFunc = Indexable.determineLookupFunc(name);
+    var libraryScope = lookupFunc(mirror, name);
+    if (libraryScope != null) {
+      var result = getDocgenObject(libraryScope, this);
+      if (result is DummyMirror) return packagePrefix + result.docName;
+      return result.packagePrefix + result.docName;
+    }
+    return super.findElementInScope(name);
+  }
+
+  /// For a library's [mirror], determine the name of the package (if any) we
+  /// believe it came from (because of its file URI).
+  ///
+  /// If no package could be determined, we return an empty string.
+  String _findPackage(LibraryMirror mirror) {
+    if (mirror == null) return '';
+    if (hasBeenCheckedForPackage) return packageName;
+    hasBeenCheckedForPackage = true;
+    if (mirror.uri.scheme != 'file') return '';
+    var filePath = mirror.uri.toFilePath();
+    // We assume that we are documenting only libraries under package/lib
+    var rootdir = path.dirname((path.dirname(filePath)));
+    var pubspec = path.join(rootdir, 'pubspec.yaml');
+    packageName = _packageName(pubspec);
+    // Associate the package readme with all the libraries. This is a bit
+    // wasteful, but easier than trying to figure out which partial match
+    // is best.
+    packageIntro = _packageIntro(rootdir);
+    return packageName;
+  }
+
+  String _packageIntro(packageDir) {
+    var dir = new Directory(packageDir);
+    var files = dir.listSync();
+    var readmes = files.where((FileSystemEntity each) => (each is File &&
+        each.path.substring(packageDir.length + 1, each.path.length)
+          .startsWith('README'))).toList();
+    if (readmes.isEmpty) return '';
+    // If there are multiples, pick the shortest name.
+    readmes.sort((a, b) => a.path.length.compareTo(b.path.length));
+    var readme = readmes.first;
+    var linkResolver = (name) => Indexable.globalFixReference(name);
+    var contents = markdown.markdownToHtml(readme
+      .readAsStringSync(), linkResolver: linkResolver,
+      inlineSyntaxes: _MARKDOWN_SYNTAXES);
+    return contents;
+  }
+
+  /// Read a pubspec and return the library name.
+  String _packageName(String pubspecName) {
+    File pubspec = new File(pubspecName);
+    if (!pubspec.existsSync()) return '';
+    var contents = pubspec.readAsStringSync();
+    var spec = loadYaml(contents);
+    return spec["name"];
+  }
+
+  markdown.Node fixReferenceWithScope(String name) => fixReference(name);
+
   String get packagePrefix => packageName == null || packageName.isEmpty ?
       '' : '$packageName/';
 
@@ -932,17 +1224,9 @@
     return basic;
   }
 
-  String get owner => '';
+  String get name => docName;
 
-  String get name => docName(mirror);
-
-  /// Set our classes field with error, typedef and regular classes.
-  void _createClasses(Map<String, ClassMirror> mirrorMap) {
-    this.classes = new ClassGroup();
-    mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
-      this.classes.addClass(mirror, this);
-    });
-  }
+  String get docName => mirror.qualifiedName.replaceAll('.','-');
 
   /// For the given library determine what items (if any) are exported.
   ///
@@ -1006,14 +1290,25 @@
     return exports;
   }
 
+  /// Checks if the given name is a key for any of the Class Maps.
+  bool containsKey(String name) {
+    return classes.containsKey(name) || errors.containsKey(name);
+  }
+
   /// Generates a map describing the [Library] object.
   Map toMap() => {
     'name': name,
     'qualifiedName': qualifiedName,
     'comment': comment,
     'variables': recurseMap(variables),
-    'functions': functions.toMap(),
-    'classes': classes.toMap(),
+    'functions': expandMethodMap(functions),
+    'classes': {
+      'class': classes.values.where((c) => c._isVisible)
+        .map((e) => e.previewMap).toList(),
+      'typedef': recurseMap(typedefs),
+      'error': errors.values.where((e) => e._isVisible)
+          .map((e) => e.previewMap).toList()
+    },
     'packageName': packageName,
     'packageIntro' : packageIntro
   };
@@ -1034,13 +1329,12 @@
   Map<String, Variable> variables;
 
   /// Inherited variables in the class.
-  Map<String, Variable> inheritedVariables = {};
+  Map<String, Variable> inheritedVariables;
 
   /// Methods in the class.
-  MethodGroup methods;
+  Map<String, Method> methods;
 
-  /// Inherited methods in the class.
-  MethodGroup inheritedMethods = new MethodGroup();
+  Map<String, Method> inheritedMethods;
 
   /// Generic infomation about the class.
   Map<String, Generic> generics;
@@ -1054,33 +1348,58 @@
   /// Make sure that we don't check for inherited comments more than once.
   bool _commentsEnsured = false;
 
+  Indexable owner;
+
   /// Returns the [Class] for the given [mirror] if it has already been created,
   /// else creates it.
-  factory Class(ClassMirror mirror) {
-    var clazz = entityMap[docName(mirror)];
-    if (clazz == null) {
-      clazz = new Class._(mirror);
-      entityMap[docName(mirror)] = clazz;
+  factory Class(ClassMirror mirror, Library owner) {
+    var clazz = getDocgenObject(mirror, owner);
+    if (clazz is DummyMirror) {
+      clazz = new Class._(mirror, owner);
+      entityMap[clazz.docName] = clazz;
     }
     return clazz;
   }
 
-  Class._(ClassMirror classMirror) : super(classMirror) {
-    var superclass = classMirror.superclass != null ?
-        new Class(classMirror.superclass) : null;
-    var interfaces = classMirror.superinterfaces.map(
-        (interface) => new Class(interface));
+  /// Called when we are constructing a superclass or interface class, but it
+  /// is not known if it belongs to the same owner as the original class. In
+  /// this case, we create an object whose owner is what the original mirror
+  /// says it is.
+  factory Class._possiblyDifferentOwner(ClassMirror mirror,
+      Library originalOwner) {
+    if (mirror.owner is LibraryMirror) {
+      var realOwner = getDocgenObject(mirror.owner);
+      if (realOwner is Library) {
+        return new Class(mirror, realOwner);
+      } else {
+        return new Class(mirror, originalOwner);
+      }
+    } else {
+      return new Class(mirror, originalOwner);
+    }
+  }
 
-    this.superclass = superclass;
-    this.interfaces = interfaces.toList();
-    this.variables = _createVariables(classMirror.variables);
-    this.methods = _createMethods(classMirror.methods);
-    this.annotations = _createAnnotations(classMirror);
-    this.generics = _createGenerics(classMirror);
-    this.isAbstract = classMirror.isAbstract;
+  Class._(ClassMirror classMirror, this.owner) : super(classMirror) {
+    inheritedVariables = {};
 
-    // Tell all superclasses that you are a subclass.
-    if (!classMirror.isNameSynthetic && _isVisible(this)) {
+    // The reason we do this madness is the superclass and interface owners may
+    // not be this class's owner!! Example: BaseClient in http pkg.
+    var superinterfaces = classMirror.superinterfaces.map(
+        (interface) => new Class._possiblyDifferentOwner(interface, owner));
+    this.superclass = classMirror.superclass == null? null :
+        new Class._possiblyDifferentOwner(classMirror.superclass, owner);
+
+    interfaces = superinterfaces.toList();
+    variables = _createVariables(classMirror.variables, this);
+    methods = _createMethods(classMirror.methods, this);
+    annotations = _createAnnotations(classMirror, _getOwningLibrary(owner));
+    generics = _createGenerics(classMirror);
+    isAbstract = classMirror.isAbstract;
+    inheritedMethods = new Map<String, Method>();
+
+    // Tell all superclasses that you are a subclass, unless you are not
+    // visible or an intermediary mixin class.
+    if (!classMirror.isNameSynthetic && _isVisible) {
       parentChain().forEach((parentClass) {
           parentClass.addSubclass(this);
       });
@@ -1090,12 +1409,41 @@
     interfaces.forEach((interface) => addInherited(interface));
   }
 
+  String get packagePrefix => owner.packagePrefix;
+
+  String _lookupInClassAndSuperclasses(String name) {
+    var lookupFunc = Indexable.determineLookupFunc(name);
+    var classScope = this;
+    while (classScope != null) {
+      var classFunc = lookupFunc(classScope.mirror, name);
+      if (classFunc != null) {
+        return packagePrefix + getDocgenObject(classFunc, owner).docName;
+      }
+      classScope = classScope.superclass;
+    }
+    return null;
+  }
+
+  /// Look for the specified name starting with the current member, and
+  /// progressively working outward to the current library scope.
+  String findElementInScope(String name) {
+    var lookupFunc = Indexable.determineLookupFunc(name);
+    var result = _lookupInClassAndSuperclasses(name);
+    if (result != null) {
+      return result;
+    }
+    result = owner.findElementInScope(name);
+    return result == null ? super.findElementInScope(name) : result;
+  }
+
+  markdown.Node fixReferenceWithScope(String name) => fixReference(name);
+
   String get typeName => 'class';
 
   /// Returns a list of all the parent classes.
   List<Class> parentChain() {
+    // TODO(efortuna): Seems like we can get rid of this method.
     var parent = superclass == null ? [] : [superclass];
-    parent.addAll(interfaces);
     return parent;
   }
 
@@ -1104,16 +1452,46 @@
   /// the superclass.
   void addInherited(Class superclass) {
     inheritedVariables.addAll(superclass.inheritedVariables);
-    inheritedVariables.addAll(_filterStatics(superclass.variables));
-    inheritedMethods.addInherited(superclass);
+    inheritedVariables.addAll(_allButStatics(superclass.variables));
+    addInheritedMethod(superclass, this);
+  }
+
+  /** [newParent] refers to the actual class is currently using these methods.
+   * which may be different because with the mirror system, we only point to the
+   * original canonical superclasse's method.
+   */
+  void addInheritedMethod(Class parent, Class newParent) {
+    parent.inheritedMethods.forEach((name, method) {
+      if(!method.isConstructor){
+        inheritedMethods[name] = new Method(method.mirror, newParent, method);
+      }}
+    );
+    _allButStatics(parent.methods).forEach((name, method) {
+      if (!method.isConstructor) {
+        inheritedMethods[name] = new Method(method.mirror, newParent, method);
+      }}
+    );
+  }
+
+  /// Remove statics from the map of inherited items before adding them.
+  Map _allButStatics(Map items) {
+    var result = {};
+    items.forEach((name, item) {
+      if (!item.isStatic) {
+        result[name] = item;
+      }
+    });
+    return result;
   }
 
   /// Add the subclass to the class.
   ///
-  /// If [this] is private, it will add the subclass to the list of subclasses
-  /// in the superclasses.
+  /// If [this] is private (or an intermediary mixin class), it will add the
+  /// subclass to the list of subclasses in the superclasses.
   void addSubclass(Class subclass) {
-    if (!_includePrivate && isPrivate) {
+    if (docName == 'dart-core.Object') return;
+
+    if (!_Generator._includePrivate && isPrivate || mirror.isNameSynthetic) {
       if (superclass != null) superclass.addSubclass(subclass);
       interfaces.forEach((interface) {
         interface.addSubclass(subclass);
@@ -1135,40 +1513,23 @@
     return superclass.isError();
   }
 
-  /// Check that the class exists in the owner library.
-  ///
-  /// If it does not exist in the owner library, it is a mixin applciation and
-  /// should be removed.
-  void updateLinksAndRemoveIntermediaryClasses() {
-    var library = entityMap[owner];
-    if (library != null) {
-      if (!library.classes.containsKey(name) && mirror.isNameSynthetic) {
-        // In the mixin case, remove the intermediary classes.
-        this.isPrivate = true;
-        // Since we are now making the mixin a private class, make all elements
-        // with the mixin as an owner private too.
-        entityMap.values.where((e) => e.owner == qualifiedName).forEach(
-            (element) => element.isPrivate = true);
-        // Move the subclass up to the next public superclass
-        subclasses.forEach((subclass) => addSubclass(subclass));
-      } else {
-        // It is an exported item. Loop through each of the exported types,
-        // and tell them to update their links, given these other exported
-        // names within the library.
-        for (Exported member in library._exportedMembers.values) {
-          member.updateExports(library._exportedMembers);
-        }
-      }
-    }
-  }
-
   /// Makes sure that all methods with inherited equivalents have comments.
   void ensureComments() {
     if (_commentsEnsured) return;
     _commentsEnsured = true;
+    if (superclass != null) superclass.ensureComments();
     inheritedMethods.forEach((qualifiedName, inheritedMethod) {
       var method = methods[qualifiedName];
-      if (method != null) method.ensureCommentFor(inheritedMethod);
+      if (method != null) {
+        // if we have overwritten this method in this class, we still provide
+        // the opportunity to inherit the comments.
+        method.ensureCommentFor(inheritedMethod);
+      }
+    });
+    // we need to populate the comments for all methods. so that the subclasses
+    // can get for their inherited versions the comments.
+    methods.forEach((qualifiedName, method) {
+      if (!method.mirror.isConstructor) method.ensureCommentFor(method);
     });
   }
 
@@ -1176,7 +1537,7 @@
   /// superclass of the private superclass.
   String validSuperclass() {
     if (superclass == null) return 'dart.core.Object';
-    if (_isVisible(superclass)) return superclass.qualifiedName;
+    if (superclass._isVisible) return superclass.qualifiedName;
     return superclass.validSuperclass();
   }
 
@@ -1187,14 +1548,14 @@
     'comment': comment,
     'isAbstract' : isAbstract,
     'superclass': validSuperclass(),
-    'implements': interfaces.where(_isVisible)
+    'implements': interfaces.where((i) => i._isVisible)
         .map((e) => e.qualifiedName).toList(),
     'subclass': (subclasses.toList()..sort())
         .map((x) => x.qualifiedName).toList(),
     'variables': recurseMap(variables),
     'inheritedVariables': recurseMap(inheritedVariables),
-    'methods': methods.toMap(),
-    'inheritedMethods': inheritedMethods.toMap(),
+    'methods': expandMethodMap(methods),
+    'inheritedMethods': expandMethodMap(inheritedMethods),
     'annotations': annotations.map((a) => a.toMap()).toList(),
     'generics': recurseMap(generics)
   };
@@ -1202,113 +1563,6 @@
   int compareTo(aClass) => name.compareTo(aClass.name);
 }
 
-abstract class Exported {
-  void updateExports(Map<String, Indexable> libraryExports);
-}
-
-Map _filterMap(exported, map, test) {
-  map.forEach((key, value) {
-    if (test(value)) exported[key] = value;
-  });
-  return exported;
-}
-
-class ExportedClass extends Class implements Exported {
-  Class _originalClass;
-  Library _exportingLibrary;
-
-  ExportedClass(ClassMirror originalClass, Library this._exportingLibrary) :
-      super._(originalClass) {
-    _originalClass = new Class(originalClass);
-  }
-
-  // The qualified name (for URL purposes) and the file name are the same,
-  // of the form packageName/ClassName or packageName/ClassName.methodName.
-  // This defines both the URL and the directory structure.
-  String get fileName => path.join(_exportingLibrary.packageName,
-      _exportingLibrary.mirror.qualifiedName + '.' + _originalClass.name);
-
-  void updateExports(Map<String, Indexable> libraryExports) {
-    // TODO(efortuna): If this class points to another exported class or type
-    // of some sort, then that reference needs to be updated here.
-    /* these need to be updated:
-    'comment': comment,
-    'superclass': validSuperclass(),
-    'implements': interfaces.where(_isVisible)
-        .map((e) => e.qualifiedName).toList(),
-    'subclass': (subclasses.toList()..sort())
-        .map((x) => x.qualifiedName).toList(),
-    'variables': recurseMap(variables),
-    'inheritedVariables': recurseMap(inheritedVariables),
-    'methods': methods.toMap(),
-    'inheritedMethods': inheritedMethods.toMap(),
-    'annotations': annotations.map((a) => a.toMap()).toList(),
-    'generics': recurseMap(generics)
-    */
-  }
-}
-
-/// A container to categorize classes into the following groups: abstract
-/// classes, regular classes, typedefs, and errors.
-class ClassGroup {
-  Map<String, Class> classes = {};
-  Map<String, Typedef> typedefs = {};
-  Map<String, Class> errors = {};
-
-  Map<String, Exported> get exported {
-    var exported = _filterMap({}, classes, (value) => value is ExportedClass);
-    // TODO(efortuna): The line below needs updating.
-    exported = _filterMap(exported, typedefs,
-        (value) => value is ExportedClass);
-    exported = _filterMap(exported, errors,
-        (value) => value is ExportedClass);
-    return exported;
-  }
-
-  void addClass(ClassMirror classMirror, Library containingLibrary) {
-    if (classMirror.isTypedef) {
-      // This is actually a Dart2jsTypedefMirror, and it does define value,
-      // but we don't have visibility to that type.
-      var mirror = classMirror;
-      if (_includePrivate || !mirror.isPrivate) {
-        entityMap[docName(mirror)] = new Typedef(mirror);
-        typedefs[mirror.simpleName] = entityMap[docName(mirror)];
-      }
-    } else {
-      var clazz = new Class(classMirror);
-
-      if (classMirror.library.qualifiedName !=
-          containingLibrary.mirror.qualifiedName) {
-        var exportedClass = new ExportedClass(classMirror, containingLibrary);
-        entityMap[clazz.fileName] = exportedClass;
-        clazz = exportedClass;
-      }
-
-      if (clazz.isError()) {
-        errors[classMirror.simpleName] = clazz;
-      } else if (classMirror.isClass) {
-        classes[classMirror.simpleName] = clazz;
-      } else {
-        throw new ArgumentError(
-            '${classMirror.simpleName} - no class type match. ');
-      }
-    }
-  }
-
-  /// Checks if the given name is a key for any of the Class Maps.
-  bool containsKey(String name) {
-    return classes.containsKey(name) || errors.containsKey(name);
-  }
-
-  Map toMap() => {
-    'class': classes.values.where(_isVisible)
-      .map((e) => e.previewMap).toList(),
-    'typedef': recurseMap(typedefs),
-    'error': errors.values.where(_isVisible)
-      .map((e) => e.previewMap).toList()
-  };
-}
-
 class Typedef extends Indexable {
   String returnType;
 
@@ -1320,11 +1574,22 @@
   /// List of the meta annotations on the typedef.
   List<Annotation> annotations;
 
-  Typedef(mirror) : super(mirror) {
-    this.returnType = docName(mirror.value.returnType);
-    this.generics = _createGenerics(mirror);
-    this.parameters = _createParameters(mirror.value.parameters);
-    this.annotations = _createAnnotations(mirror);
+  /// Returns the [Library] for the given [mirror] if it has already been
+  /// created, else creates it.
+  factory Typedef(TypedefMirror mirror, Library owningLibrary) {
+    var aTypedef = getDocgenObject(mirror, owningLibrary);
+    if (aTypedef is DummyMirror) {
+      aTypedef = new Typedef._(mirror, owningLibrary);
+    }
+    return aTypedef;
+  }
+
+  Typedef._(TypedefMirror mirror, Library owningLibrary) : super(mirror) {
+    owner = owningLibrary;
+    returnType = getDocgenObject(mirror.value.returnType).docName;
+    generics = _createGenerics(mirror);
+    parameters = _createParameters(mirror.value.parameters, owningLibrary);
+    annotations = _createAnnotations(mirror, owningLibrary);
   }
 
   Map toMap() => {
@@ -1348,16 +1613,27 @@
   bool isConst;
   Type type;
   String _variableName;
+  Indexable owner;
 
   /// List of the meta annotations on the variable.
   List<Annotation> annotations;
 
-  Variable(this._variableName, VariableMirror mirror) : super(mirror) {
-    this.isFinal = mirror.isFinal;
-    this.isStatic = mirror.isStatic;
-    this.isConst = mirror.isConst;
-    this.type = _createType(mirror.type);
-    this.annotations = _createAnnotations(mirror);
+  factory Variable(String variableName, VariableMirror mirror,
+      Indexable owner) {
+    var variable = getDocgenObject(mirror);
+    if (variable is DummyMirror) {
+      return new Variable._(variableName, mirror, owner);
+    }
+    return variable;
+  }
+
+  Variable._(this._variableName, VariableMirror mirror, this.owner) :
+      super(mirror) {
+    isFinal = mirror.isFinal;
+    isStatic = mirror.isStatic;
+    isConst = mirror.isConst;
+    type = new Type(mirror.type, _getOwningLibrary(owner));
+    annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
   }
 
   String get name => _variableName;
@@ -1374,35 +1650,36 @@
     'annotations': annotations.map((a) => a.toMap()).toList()
   };
 
+  String get packagePrefix => owner.packagePrefix;
+
   String get typeName => 'property';
 
   get comment {
     if (_comment != null) return _comment;
-    var owningClass = owningEntity;
-    if (owningClass is Class) {
-      owningClass.ensureComments();
+    if (owner is Class) {
+      (owner as Class).ensureComments();
     }
     return super.comment;
   }
-}
 
-class ExportedVariable extends Variable implements Exported {
-  Library _exportingLibrary;
+  markdown.Node fixReferenceWithScope(String name) => fixReference(name);
 
-  ExportedVariable(String variableName, VariableMirror originalVariable,
-      Library this._exportingLibrary) : super(variableName, originalVariable);
+  String findElementInScope(String name) {
+    var lookupFunc = Indexable.determineLookupFunc(name);
+    var result = lookupFunc(mirror, name);
+    if (result != null) {
+      result = getDocgenObject(result);
+      if (result is DummyMirror) return packagePrefix + result.docName;
+      return result.packagePrefix + result.docName;
+    }
 
-  String get fileName => path.join(_exportingLibrary.packageName,
-          _exportingLibrary.mirror.qualifiedName + '.' + super.name);
-
-  void updateExports(Map<String, Indexable> libraryExports) {
-    // TODO(efortuna): if this class points to another exported class or type
-    // of some sort, then that reference needs to be updated here.
-    /* these need to be updated:
-    'comment': comment,
-    'type': new List.filled(1, type.toMap()),
-    'annotations': annotations.map((a) => a.toMap()).toList()
-    */
+    if (owner != null) {
+      var result = owner.findElementInScope(name);
+      if (result != null) {
+        return result;
+      }
+    }
+    return super.findElementInScope(name);
   }
 }
 
@@ -1420,6 +1697,7 @@
   bool isSetter;
   bool isOperator;
   Type returnType;
+  Method methodInheritedFrom;
 
   /// Qualified name to state where the comment is inherited from.
   String commentInheritedFrom = "";
@@ -1427,25 +1705,85 @@
   /// List of the meta annotations on the method.
   List<Annotation> annotations;
 
-  Method(MethodMirror mirror) : super(mirror) {
+  Indexable owner;
+
+  factory Method(MethodMirror mirror, Indexable owner, // Indexable newOwner.
+      [Method methodInheritedFrom]) {
+    var method = getDocgenObject(mirror, owner);
+    if (method is DummyMirror) {
+      method = new Method._(mirror, owner, methodInheritedFrom);
+    }
+    return method;
+  }
+
+  Method._(MethodMirror mirror, this.owner, this.methodInheritedFrom)
+      : super(mirror) {
     this.isStatic = mirror.isStatic;
     this.isAbstract = mirror.isAbstract;
     this.isConst = mirror.isConstConstructor;
-    this.returnType = _createType(mirror.returnType);
-    this.parameters = _createParameters(mirror.parameters);
-    this.annotations = _createAnnotations(mirror);
+    this.returnType = new Type(mirror.returnType, _getOwningLibrary(owner));
+    this.parameters = _createParameters(mirror.parameters, owner);
+    this.annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
     this.isConstructor = mirror.isConstructor;
     this.isGetter = mirror.isGetter;
     this.isSetter = mirror.isSetter;
     this.isOperator = mirror.isOperator;
   }
 
+  String get packagePrefix => owner.packagePrefix;
+
+  Method get originallyInheritedFrom => methodInheritedFrom == null ?
+      this : methodInheritedFrom.originallyInheritedFrom;
+
+  markdown.Node fixReferenceWithScope(String name) => fixReference(name);
+
+  /// Look for the specified name starting with the current member, and
+  /// progressively working outward to the current library scope.
+  String findElementInScope(String name) {
+    var lookupFunc = Indexable.determineLookupFunc(name);
+
+    var memberScope = lookupFunc(this.mirror, name);
+    if (memberScope != null) {
+      // do we check for a dummy mirror returned here and look up with an owner
+      // higher ooooor in getDocgenObject do we include more things in our
+      // lookup
+      var result = getDocgenObject(memberScope, owner);
+      if (result is DummyMirror && owner.owner != null
+          && owner.owner is! DummyMirror) {
+        var aresult = getDocgenObject(memberScope, owner.owner);
+        if (aresult is! DummyMirror) result = aresult;
+      }
+      if (result is DummyMirror) return packagePrefix + result.docName;
+      return result.packagePrefix + result.docName;
+    }
+
+    if (owner != null) {
+      var result = owner.findElementInScope(name);
+      if (result != null) return result;
+    }
+    return super.findElementInScope(name);
+  }
+
+  String get docName {
+    if ((mirror as MethodMirror).isConstructor) {
+      // We name constructors specially -- including the class name again and a
+      // "-" to separate the constructor from its name (if any).
+      return '${owner.docName}.${mirror.owner.simpleName}-${mirror.simpleName}';
+    }
+    return super.docName;
+  }
+
+  String get fileName => packagePrefix + docName;
+
   /// Makes sure that the method with an inherited equivalent have comments.
   void ensureCommentFor(Method inheritedMethod) {
     if (comment.isNotEmpty) return;
-    comment = inheritedMethod._commentToHtml(mirror);
+
+    comment = inheritedMethod._commentToHtml(this);
+    _unresolvedComment = inheritedMethod._unresolvedComment;
     commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
-        inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
+        new DummyMirror(inheritedMethod.mirror).docName :
+        inheritedMethod.commentInheritedFrom;
   }
 
   /// Generates a map describing the [Method] object.
@@ -1453,7 +1791,11 @@
     'name': name,
     'qualifiedName': qualifiedName,
     'comment': comment,
-    'commentFrom': commentInheritedFrom,
+    'commentFrom': (methodInheritedFrom != null &&
+        commentInheritedFrom == methodInheritedFrom.docName ? ''
+        : commentInheritedFrom),
+    'inheritedFrom': (methodInheritedFrom == null? '' :
+        originallyInheritedFrom.docName),
     'static': isStatic.toString(),
     'abstract': isAbstract.toString(),
     'constant': isConst.toString(),
@@ -1468,139 +1810,47 @@
 
   get comment {
     if (_comment != null) return _comment;
-    var owningClass = owningEntity;
-    if (owningClass is Class) {
-      owningClass.ensureComments();
+    if (owner is Class) {
+      (owner as Class).ensureComments();
     }
-    return super.comment;
+    var result = super.comment;
+    if (result == '' && methodInheritedFrom != null) {
+      // this should be NOT from the MIRROR, but from the COMMENT
+      _unresolvedComment = methodInheritedFrom._unresolvedComment;
+
+      var linkResolver = (name) => fixReferenceWithScope(name);
+      comment = _unresolvedComment == null ? '' :
+        markdown.markdownToHtml(_unresolvedComment.trim(),
+            linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
+      commentInheritedFrom = methodInheritedFrom.commentInheritedFrom;
+      result = comment;
+    }
+    return result;
   }
 }
 
-class ExportedMethod extends Method implements Exported {
-  Library _exportingLibrary;
-
-  ExportedMethod(MethodMirror originalMethod, Library this._exportingLibrary) :
-      super(originalMethod);
-
-  // TODO(efortuna): Refactor this code so the exported items can share this
-  // behavior.
-  String get fileName => path.join(_exportingLibrary.packageName,
-      _exportingLibrary.mirror.qualifiedName + '.' + super.name);
-
-  void updateExports(Map<String, Indexable> libraryExports) {
-    // TODO(efortuna): if this class points to another exported class or type
-    // of some sort, then that reference needs to be updated here.
-    /* these need to be updated:
-    'qualifiedName': qualifiedName,
-    'comment': comment,
-    'commentFrom': commentInheritedFrom,
-    'return': new List.filled(1, returnType.toMap()),
-    'parameters': recurseMap(parameters),
-    'annotations': annotations.map((a) => a.toMap()).toList()
-    */
-  }
-}
-
-
-
-/// A container to categorize methods into the following groups: setters,
-/// getters, constructors, operators, regular methods.
-class MethodGroup {
-  Map<String, Method> setters = {};
-  Map<String, Method> getters = {};
-  Map<String, Method> constructors = {};
-  Map<String, Method> operators = {};
-  Map<String, Method> regularMethods = {};
-
-  Map<String, Exported> get exported {
-    var exported = {};
-    for (Map<String, Method> group in [setters, getters, constructors,
-      operators, regularMethods]) {
-      exported = _filterMap(exported, group,
-          (value) => value is ExportedMethod);
-    }
-    return exported;
-  }
-
-  /// The optional parameter [containingLibrary] is contains data for variables
-  /// defined at the top level of a library (potentially for exporting
-  /// purposes).
-  void addMethod(MethodMirror mirror, [Library containingLibrary]) {
-    var method;
-    if (containingLibrary != null && mirror.owner.qualifiedName !=
-        containingLibrary.mirror.qualifiedName) {
-      method = new ExportedMethod(mirror, containingLibrary);
-    } else {
-      method = new Method(mirror);
-    }
-    entityMap[docName(mirror)] = method;
-    if (mirror.isSetter) {
-      setters[mirror.simpleName] = method;
-    } else if (mirror.isGetter) {
-      getters[mirror.simpleName] = method;
-    } else if (mirror.isConstructor) {
-      constructors[mirror.simpleName] = method;
-    } else if (mirror.isOperator) {
-      operators[mirror.simpleName] = method;
-    } else if (mirror.isRegularMethod) {
-      regularMethods[mirror.simpleName] = method;
-    } else {
-      throw new ArgumentError('${mirror.simpleName} - no method type match');
-    }
-  }
-
-  void addInherited(Class parent) {
-    setters.addAll(parent.inheritedMethods.setters);
-    setters.addAll(_filterStatics(parent.methods.setters));
-    getters.addAll(parent.inheritedMethods.getters);
-    getters.addAll(_filterStatics(parent.methods.getters));
-    operators.addAll(parent.inheritedMethods.operators);
-    operators.addAll(_filterStatics(parent.methods.operators));
-    regularMethods.addAll(parent.inheritedMethods.regularMethods);
-    regularMethods.addAll(_filterStatics(parent.methods.regularMethods));
-  }
-
-  Map toMap() => {
-    'setters': recurseMap(setters),
-    'getters': recurseMap(getters),
-    'constructors': recurseMap(constructors),
-    'operators': recurseMap(operators),
-    'methods': recurseMap(regularMethods)
-  };
-
-  Method operator [](String qualifiedName) {
-    if (setters.containsKey(qualifiedName)) return setters[qualifiedName];
-    if (getters.containsKey(qualifiedName)) return getters[qualifiedName];
-    if (operators.containsKey(qualifiedName)) return operators[qualifiedName];
-    if (regularMethods.containsKey(qualifiedName)) {
-      return regularMethods[qualifiedName];
-    }
-    return null;
-  }
-
-  void forEach(void f(String key, Method value)) {
-    setters.forEach(f);
-    getters.forEach(f);
-    operators.forEach(f);
-    regularMethods.forEach(f);
-  }
-}
-
-/// A class containing properties of a Dart method/function parameter.
-class Parameter {
-
+/// Docgen wrapper around the dart2js mirror for a Dart
+/// method/function parameter.
+class Parameter extends MirrorBased {
+  ParameterMirror mirror;
   String name;
   bool isOptional;
   bool isNamed;
   bool hasDefaultValue;
   Type type;
   String defaultValue;
-
   /// List of the meta annotations on the parameter.
   List<Annotation> annotations;
 
-  Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue,
-      this.type, this.defaultValue, this.annotations);
+  Parameter(this.mirror, Library owningLibrary) {
+    name = mirror.simpleName;
+    isOptional = mirror.isOptional;
+    isNamed = mirror.isNamed;
+    hasDefaultValue = mirror.hasDefaultValue;
+    defaultValue = mirror.defaultValue;
+    type = new Type(mirror.type, owningLibrary);
+    annotations = _createAnnotations(mirror, owningLibrary);
+  }
 
   /// Generates a map describing the [Parameter] object.
   Map toMap() => {
@@ -1614,20 +1864,18 @@
   };
 }
 
-/// A class containing properties of a Generic.
-class Generic {
-  String name;
-  String type;
-
-  Generic(this.name, this.type);
-
+/// A Docgen wrapper around the dart2js mirror for a generic type.
+class Generic extends MirrorBased {
+  TypeVariableMirror mirror;
+  Generic(this.mirror);
   Map toMap() => {
-    'name': name,
-    'type': type
+    'name': mirror.toString(),
+    'type': mirror.upperBound.qualifiedName
   };
 }
 
-/// Holds the name of a return type, and its generic type parameters.
+/// Docgen wrapper around the mirror for a return type, and/or its generic
+/// type parameters.
 ///
 /// Return types are of a form [outer]<[inner]>.
 /// If there is no [inner] part, [inner] will be an empty list.
@@ -1655,56 +1903,50 @@
 ///                  "inner" :
 ///                    - "outer" : "dart-core.int"
 ///                      "inner" :
-class Type {
-  String outer;
-  List<Type> inner;
+class Type extends MirrorBased {
+  TypeMirror mirror;
+  MirrorBased owningLibrary;
 
-  Type(this.outer, this.inner);
+  Type(this.mirror, this.owningLibrary);
+
+  /// Returns a list of [Type] objects constructed from TypeMirrors.
+  List<Type> _createTypeGenerics(TypeMirror mirror) {
+    if (mirror is ClassMirror && !mirror.isTypedef) {
+      var innerList = [];
+      mirror.typeArguments.forEach((e) {
+        innerList.add(new Type(e, owningLibrary));
+      });
+      return innerList;
+    }
+    return [];
+  }
 
   Map toMap() => {
-    'outer': outer,
-    'inner': inner.map((e) => e.toMap()).toList()
+    // We may encounter types whose corresponding library has not been
+    // processed yet, so look up with the owningLibrary at the last moment.
+    'outer': getDocgenObject(mirror, owningLibrary).docName,
+    'inner': _createTypeGenerics(mirror).map((e) => e.toMap()).toList(),
   };
 }
 
 /// Holds the name of the annotation, and its parameters.
-class Annotation {
-  String qualifiedName;
+class Annotation extends MirrorBased {
   List<String> parameters;
+  /// The class of this annotation.
+  ClassMirror mirror;
+  Library owningLibrary;
 
-  Annotation(this.qualifiedName, this.parameters);
+  Annotation(InstanceMirror originalMirror, this.owningLibrary) {
+    mirror = originalMirror.type;
+    parameters = originalMirror.type.variables.values
+        .where((e) => e.isFinal)
+        .map((e) => originalMirror.getField(e.simpleName).reflectee)
+        .where((e) => e != null)
+        .toList();
+  }
 
   Map toMap() => {
-    'name': qualifiedName,
+    'name': getDocgenObject(mirror, owningLibrary).docName,
     'parameters': parameters
   };
-}
-
-/// Given a mirror, returns its qualified name, but following the conventions
-/// we're using in Dartdoc, which is that library names with dots in them
-/// have them replaced with hyphens.
-String docName(DeclarationMirror m) {
-  if (m is LibraryMirror) {
-    return m.qualifiedName.replaceAll('.','-');
-  }
-  var owner = m.owner;
-  if (owner == null) return m.qualifiedName;
-  var simpleName = m.simpleName;
-  if (m is MethodMirror && m.isConstructor) {
-    // We name constructors specially -- including the class name again and a
-    // "-" to separate the constructor from its name (if any).
-    simpleName = '${owner.simpleName}-$simpleName';
-  }
-  return docName(owner) + '.' + simpleName;
-}
-
-/// Remove statics from the map of inherited items before adding them.
-Map _filterStatics(Map items) {
-  var result = {};
-  items.forEach((name, item) {
-    if (!item.isStatic) {
-      result[name] = item;
-    }
-  });
-  return result;
-}
+}
\ No newline at end of file
diff --git a/pkg/docgen/test/multi_library_test.dart b/pkg/docgen/test/multi_library_test.dart
new file mode 100644
index 0000000..1346de8
--- /dev/null
+++ b/pkg/docgen/test/multi_library_test.dart
@@ -0,0 +1,174 @@
+library single_library_test;
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import '../lib/docgen.dart';
+
+const String DART_LIBRARY_1 = '''
+  library testLib;
+  import 'temp2.dart';
+  import 'temp3.dart';
+  export 'temp2.dart';
+  export 'temp3.dart';
+
+  /**
+   * Doc comment for class [A].
+   *
+   * Multiline Test
+   */
+  /*
+   * Normal comment for class A.
+   */
+  class A {
+
+    int _someNumber;
+
+    A() {
+      _someNumber = 12;
+    }
+
+    A.customConstructor();
+
+    /**
+     * Test for linking to parameter [A]
+     */
+    void doThis(int A) {
+      print(A);
+    }
+  }
+''';
+
+const String DART_LIBRARY_2 = '''
+  library testLib2.foo;
+  import 'temp.dart';
+
+  /**
+   * Doc comment for class [B].
+   *
+   * Multiline Test
+   */
+
+  /*
+   * Normal comment for class B.
+   */
+  class B extends A {
+
+    B();
+    B.fooBar();
+
+    /**
+     * Test for linking to super
+     */
+    int doElse(int b) {
+      print(b);
+    }
+
+    /**
+     * Test for linking to parameter [c]
+     */
+    void doThis(int c) {
+      print(a);
+    }
+  }
+
+  int testFunc(int a) {
+  }
+''';
+
+const String DART_LIBRARY_3 = '''
+  library testLib.bar;
+  import 'temp.dart';
+
+  /*
+   * Normal comment for class C.
+   */
+  class C {
+  }
+''';
+
+Directory TEMP_DIRNAME;
+
+List writeLibFiles() {
+  TEMP_DIRNAME = Directory.systemTemp.createTempSync('single_library_');
+  var fileName = path.join(TEMP_DIRNAME.path, 'temp.dart');
+  var file = new File(fileName);
+  file.writeAsStringSync(DART_LIBRARY_1);
+
+  var fileName2 = path.join(TEMP_DIRNAME.path, 'temp2.dart');
+  file = new File(fileName2);
+  file.writeAsStringSync(DART_LIBRARY_2);
+
+  var fileName3 = path.join(TEMP_DIRNAME.path, 'temp3.dart');
+  file = new File(fileName3);
+  file.writeAsStringSync(DART_LIBRARY_3);
+  return [new Uri.file(fileName), new Uri.file(fileName3),
+      new Uri.file(fileName3)];
+}
+
+main() {
+  group('Generate docs for', () {
+    test('multiple libraries.', () {
+      var files = writeLibFiles();
+      getMirrorSystem(files)
+        .then(expectAsync1((mirrorSystem) {
+          var testLibraryUri = files[0];
+          var library = new Library(mirrorSystem.libraries[testLibraryUri]);
+
+          /// Testing fixReference
+          // Testing Doc comment for class [B].
+          var libraryMirror = mirrorSystem.libraries[testLibraryUri];
+          var classDocComment = library.fixReference('B').children.first.text;
+          expect(classDocComment, 'testLib.B');
+
+          // Test for linking to parameter [c]
+          var importedLib = libraryMirror.libraryDependencies.firstWhere(
+            (dep) => dep.isImport).targetLibrary;
+          var aClassMirror = importedLib.classes.values.first;
+          expect(aClassMirror.qualifiedName, 'testLib2.foo.B');
+          var exportedClass = getDocgenObject(aClassMirror, library);
+          expect(exportedClass is Class, isTrue);
+
+
+          var method = exportedClass.methods['doThis'];
+          expect(method is Method, isTrue);
+          var methodParameterDocComment = method.fixReference(
+              'c').children.first.text;
+          expect(methodParameterDocComment, 'testLib.B.doThis.c');
+
+
+          expect(method.fixReference('A').children.first.text, 'testLib.A');
+          // Testing trying to refer to doThis function
+          expect(method.fixReference('doThis').children.first.text,
+              'testLib.B.doThis');
+
+          // Testing trying to refer to doThis function
+          expect(method.fixReference('doElse').children.first.text,
+              'testLib.B.doElse');
+
+
+          // Test a third library referencing another exported library in a
+          // separate file.
+          importedLib = libraryMirror.libraryDependencies.firstWhere(
+            (dep) => dep.isImport && dep.targetLibrary.qualifiedName ==
+            'testLib.bar').targetLibrary;
+          aClassMirror = importedLib.classes.values.first;
+          expect(aClassMirror.qualifiedName, 'testLib.bar.C');
+          exportedClass = getDocgenObject(aClassMirror, library);
+          expect(exportedClass is Class, isTrue);
+          expect(exportedClass.docName, 'testLib.C');
+
+          methodParameterDocComment = exportedClass.fixReference(
+              'B').children.first.text;
+          expect(methodParameterDocComment, 'testLib.B');
+
+          methodParameterDocComment = exportedClass.fixReference(
+              'testFunc').children.first.text;
+          expect(methodParameterDocComment, 'testLib.testFunc');
+
+        })).whenComplete(() => TEMP_DIRNAME.deleteSync(recursive: true));
+    });
+  });
+}
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index 12cd6b6..ed30818 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -50,33 +50,27 @@
         .then(expectAsync1((mirrorSystem) {
           var testLibraryUri = new Uri(scheme: 'file',
               path: path.absolute(fileName));
-          var library = generateLibrary(mirrorSystem.libraries[testLibraryUri]);
+          var library = new Library(mirrorSystem.libraries[testLibraryUri]);
           expect(library is Library, isTrue);
 
           var classTypes = library.classes;
-          expect(classTypes is ClassGroup, isTrue);
-
           var classes = [];
-          classes.addAll(classTypes.classes.values);
-          classes.addAll(classTypes.errors.values);
+          classes.addAll(classTypes.values);
+          classes.addAll(library.errors.values);
           expect(classes.every((e) => e is Class), isTrue);
 
-          expect(classTypes.typedefs.values.every((e) => e is Typedef), isTrue);
+          expect(library.typedefs.values.every((e) => e is Typedef), isTrue);
 
           var classMethodTypes = [];
           classes.forEach((e) {
             classMethodTypes.add(e.methods);
             classMethodTypes.add(e.inheritedMethods);
           });
-          expect(classMethodTypes.every((e) => e is MethodGroup), isTrue);
+          expect(classMethodTypes.every((e) => e is Map<String, Method>), isTrue);
 
           var classMethods = [];
           classMethodTypes.forEach((e) {
-            classMethods.addAll(e.setters.values);
-            classMethods.addAll(e.getters.values);
-            classMethods.addAll(e.constructors.values);
-            classMethods.addAll(e.operators.values);
-            classMethods.addAll(e.regularMethods.values);
+            classMethods.addAll(e.values);
           });
           expect(classMethods.every((e) => e is Method), isTrue);
 
@@ -87,14 +81,10 @@
           expect(methodParameters.every((e) => e is Parameter), isTrue);
 
           var functionTypes = library.functions;
-          expect(functionTypes is MethodGroup, isTrue);
+          expect(functionTypes is Map<String, Method>, isTrue);
 
           var functions = [];
-          functions.addAll(functionTypes.setters.values);
-          functions.addAll(functionTypes.getters.values);
-          functions.addAll(functionTypes.constructors.values);
-          functions.addAll(functionTypes.operators.values);
-          functions.addAll(functionTypes.regularMethods.values);
+          functions.addAll(functionTypes.values);
           expect(functions.every((e) => e is Method), isTrue);
 
           var functionParameters = [];
@@ -110,26 +100,23 @@
           // Testing Doc comment for class [A].
           var libraryMirror = mirrorSystem.libraries[testLibraryUri];
           var classMirror = libraryMirror.classes.values.first;
-          var classDocComment = fixReference('A', libraryMirror,
-              classMirror, null).children.first.text;
-          expect(classDocComment == 'test.A', isTrue);
+          var classDocComment = library.fixReference('A').children.first.text;
+          expect(classDocComment, 'test.A');
 
           // Test for linking to parameter [A]
-          var methodMirror = classMirror.methods['doThis'];
-          var methodParameterDocComment = fixReference('A', libraryMirror,
-              classMirror, methodMirror).children.first.text;
-          // TODO(alanknight) : We're not supporting linking to parameters yet
-          // expect(methodParameterDocComment == 'test.A.doThis#A', isTrue);
+          var method = getDocgenObject(classMirror.methods['doThis']);
+          var methodParameterDocComment = method.fixReference(
+              'A').children.first.text;
+          expect(methodParameterDocComment, 'test.A.doThis.A');
 
           // Testing trying to refer to doThis function
-          var methodDocComment = fixReference('doThis', libraryMirror,
-              classMirror, methodMirror).children.first.text;
-          expect(methodDocComment == 'test.A.doThis', isTrue);
+          var methodDocComment = method.fixReference(
+              'doThis').children.first.text;
+          expect(methodDocComment, 'test.A.doThis');
 
           // Testing something with no reference
-          var libraryDocComment = fixReference('foobar', libraryMirror,
-              classMirror, methodMirror).text;
-          expect(libraryDocComment == 'foobar', isTrue);
+          var libraryDocComment = method.fixReference('foobar').text;
+          expect(libraryDocComment, 'foobar');
         })).whenComplete(() => temporaryDir.deleteSync(recursive: true));
     });
   });
diff --git a/pkg/expect/LICENSE b/pkg/expect/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/expect/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/fixnum/LICENSE b/pkg/fixnum/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/fixnum/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/html_import/LICENSE b/pkg/html_import/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/html_import/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/http/LICENSE b/pkg/http/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/http/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/http/lib/src/base_request.dart b/pkg/http/lib/src/base_request.dart
index e75ef15..f54e757 100644
--- a/pkg/http/lib/src/base_request.dart
+++ b/pkg/http/lib/src/base_request.dart
@@ -122,7 +122,7 @@
     });
   }
 
-  /// Throws an error if this request has been finalized.
+  // Throws an error if this request has been finalized.
   void _checkFinalized() {
     if (!finalized) return;
     throw new StateError("Can't modify a finalized Request.");
diff --git a/pkg/http/lib/src/io_client.dart b/pkg/http/lib/src/io_client.dart
index b4fa893..c12cac2 100644
--- a/pkg/http/lib/src/io_client.dart
+++ b/pkg/http/lib/src/io_client.dart
@@ -27,10 +27,11 @@
 
     return Chain.track(_inner.openUrl(request.method, request.url))
         .then((ioRequest) {
-      ioRequest.followRedirects = request.followRedirects;
-      ioRequest.maxRedirects = request.maxRedirects;
-      ioRequest.contentLength = request.contentLength;
-      ioRequest.persistentConnection = request.persistentConnection;
+      ioRequest
+          ..followRedirects = request.followRedirects
+          ..maxRedirects = request.maxRedirects
+          ..contentLength = request.contentLength
+          ..persistentConnection = request.persistentConnection;
       request.headers.forEach((name, value) {
         ioRequest.headers.set(name, value);
       });
diff --git a/pkg/http/lib/src/mock_client.dart b/pkg/http/lib/src/mock_client.dart
index b81bf06..5d29545 100644
--- a/pkg/http/lib/src/mock_client.dart
+++ b/pkg/http/lib/src/mock_client.dart
@@ -33,13 +33,13 @@
   MockClient(MockClientHandler fn)
     : this._((baseRequest, bodyStream) {
       return bodyStream.toBytes().then((bodyBytes) {
-        var request = new Request(baseRequest.method, baseRequest.url);
-        request.persistentConnection = baseRequest.persistentConnection;
-        request.followRedirects = baseRequest.followRedirects;
-        request.maxRedirects = baseRequest.maxRedirects;
-        request.headers.addAll(baseRequest.headers);
-        request.bodyBytes = bodyBytes;
-        request.finalize();
+        var request = new Request(baseRequest.method, baseRequest.url)
+            ..persistentConnection = baseRequest.persistentConnection
+            ..followRedirects = baseRequest.followRedirects
+            ..maxRedirects = baseRequest.maxRedirects
+            ..headers.addAll(baseRequest.headers)
+            ..bodyBytes = bodyBytes
+            ..finalize();
 
         return fn(request);
       }).then((response) {
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index d3a4307..f08e962 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -6,7 +6,6 @@
 
 import 'dart:async';
 import 'dart:convert';
-import 'dart:io';
 import 'dart:typed_data';
 
 import 'package:stack_trace/stack_trace.dart';
@@ -199,22 +198,5 @@
   future.then(completer.complete, onError: completer.completeError);
 }
 
-// TOOD(nweiz): Get rid of this once https://codereview.chromium.org/11293132/
-// is in.
-/// Runs [fn] for each element in [input] in order, moving to the next element
-/// only when the [Future] returned by [fn] completes. Returns a [Future] that
-/// completes when all elements have been processed.
-///
-/// The return values of all [Future]s are discarded. Any errors will cause the
-/// iteration to stop and will be piped through the return value.
-Future forEachFuture(Iterable input, Future fn(element)) {
-  var iterator = input.iterator;
-  Future nextElement(_) {
-    if (!iterator.moveNext()) return new Future.value();
-    return fn(iterator.current).then(nextElement);
-  }
-  return nextElement(null);
-}
-
 /// Like [Future.sync], but wraps the Future in [Chain.track] as well.
 Future syncFuture(callback()) => Chain.track(new Future.sync(callback));
diff --git a/pkg/http/pubspec.yaml b/pkg/http/pubspec.yaml
index d3c751b..03288ec 100644
--- a/pkg/http/pubspec.yaml
+++ b/pkg/http/pubspec.yaml
@@ -1,5 +1,5 @@
 name: http
-version: 0.9.2
+version: 0.9.2+3
 author: "Dart Team <misc@dartlang.org>"
 homepage: https://pub.dartlang.org/packages/http
 description: A composable, Future-based API for making HTTP requests.
@@ -9,4 +9,4 @@
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.1.0 <2.0.0"
diff --git a/pkg/http/test/safe_http_server.dart b/pkg/http/test/safe_http_server.dart
deleted file mode 100644
index 9c3622d..0000000
--- a/pkg/http/test/safe_http_server.dart
+++ /dev/null
@@ -1,150 +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 safe_http_server;
-
-import 'dart:async';
-import 'dart:io';
-
-// TODO(nweiz): remove this when issue 9140 is fixed.
-/// A wrapper around [HttpServer] that swallows errors caused by requests
-/// behaving badly. This provides the following guarantees:
-///
-/// * The [SafeHttpServer.listen] onError callback will only emit server-wide
-///   errors. It will not emit errors for requests that were unparseable or
-///   where the connection was closed too soon.
-/// * [HttpResponse.done] will emit no errors.
-///
-/// The [HttpRequest] data stream can still emit errors.
-class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
-  final HttpServer _inner;
-
-  static Future<SafeHttpServer> bind([String host = "localhost",
-      int port = 0, int backlog = 0]) {
-    return HttpServer.bind(host, port, backlog: backlog)
-        .then((server) => new SafeHttpServer(server));
-  }
-
-  SafeHttpServer(HttpServer server)
-      : super(server),
-        _inner = server;
-
-  Future close({bool force: false}) => _inner.close(force: force);
-
-  InternetAddress get address => _inner.address;
-  int get port => _inner.port;
-
-  set sessionTimeout(int timeout) {
-    _inner.sessionTimeout = timeout;
-  }
-
-  HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
-
-  StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
-      {Function onError, void onDone(),
-      bool cancelOnError: false}) {
-    var subscription;
-    subscription = super.listen((request) {
-      onData(new _HttpRequestWrapper(request));
-    }, onError: (error, StackTrace stackTrace) {
-      // Ignore socket error 104, which is caused by a request being cancelled
-      // before it writes any headers. There's no reason to care about such
-      // requests.
-      if (error is SocketException && error.osError.errorCode == 104) return;
-      // Ignore any parsing errors, which come from malformed requests.
-      if (error is HttpException) return;
-      // Manually handle cancelOnError so the above (ignored) errors don't
-      // cause unsubscription.
-      if (cancelOnError) subscription.cancel();
-      if (onError != null) {
-        if (onError is ZoneBinaryCallback) {
-          onError(error, stackTrace);
-        } else {
-          onError(error);
-        }
-      }
-    }, onDone: onDone);
-    return subscription;
-  }
-}
-
-/// A wrapper around [HttpRequest] for the sole purpose of swallowing errors on
-/// [HttpResponse.done].
-class _HttpRequestWrapper extends StreamView<List<int>> implements HttpRequest {
-  final HttpRequest _inner;
-  final HttpResponse response;
-
-  _HttpRequestWrapper(HttpRequest inner)
-      : super(inner),
-        _inner = inner,
-        response = new _HttpResponseWrapper(inner.response);
-
-  int get contentLength => _inner.contentLength;
-  String get method => _inner.method;
-  Uri get uri => _inner.uri;
-  HttpHeaders get headers => _inner.headers;
-  List<Cookie> get cookies => _inner.cookies;
-  bool get persistentConnection => _inner.persistentConnection;
-  X509Certificate get certificate => _inner.certificate;
-  HttpSession get session => _inner.session;
-  String get protocolVersion => _inner.protocolVersion;
-  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
-}
-
-/// A wrapper around [HttpResponse] for the sole purpose of swallowing errors on
-/// [done].
-class _HttpResponseWrapper implements HttpResponse {
-  final HttpResponse _inner;
-  Future<HttpResponse> _done;
-
-  _HttpResponseWrapper(this._inner);
-
-  /// Swallows all errors from writing to the response.
-  Future<HttpResponse> get done {
-    if (_done == null) _done = _inner.done.catchError((_) {});
-    return _done;
-  }
-
-  int get contentLength => _inner.contentLength;
-  set contentLength(int value) {
-    _inner.contentLength = value;
-  }
-
-  int get statusCode => _inner.statusCode;
-  set statusCode(int value) {
-    _inner.statusCode = value;
-  }
-
-  String get reasonPhrase => _inner.reasonPhrase;
-  set reasonPhrase(String value) {
-    _inner.reasonPhrase = value;
-  }
-
-  bool get persistentConnection => _inner.persistentConnection;
-  set persistentConnection(bool value) {
-    _inner.persistentConnection = value;
-  }
-
-  Encoding get encoding => _inner.encoding;
-  set encoding(Encoding value) {
-    _inner.encoding = value;
-  }
-
-  HttpHeaders get headers => _inner.headers;
-  List<Cookie> get cookies => _inner.cookies;
-  Future<Socket> detachSocket() => _inner.detachSocket();
-  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
-  void add(List<int> data) => _inner.add(data);
-  Future<HttpResponse> addStream(Stream<List<int>> stream) =>
-    _inner.addStream(stream);
-  Future close() => _inner.close();
-  Future flush() => _inner.flush();
-  void write(Object obj) => _inner.write(obj);
-  void writeAll(Iterable objects, [String separator = ""]) =>
-    _inner.writeAll(objects, separator);
-  void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
-  void writeln([Object obj = ""]) => _inner.writeln(obj);
-  void addError(error, [StackTrace stackTrace]) =>
-      _inner.addError(error, stackTrace);
-}
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index f93ca25..3797bd1 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -12,8 +12,6 @@
 import 'package:http/src/utils.dart';
 import 'package:unittest/unittest.dart';
 
-import 'safe_http_server.dart';
-
 /// The current server instance.
 HttpServer _server;
 
@@ -25,7 +23,7 @@
 
 /// Starts a new HTTP server.
 Future startServer() {
-  return SafeHttpServer.bind("localhost", 0).then((s) {
+  return HttpServer.bind("localhost", 0).then((s) {
     _server = s;
     s.listen((request) {
       var path = request.uri.path;
diff --git a/pkg/http_server/LICENSE b/pkg/http_server/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/http_server/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/http_server/lib/src/virtual_directory.dart b/pkg/http_server/lib/src/virtual_directory.dart
index 88a9d50..6eef0b4 100644
--- a/pkg/http_server/lib/src/virtual_directory.dart
+++ b/pkg/http_server/lib/src/virtual_directory.dart
@@ -4,6 +4,15 @@
 
 part of http_server;
 
+
+// Used for signal a directory redirecting, where a tailing slash is missing.
+class _DirectoryRedirect {
+  const _DirectoryRedirect();
+}
+
+typedef dynamic _DirCallback(Directory dir, HttpRequest request);
+typedef dynamic _ErrorCallback(HttpRequest request);
+
 /**
  * A [VirtualDirectory] can serve files and directory-listing from a root path,
  * to [HttpRequest]s.
@@ -34,8 +43,8 @@
 
   final RegExp _invalidPathRegExp = new RegExp("[\\\/\x00]");
 
-  Function _errorCallback;
-  Function _dirCallback;
+  _ErrorCallback _errorCallback;
+  _DirCallback _dirCallback;
 
   /*
    * Create a new [VirtualDirectory] for serving static file content of
@@ -49,27 +58,32 @@
   /**
    * Serve a [Stream] of [HttpRequest]s, in this [VirtualDirectory].
    */
-  void serve(Stream<HttpRequest> requests) {
-    requests.listen(serveRequest);
-  }
+  StreamSubscription<HttpRequest> serve(Stream<HttpRequest> requests) =>
+      requests.listen(serveRequest);
 
   /**
    * Serve a single [HttpRequest], in this [VirtualDirectory].
    */
-  void serveRequest(HttpRequest request) {
-    _locateResource('.', request.uri.pathSegments.iterator..moveNext())
+  Future serveRequest(HttpRequest request) {
+    return _locateResource('.', request.uri.pathSegments.iterator..moveNext())
         .then((entity) {
-          if (entity == null) {
-            _serveErrorPage(HttpStatus.NOT_FOUND, request);
-            return;
-          }
           if (entity is File) {
             serveFile(entity, request);
           } else if (entity is Directory) {
-            _serveDirectory(entity, request);
+            if (allowDirectoryListing) {
+              _serveDirectory(entity, request);
+            } else {
+              _serveErrorPage(HttpStatus.NOT_FOUND, request);
+            }
+          } else if (entity is _DirectoryRedirect) {
+            // TODO(ajohnsen): Use HttpRequest.requestedUri once 1.2 is out.
+            request.response.redirect(Uri.parse('${request.uri}/'),
+                                      status: HttpStatus.MOVED_PERMANENTLY);
           } else {
+            assert(entity == null);
             _serveErrorPage(HttpStatus.NOT_FOUND, request);
           }
+          return request.response.done;
         });
   }
 
@@ -90,8 +104,7 @@
     _errorCallback = callback;
   }
 
-  Future<FileSystemEntity> _locateResource(String path,
-                                           Iterator<String> segments) {
+  Future _locateResource(String path, Iterator<String> segments) {
     // Don't allow navigating up paths.
     if (segments.current == "..") return new Future.value(null);
     path = normalize(path);
@@ -108,14 +121,18 @@
               break;
 
             case FileSystemEntityType.DIRECTORY:
-              if (segments.current == null) {
-                if (allowDirectoryListing) {
-                  return new Directory(fullPath());
-                }
+              String dirFullPath() => '${fullPath()}$separator';
+              var current = segments.current;
+              if (current == null) {
+                if (path == '.') return new Directory(dirFullPath());
+                return const _DirectoryRedirect();
+              }
+              bool hasNext = segments.moveNext();
+              if (!hasNext && current == "") {
+                return new Directory(dirFullPath());
               } else {
-                if (_invalidPathRegExp.hasMatch(segments.current)) break;
-                return _locateResource(join(path, segments.current),
-                                       segments..moveNext());
+                if (_invalidPathRegExp.hasMatch(current)) break;
+                return _locateResource(join(path, current), segments);
               }
               break;
 
@@ -162,7 +179,7 @@
           !lastModified.isAfter(request.headers.ifModifiedSince)) {
         response.statusCode = HttpStatus.NOT_MODIFIED;
         response.close();
-        return;
+        return null;
       }
 
       response.headers.set(HttpHeaders.LAST_MODIFIED, lastModified);
@@ -170,7 +187,7 @@
 
       if (request.method == 'HEAD') {
         response.close();
-        return;
+        return null;
       }
 
       return file.length().then((length) {
@@ -204,14 +221,18 @@
             // Pipe the 'range' of the file.
             file.openRead(start, end)
                 .pipe(new _VirtualDirectoryFileStream(response, file.path))
-                .catchError((_) {});
+                .catchError((_) {
+                  // TODO(kevmoo): log errors
+                });
             return;
           }
         }
 
         file.openRead()
             .pipe(new _VirtualDirectoryFileStream(response, file.path))
-            .catchError((_) {});
+            .catchError((_) {
+              // TODO(kevmoo): log errors
+            });
       });
     }).catchError((_) {
       response.statusCode = HttpStatus.NOT_FOUND;
@@ -280,7 +301,6 @@
       }
 
       dir.list(followLinks: true).listen((entity) {
-        // TODO(ajohnsen): Consider async dir listing.
         if (entity is File) {
           var stat = entity.statSync();
           add(basename(entity.path),
@@ -292,11 +312,15 @@
               null);
         }
       }, onError: (e) {
+        // TODO(kevmoo): log error
       }, onDone: () {
         response.write(footer);
         response.close();
       });
-    }, onError: (e) => response.close());
+    }, onError: (e) {
+      // TODO(kevmoo): log error
+      response.close();
+    });
   }
 
   void _serveErrorPage(int error, HttpRequest request) {
@@ -332,7 +356,7 @@
 class _VirtualDirectoryFileStream extends StreamConsumer<List<int>> {
   final HttpResponse response;
   final String path;
-  var buffer = [];
+  List<int> buffer = [];
 
   _VirtualDirectoryFileStream(HttpResponse this.response, String this.path);
 
@@ -377,7 +401,7 @@
 
   Future close() => new Future.value();
 
-  void setMimeType(var bytes) {
+  void setMimeType(List<int> bytes) {
     var mimeType = lookupMimeType(path, headerBytes: bytes);
     if (mimeType != null) {
       response.headers.contentType = ContentType.parse(mimeType);
diff --git a/pkg/http_server/pubspec.yaml b/pkg/http_server/pubspec.yaml
index 2c29396..6511e98 100644
--- a/pkg/http_server/pubspec.yaml
+++ b/pkg/http_server/pubspec.yaml
@@ -1,5 +1,5 @@
 name: http_server
-version: 0.9.1
+version: 0.9.2-dev
 author: Dart Team <misc@dartlang.org>
 description: Library of HTTP server classes.
 homepage: http://www.dartlang.org
diff --git a/pkg/http_server/test/http_mock.dart b/pkg/http_server/test/http_mock.dart
new file mode 100644
index 0000000..aa20ffb
--- /dev/null
+++ b/pkg/http_server/test/http_mock.dart
@@ -0,0 +1,199 @@
+library http_mock;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:io';
+
+class MockHttpHeaders implements HttpHeaders {
+  final Map<String, List<String>> _headers =
+      new HashMap<String, List<String>>();
+
+
+  DateTime get ifModifiedSince {
+    List<String> values = _headers[HttpHeaders.IF_MODIFIED_SINCE];
+    if (values != null) {
+      try {
+        return HttpDate.parse(values[0]);
+      } on Exception catch (e) {
+        return null;
+      }
+    }
+    return null;
+  }
+
+  void set ifModifiedSince(DateTime ifModifiedSince) {
+    // Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT).
+    String formatted = HttpDate.format(ifModifiedSince.toUtc());
+    _set(HttpHeaders.IF_MODIFIED_SINCE, formatted);
+  }
+
+  ContentType contentType;
+
+  void set(String name, Object value) {
+    name = name.toLowerCase();
+    _headers.remove(name);
+    _addAll(name, value);
+  }
+
+  String value(String name) {
+    name = name.toLowerCase();
+    List<String> values = _headers[name];
+    if (values == null) return null;
+    if (values.length > 1) {
+      throw new HttpException("More than one value for header $name");
+    }
+    return values[0];
+  }
+
+  String toString() => '$runtimeType : $_headers';
+
+  // [name] must be a lower-case version of the name.
+  void _add(String name, value) {
+    if (name == HttpHeaders.IF_MODIFIED_SINCE) {
+      if (value is DateTime) {
+        ifModifiedSince = value;
+      } else if (value is String) {
+        _set(HttpHeaders.IF_MODIFIED_SINCE, value);
+      } else {
+        throw new HttpException("Unexpected type for header named $name");
+      }
+    } else {
+      _addValue(name, value);
+    }
+  }
+
+  void _addAll(String name, value) {
+    if (value is List) {
+      for (int i = 0; i < value.length; i++) {
+        _add(name, value[i]);
+      }
+    } else {
+      _add(name, value);
+    }
+  }
+
+  void _addValue(String name, Object value) {
+    List<String> values = _headers[name];
+    if (values == null) {
+      values = new List<String>();
+      _headers[name] = values;
+    }
+    if (value is DateTime) {
+      values.add(HttpDate.format(value));
+    } else {
+      values.add(value.toString());
+    }
+  }
+
+  void _set(String name, String value) {
+    assert(name == name.toLowerCase());
+    List<String> values = new List<String>();
+    _headers[name] = values;
+    values.add(value);
+  }
+
+  /*
+   * Implemented to remove editor warnings
+   */
+  dynamic noSuchMethod(Invocation invocation) {
+    print([invocation.memberName, invocation.isGetter, invocation.isSetter, invocation.isMethod, invocation.isAccessor]);
+    return super.noSuchMethod(invocation);
+  }
+}
+
+class MockHttpRequest implements HttpRequest {
+  final Uri uri;
+  final MockHttpResponse response = new MockHttpResponse();
+  final HttpHeaders headers = new MockHttpHeaders();
+  final String method = 'GET';
+  final bool followRedirects;
+
+  MockHttpRequest(this.uri, {this.followRedirects: true,
+      DateTime ifModifiedSince}) {
+    if(ifModifiedSince != null) {
+      headers.ifModifiedSince = ifModifiedSince;
+    }
+  }
+
+  /*
+   * Implemented to remove editor warnings
+   */
+  dynamic noSuchMethod(Invocation invocation) =>
+      super.noSuchMethod(invocation);
+}
+
+class MockHttpResponse implements HttpResponse {
+  final HttpHeaders headers = new MockHttpHeaders();
+  final Completer _completer = new Completer();
+  final List<int> _buffer = new List<int>();
+  String _reasonPhrase;
+  Future _doneFuture;
+
+  MockHttpResponse() {
+    _doneFuture = _completer.future
+        .whenComplete(() {
+          assert(!_isDone);
+          _isDone = true;
+        });
+  }
+
+  bool _isDone = false;
+
+  int statusCode = HttpStatus.OK;
+
+  String get reasonPhrase => _findReasonPhrase(statusCode);
+
+  void set reasonPhrase(String value) {
+    _reasonPhrase = value;
+  }
+
+  Future get done => _doneFuture;
+
+  Future close() {
+    _completer.complete();
+    return _doneFuture;
+  }
+
+  void add(List<int> data) {
+    _buffer.addAll(data);
+  }
+
+  void addError(error, [StackTrace stackTrace]) {
+    // doesn't seem to be hit...hmm...
+  }
+
+  Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY}) {
+    this.statusCode = status;
+    headers.set(HttpHeaders.LOCATION, location.toString());
+    return close();
+  }
+
+  void write(Object obj) {
+    var str = obj.toString();
+    add(UTF8.encode(str));
+  }
+
+  /*
+   * Implemented to remove editor warnings
+   */
+  dynamic noSuchMethod(Invocation invocation) =>
+      super.noSuchMethod(invocation);
+
+  String get mockContent => UTF8.decode(_buffer);
+
+  bool get mockDone => _isDone;
+
+  // Copied from SDK http_impl.dart @ 845 on 2014-01-05
+  // TODO: file an SDK bug to expose this on HttpStatus in some way
+  String _findReasonPhrase(int statusCode) {
+    if (_reasonPhrase != null) {
+      return _reasonPhrase;
+    }
+
+    switch (statusCode) {
+      case HttpStatus.NOT_FOUND: return "Not Found";
+      default: return "Status $statusCode";
+    }
+  }
+}
diff --git a/pkg/http_server/test/utils.dart b/pkg/http_server/test/utils.dart
index 85fa8b9..c0b3c5c 100644
--- a/pkg/http_server/test/utils.dart
+++ b/pkg/http_server/test/utils.dart
@@ -7,27 +7,82 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
-import "package:path/path.dart";
+import "package:unittest/unittest.dart";
+
+import 'package:http_server/http_server.dart';
+
+import 'http_mock.dart';
+
+/**
+ *  Used to flag a given test case as being a mock or not.
+ */
+final _isMockTestExpando = new Expando<bool>('isMockTest');
+
+void testVirtualDir(String name, Future func(Directory dir)) {
+  _testVirtualDir(name, false, func);
+  _testVirtualDir(name, true, func);
+}
+
+void _testVirtualDir(String name, bool useMocks, Future func(Directory dir)) {
+  if(useMocks) {
+    name = '$name, with mocks';
+  }
+
+  test(name, () {
+    // see subsequent access to this expando below
+    _isMockTestExpando[currentTestCase] = useMocks;
+
+    var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+
+    return func(dir)
+        .whenComplete(() {
+          return dir.delete(recursive: true);
+        });
+  });
+}
+
+Future<int> getStatusCodeForVirtDir(VirtualDirectory virtualDir,
+                           String path,
+                          {String host,
+                           bool secure: false,
+                           DateTime ifModifiedSince,
+                           bool rawPath: false,
+                           bool followRedirects: true}) {
+
+  // if this is a mock test, then run the mock code path
+  if(_isMockTestExpando[currentTestCase]) {
+    var uri = _getUri(0, path, secure: secure, rawPath: rawPath);
+
+    var request = new MockHttpRequest(uri, followRedirects: followRedirects,
+        ifModifiedSince: ifModifiedSince);
+
+    return _withMockRequest(virtualDir, request)
+        .then((response) {
+          return response.statusCode;
+        });
+  };
+
+  assert(_isMockTestExpando[currentTestCase] == false);
+
+  return _withServer(virtualDir, (port) {
+    return getStatusCode(port, path, host: host, secure: secure,
+          ifModifiedSince: ifModifiedSince, rawPath: rawPath,
+          followRedirects: followRedirects);
+  });
+}
 
 Future<int> getStatusCode(int port,
                           String path,
                           {String host,
                            bool secure: false,
                            DateTime ifModifiedSince,
-                           bool rawPath: false}) {
-  var uri;
-  if (rawPath) {
-    uri = new Uri(scheme: secure ? 'https' : 'http',
-                  host: 'localhost',
-                  port: port,
-                  path: path);
-  } else {
-    uri = (secure ?
-        new Uri.https('localhost:$port', path) :
-        new Uri.http('localhost:$port', path));
-  }
+                           bool rawPath: false,
+                           bool followRedirects: true}) {
+  var uri = _getUri(port, path, secure: secure, rawPath: rawPath);
+
   return new HttpClient().getUrl(uri)
       .then((request) {
+        if (!followRedirects) request.followRedirects = false;
         if (host != null) request.headers.host = host;
         if (ifModifiedSince != null) {
           request.headers.ifModifiedSince = ifModifiedSince;
@@ -38,26 +93,113 @@
           (_) => response.statusCode));
 }
 
+Future<HttpHeaders> getHeaders(VirtualDirectory virDir, String path) {
 
-Future<HttpHeaders> getHeaders(int port, String path) {
-  return new HttpClient().get('localhost', port, path)
+  // if this is a mock test, then run the mock code path
+  if(_isMockTestExpando[currentTestCase]) {
+    var uri = _getUri(0, path);
+
+    var request = new MockHttpRequest(uri);
+
+    return _withMockRequest(virDir, request)
+        .then((response) {
+          return response.headers;
+        });
+  }
+
+  assert(_isMockTestExpando[currentTestCase] == false);
+
+  return _withServer(virDir, (port) {
+      return _getHeaders(port, path);
+    });
+}
+
+Future<String> getAsString(VirtualDirectory virtualDir, String path) {
+
+  // if this is a mock test, then run the mock code path
+  if(_isMockTestExpando[currentTestCase]) {
+    var uri = _getUri(0, path);
+
+    var request = new MockHttpRequest(uri);
+
+    return _withMockRequest(virtualDir, request)
+        .then((response) {
+          return response.mockContent;
+        });
+  };
+
+  assert(_isMockTestExpando[currentTestCase] == false);
+
+  return _withServer(virtualDir, (int port) {
+      return _getAsString(port, path);
+    });
+}
+
+Future<MockHttpResponse> _withMockRequest(VirtualDirectory virDir,
+    MockHttpRequest request) {
+    return virDir.serveRequest(request).then((value) {
+      expect(value, isNull);
+      expect(request.response.mockDone, isTrue);
+      return request.response;
+    })
+    .then((HttpResponse response) {
+      if(response.statusCode == HttpStatus.MOVED_PERMANENTLY ||
+          response.statusCode == HttpStatus.MOVED_TEMPORARILY) {
+        if(request.followRedirects == true) {
+          var uri = Uri.parse(response.headers.value(HttpHeaders.LOCATION));
+          var newMock = new MockHttpRequest(uri, followRedirects: true);
+
+          return _withMockRequest(virDir, newMock);
+        }
+      }
+      return response;
+    });
+}
+
+Future _withServer(VirtualDirectory virDir, Future func(int port)) {
+  HttpServer server;
+  return HttpServer.bind('localhost', 0)
+      .then((value) {
+        server = value;
+        virDir.serve(server);
+        return func(server.port);
+      })
+      .whenComplete(() => server.close());
+}
+
+Future<HttpHeaders> _getHeaders(int port, String path) =>
+    new HttpClient()
+      .get('localhost', port, path)
       .then((request) => request.close())
       .then((response) => response.drain().then(
           (_) => response.headers));
-}
 
-
-Future<String> getAsString(int port, String path) {
-  return new HttpClient().get('localhost', port, path)
+Future<String> _getAsString(int port, String path) =>
+    new HttpClient()
+      .get('localhost', port, path)
       .then((request) => request.close())
       .then((response) => UTF8.decodeStream(response));
-}
 
+Uri _getUri(int port,
+            String path,
+           {bool secure: false,
+            bool rawPath: false}) {
+  if (rawPath) {
+    return new Uri(scheme: secure ? 'https' : 'http',
+                  host: 'localhost',
+                  port: port,
+                  path: path);
+  } else {
+    return (secure ?
+        new Uri.https('localhost:$port', path) :
+        new Uri.http('localhost:$port', path));
+  }
+}
 
 const CERTIFICATE = "localhost_cert";
 
 
-setupSecure() {
+void setupSecure() {
   String certificateDatabase = Platform.script.resolve('pkcert').toFilePath();
   SecureSocket.initialize(database: certificateDatabase,
                           password: 'dartdart');
diff --git a/pkg/http_server/test/virtual_directory_test.dart b/pkg/http_server/test/virtual_directory_test.dart
index 027f044..7be2a12 100644
--- a/pkg/http_server/test/virtual_directory_test.dart
+++ b/pkg/http_server/test/virtual_directory_test.dart
@@ -6,226 +6,235 @@
 import 'dart:io';
 
 import "package:http_server/http_server.dart";
-import "package:path/path.dart";
+import 'package:path/path.dart' as pathos;
 import "package:unittest/unittest.dart";
 
 import 'utils.dart';
 
+void _testEncoding(name, expected, [bool create = true]) {
+  testVirtualDir('encode-$name', (dir) {
+      if (create) new File('${dir.path}/$name').createSync();
+      var virDir = new VirtualDirectory(dir.path);
+      virDir.allowDirectoryListing = true;
+
+      return getStatusCodeForVirtDir(virDir, '/$name')
+        .then((result) {
+          expect(result, expected);
+        });
+  });
+}
 
 void main() {
   group('serve-root', () {
-    test('dir-exists', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-        var virDir = new VirtualDirectory(dir.path);
+    testVirtualDir('dir-exists', (dir) {
 
-        virDir.serve(server);
+      var virDir = new VirtualDirectory(dir.path);
 
-        return getStatusCode(server.port, '/')
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync();
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+      return getStatusCodeForVirtDir(virDir, '/')
+        .then((result) {
+          expect(result, HttpStatus.NOT_FOUND);
+        });
     });
 
-    test('dir-not-exists', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-        dir.deleteSync();
-        var virDir = new VirtualDirectory(dir.path);
+    testVirtualDir('dir-not-exists', (dir) {
+      var virDir = new VirtualDirectory(pathos.join(dir.path + 'foo'));
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/')
-            .whenComplete(() {
-              server.close();
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+      return getStatusCodeForVirtDir(virDir, '/')
+          .then((result) {
+            expect(result, HttpStatus.NOT_FOUND);
+          });
     });
   });
 
   group('serve-file', () {
     group('top-level', () {
-      test('file-exists', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var file = new File('${dir.path}/file')..createSync();
-          var virDir = new VirtualDirectory(dir.path);
-
-          virDir.serve(server);
-
-          return getStatusCode(server.port, '/file')
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
-              });
-        }), completion(equals(HttpStatus.OK)));
+      testVirtualDir('file-exists', (dir) {
+        var file = new File('${dir.path}/file')..createSync();
+        var virDir = new VirtualDirectory(dir.path);
+        return getStatusCodeForVirtDir(virDir, '/file')
+            .then((result) {
+              expect(result, HttpStatus.OK);
+            });
       });
 
-      test('file-not-exists', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var virDir = new VirtualDirectory(dir.path);
+      testVirtualDir('file-not-exists', (dir) {
+        var virDir = new VirtualDirectory(dir.path);
 
-          virDir.serve(server);
-
-          return getStatusCode(server.port, '/file')
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync();
-              });
-        }), completion(equals(HttpStatus.NOT_FOUND)));
+        return getStatusCodeForVirtDir(virDir, '/file')
+            .then((result) {
+              expect(result, HttpStatus.NOT_FOUND);
+            });
       });
     });
 
     group('in-dir', () {
-      test('file-exists', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var dir2 = new Directory('${dir.path}/dir')..createSync();
-          var file = new File('${dir2.path}/file')..createSync();
-          var virDir = new VirtualDirectory(dir.path);
-
-          virDir.serve(server);
-
-          return getStatusCode(server.port, '/dir/file')
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
-              });
-        }), completion(equals(HttpStatus.OK)));
+      testVirtualDir('file-exists', (dir) {
+              var dir2 = new Directory('${dir.path}/dir')..createSync();
+              var file = new File('${dir2.path}/file')..createSync();
+              var virDir = new VirtualDirectory(dir.path);
+              return getStatusCodeForVirtDir(virDir, '/dir/file')
+            .then((result) {
+              expect(result, HttpStatus.OK);
+            });
       });
 
-      test('file-not-exists', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var dir2 = new Directory('${dir.path}/dir')..createSync();
-          var file = new File('${dir.path}/file')..createSync();
-          var virDir = new VirtualDirectory(dir.path);
+      testVirtualDir('file-not-exists', (dir) {
+              var dir2 = new Directory('${dir.path}/dir')..createSync();
+              var file = new File('${dir.path}/file')..createSync();
+              var virDir = new VirtualDirectory(dir.path);
 
-          virDir.serve(server);
-
-          return getStatusCode(server.port, '/dir/file')
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
-              });
-        }), completion(equals(HttpStatus.NOT_FOUND)));
+              return getStatusCodeForVirtDir(virDir, '/dir/file')
+                .then((result) {
+                  expect(result, HttpStatus.NOT_FOUND);
+                });
       });
     });
   });
 
   group('serve-dir', () {
     group('top-level', () {
-      test('simple', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var virDir = new VirtualDirectory(dir.path);
-          virDir.allowDirectoryListing = true;
+      testVirtualDir('simple', (dir) {
+        var virDir = new VirtualDirectory(dir.path);
+        virDir.allowDirectoryListing = true;
 
-          virDir.serve(server);
-
-          return getAsString(server.port, '/')
-          .whenComplete(() {
-            server.close();
-            dir.deleteSync();
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, contains('Index of /'));
           });
-        }), completion(contains('Index of /')));
       });
 
-      test('files', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var virDir = new VirtualDirectory(dir.path);
-          for (int i = 0; i < 10; i++) {
-            new File('${dir.path}/$i').createSync();
-          }
-          virDir.allowDirectoryListing = true;
+      testVirtualDir('files', (dir) {
+        var virDir = new VirtualDirectory(dir.path);
+        for (int i = 0; i < 10; i++) {
+          new File('${dir.path}/$i').createSync();
+        }
+        virDir.allowDirectoryListing = true;
 
-          virDir.serve(server);
-
-          return getAsString(server.port, '/')
-          .whenComplete(() {
-            server.close();
-            dir.deleteSync(recursive: true);
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, contains('Index of /'));
           });
-        }), completion(contains('Index of /')));
       });
 
-      test('dirs', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var virDir = new VirtualDirectory(dir.path);
-          for (int i = 0; i < 10; i++) {
-            new Directory('${dir.path}/$i').createSync();
-          }
-          virDir.allowDirectoryListing = true;
+      testVirtualDir('dirs', (dir) {
+        var virDir = new VirtualDirectory(dir.path);
+        for (int i = 0; i < 10; i++) {
+          new Directory('${dir.path}/$i').createSync();
+        }
+        virDir.allowDirectoryListing = true;
 
-          virDir.serve(server);
-
-          return getAsString(server.port, '/')
-          .whenComplete(() {
-            server.close();
-            dir.deleteSync(recursive: true);
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, contains('Index of /'));
           });
-        }), completion(contains('Index of /')));
       });
 
       if (!Platform.isWindows) {
-        test('recursive-link', () {
-          expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir =
-                Directory.systemTemp.createTempSync('http_server_virtual_');
-            var link = new Link('${dir.path}/recursive')..createSync('.');
-            var virDir = new VirtualDirectory(dir.path);
-            virDir.allowDirectoryListing = true;
+        testVirtualDir('recursive-link', (dir) {
+          var link = new Link('${dir.path}/recursive')..createSync('.');
+          var virDir = new VirtualDirectory(dir.path);
+          virDir.allowDirectoryListing = true;
 
-            virDir.serve(server);
-
-            return Future.wait([
-                getAsString(server.port, '/').then(
-                    (s) => s.contains('recursive/')),
-                getAsString(server.port, '/').then(
-                    (s) => !s.contains('../')),
-                getAsString(server.port, '/').then(
-                    (s) => s.contains('Index of /')),
-                getAsString(server.port, '/recursive').then(
-                    (s) => s.contains('recursive/')),
-                getAsString(server.port, '/recursive').then(
-                    (s) => s.contains('../')),
-                getAsString(server.port, '/recursive').then(
-                    (s) => s.contains('Index of /recursive'))])
-                .whenComplete(() {
-                  server.close();
-                  dir.deleteSync(recursive: true);
-                });
-          }), completion(equals([true, true, true, true, true, true])));
+          return Future.wait([
+              getAsString(virDir, '/').then(
+                  (s) => s.contains('recursive/')),
+              getAsString(virDir, '/').then(
+                  (s) => !s.contains('../')),
+              getAsString(virDir, '/').then(
+                  (s) => s.contains('Index of /')),
+              getAsString(virDir, '/recursive').then(
+                  (s) => s.contains('recursive/')),
+              getAsString(virDir, '/recursive').then(
+                  (s) => s.contains('../')),
+              getAsString(virDir, '/recursive').then(
+                  (s) => s.contains('Index of /recursive'))])
+            .then((result) {
+              expect(result, equals([true, true, true, true, true, true]));
+            });
         });
       }
     });
 
     group('custom', () {
-      test('simple', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          var virDir = new VirtualDirectory(dir.path);
-          virDir.allowDirectoryListing = true;
-          virDir.directoryHandler = (dir2, request) {
-            expect(dir2, isNotNull);
-            expect(FileSystemEntity.identicalSync(dir.path, dir2.path), isTrue);
-            request.response.write('My handler ${request.uri.path}');
-            request.response.close();
-          };
+      testVirtualDir('simple', (dir) {
+        var virDir = new VirtualDirectory(dir.path);
+        virDir.allowDirectoryListing = true;
+        virDir.directoryHandler = (dir2, request) {
+          expect(dir2, isNotNull);
+          expect(FileSystemEntity.identicalSync(dir.path, dir2.path), isTrue);
+          request.response.write('My handler ${request.uri.path}');
+          request.response.close();
+        };
 
-          virDir.serve(server);
-
-          return getAsString(server.port, '/')
-          .whenComplete(() {
-            server.close();
-            dir.deleteSync();
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, 'My handler /');
           });
-        }), completion(contains('My handler /')));
+      });
+
+      testVirtualDir('index-1', (dir) {
+        new File('${dir.path}/index.html').writeAsStringSync('index file');
+        var virDir = new VirtualDirectory(dir.path);
+        virDir.allowDirectoryListing = true;
+        virDir.directoryHandler = (dir2, request) {
+          // Redirect directory-requests to index.html files.
+          var indexUri = new Uri.file(dir2.path).resolve('index.html');
+          return virDir.serveFile(new File(indexUri.toFilePath()), request);
+        };
+
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, 'index file');
+          });
+      });
+
+      testVirtualDir('index-2', (dir) {
+        new Directory('${dir.path}/dir').createSync();
+        var virDir = new VirtualDirectory(dir.path);
+        virDir.allowDirectoryListing = true;
+
+        virDir.directoryHandler = protectAsync2((dir2, request) {
+          fail('not expected');
+        });
+
+        return getStatusCodeForVirtDir(virDir, '/dir', followRedirects: false)
+          .then((result) {
+            expect(result, 301);
+          });
+      });
+
+      testVirtualDir('index-3', (dir) {
+        new File('${dir.path}/dir/index.html')
+            ..createSync(recursive: true)
+            ..writeAsStringSync('index file');
+        var virDir = new VirtualDirectory(dir.path);
+        virDir.allowDirectoryListing = true;
+        virDir.directoryHandler = (dir2, request) {
+          // Redirect directory-requests to index.html files.
+          var indexUri = new Uri.file(dir2.path).resolve('index.html');
+          return virDir.serveFile(new File(indexUri.toFilePath()), request);
+        };
+        return getAsString(virDir, '/dir')
+          .then((result) {
+            expect(result, 'index file');
+          });
+      });
+
+      testVirtualDir('index-4', (dir) {
+        new File('${dir.path}/dir/index.html')
+            ..createSync(recursive: true)
+            ..writeAsStringSync('index file');
+        var virDir = new VirtualDirectory(dir.path);
+        virDir.allowDirectoryListing = true;
+        virDir.directoryHandler = (dir2, request) {
+          // Redirect directory-requests to index.html files.
+          var indexUri = new Uri.file(dir2.path).resolve('index.html');
+          virDir.serveFile(new File(indexUri.toFilePath()), request);
+        };
+        return getAsString(virDir, '/dir/')
+          .then((result) {
+            expect(result, 'index file');
+          });
       });
     });
   });
@@ -233,75 +242,46 @@
   group('links', () {
     if (!Platform.isWindows) {
       group('follow-links', () {
-        test('dir-link', () {
-          expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir =
-                Directory.systemTemp.createTempSync('http_server_virtual_');
-            var dir2 = new Directory('${dir.path}/dir2')..createSync();
-            var link = new Link('${dir.path}/dir3')..createSync('dir2');
-            var file = new File('${dir2.path}/file')..createSync();
-            var virDir = new VirtualDirectory(dir.path);
-            virDir.followLinks = true;
+        testVirtualDir('dir-link', (dir) {
+          var dir2 = new Directory('${dir.path}/dir2')..createSync();
+          var link = new Link('${dir.path}/dir3')..createSync('dir2');
+          var file = new File('${dir2.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+          virDir.followLinks = true;
 
-            virDir.serve(server);
-
-            return getStatusCode(server.port, '/dir3/file')
-                .whenComplete(() {
-                  server.close();
-                  dir.deleteSync(recursive: true);
-                });
-          }), completion(equals(HttpStatus.OK)));
+          return getStatusCodeForVirtDir(virDir, '/dir3/file')
+            .then((result) {
+              expect(result, HttpStatus.OK);
+            });
         });
 
-        test('root-link', () {
-          expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir =
-                Directory.systemTemp.createTempSync('http_server_virtual_');
-            var link = new Link('${dir.path}/dir3')..createSync('.');
-            var file = new File('${dir.path}/file')..createSync();
-            var virDir = new VirtualDirectory(dir.path);
-            virDir.followLinks = true;
+        testVirtualDir('root-link', (dir) {
+          var link = new Link('${dir.path}/dir3')..createSync('.');
+          var file = new File('${dir.path}/file')..createSync();
+          var virDir = new VirtualDirectory(dir.path);
+          virDir.followLinks = true;
 
-            virDir.serve(server);
-
-            return getStatusCode(server.port, '/dir3/file')
-                .whenComplete(() {
-                  server.close();
-                  dir.deleteSync(recursive: true);
-                });
-          }), completion(equals(HttpStatus.OK)));
+          return getStatusCodeForVirtDir(virDir, '/dir3/file')
+            .then((result) {
+              expect(result, HttpStatus.OK);
+            });
         });
 
         group('bad-links', () {
-          test('absolute-link', () {
-            expect(HttpServer.bind('localhost', 0).then((server) {
-              var dir =
-                  Directory.systemTemp.createTempSync('http_server_virtual_');
+          testVirtualDir('absolute-link', (dir) {
               var file = new File('${dir.path}/file')..createSync();
               var link = new Link('${dir.path}/file2')
                   ..createSync('${dir.path}/file');
               var virDir = new VirtualDirectory(dir.path);
               virDir.followLinks = true;
 
-              virDir.serve(server);
-
-              return new HttpClient().get('localhost',
-                                          server.port,
-                                          '/file2')
-                  .then((request) => request.close())
-                  .then((response) => response.drain().then(
-                      (_) => response.statusCode))
-                  .whenComplete(() {
-                    server.close();
-                    dir.deleteSync(recursive: true);
-                  });
-            }), completion(equals(HttpStatus.NOT_FOUND)));
+              return getStatusCodeForVirtDir(virDir, '/file2')
+                .then((result) {
+                  expect(result, HttpStatus.NOT_FOUND);
+                });
           });
 
-          test('relative-parent-link', () {
-            expect(HttpServer.bind('localhost', 0).then((server) {
-              var dir =
-                  Directory.systemTemp.createTempSync('http_server_virtual_');
+          testVirtualDir('relative-parent-link', (dir) {
               var dir2 = new Directory('${dir.path}/dir')..createSync();
               var file = new File('${dir.path}/file')..createSync();
               var link = new Link('${dir2.path}/file')
@@ -309,51 +289,32 @@
               var virDir = new VirtualDirectory(dir2.path);
               virDir.followLinks = true;
 
-              virDir.serve(server);
-
-              return new HttpClient().get('localhost',
-                                          server.port,
-                                          '/dir3/file')
-                  .then((request) => request.close())
-                  .then((response) => response.drain().then(
-                      (_) => response.statusCode))
-                  .whenComplete(() {
-                    server.close();
-                    dir.deleteSync(recursive: true);
+              return getStatusCodeForVirtDir(virDir, '/dir3/file')
+                  .then((result) {
+                    expect(result, HttpStatus.NOT_FOUND);
                   });
-            }), completion(equals(HttpStatus.NOT_FOUND)));
           });
         });
       });
 
       group('not-follow-links', () {
-        test('dir-link', () {
-          expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir =
-                Directory.systemTemp.createTempSync('http_server_virtual_');
+        testVirtualDir('dir-link', (dir) {
             var dir2 = new Directory('${dir.path}/dir2')..createSync();
             var link = new Link('${dir.path}/dir3')..createSync('dir2');
             var file = new File('${dir2.path}/file')..createSync();
             var virDir = new VirtualDirectory(dir.path);
             virDir.followLinks = false;
 
-            virDir.serve(server);
-
-            return getStatusCode(server.port, '/dir3/file')
-                .whenComplete(() {
-                  server.close();
-                  dir.deleteSync(recursive: true);
+            return getStatusCodeForVirtDir(virDir, '/dir3/file')
+                .then((result) {
+                  expect(result, HttpStatus.NOT_FOUND);
                 });
-          }), completion(equals(HttpStatus.NOT_FOUND)));
         });
       });
 
       group('follow-links', () {
-        test('no-root-jail', () {
-          test('absolute-link', () {
-            expect(HttpServer.bind('localhost', 0).then((server) {
-              var dir =
-                  Directory.systemTemp.createTempSync('http_server_virtual_');
+        group('no-root-jail', () {
+          testVirtualDir('absolute-link', (dir) {
               var file = new File('${dir.path}/file')..createSync();
               var link = new Link('${dir.path}/file2')
                   ..createSync('${dir.path}/file');
@@ -361,25 +322,13 @@
               virDir.followLinks = true;
               virDir.jailRoot = false;
 
-              virDir.serve(server);
-
-              return new HttpClient().get('localhost',
-                                          server.port,
-                                          '/file2')
-                  .then((request) => request.close())
-                  .then((response) => response.drain().then(
-                      (_) => response.statusCode))
-                  .whenComplete(() {
-                    server.close();
-                    dir.deleteSync(recursive: true);
+              return getStatusCodeForVirtDir(virDir, '/file2')
+                  .then((result) {
+                    expect(result, HttpStatus.OK);
                   });
-            }), completion(equals(HttpStatus.OK)));
           });
 
-          test('relative-parent-link', () {
-            expect(HttpServer.bind('localhost', 0).then((server) {
-              var dir =
-                  Directory.systemTemp.createTempSync('http_server_virtual_');
+          testVirtualDir('relative-parent-link', (dir) {
               var dir2 = new Directory('${dir.path}/dir')..createSync();
               var file = new File('${dir.path}/file')..createSync();
               var link = new Link('${dir2.path}/file')
@@ -388,19 +337,10 @@
               virDir.followLinks = true;
               virDir.jailRoot = false;
 
-              virDir.serve(server);
-
-              return new HttpClient().get('localhost',
-                                          server.port,
-                                          '/file')
-                  .then((request) => request.close())
-                  .then((response) => response.drain().then(
-                      (_) => response.statusCode))
-                  .whenComplete(() {
-                    server.close();
-                    dir.deleteSync(recursive: true);
+              return getStatusCodeForVirtDir(virDir, '/file')
+                  .then((result) {
+                    expect(result, HttpStatus.OK);
                   });
-            }), completion(equals(HttpStatus.OK)));
           });
         });
       });
@@ -409,288 +349,191 @@
 
   group('last-modified', () {
     group('file', () {
-      test('file-exists', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+      testVirtualDir('file-exists', (dir) {
           var file = new File('${dir.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
-          virDir.serve(server);
-
-          return getHeaders(server.port, '/file')
+          return getHeaders(virDir, '/file')
               .then((headers) {
                 expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull);
-                return HttpDate.parse(
+                var lastModified = HttpDate.parse(
                     headers.value(HttpHeaders.LAST_MODIFIED));
+
+                return getStatusCodeForVirtDir(
+                    virDir, '/file', ifModifiedSince: lastModified);
               })
-              .then((lastModified) {
-                return getStatusCode(
-                    server.port, '/file', ifModifiedSince: lastModified);
-              })
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
+              .then((result) {
+                expect(result, HttpStatus.NOT_MODIFIED);
               });
-        }), completion(equals(HttpStatus.NOT_MODIFIED)));
       });
 
-      test('file-changes', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+      testVirtualDir('file-changes', (dir) {
           var file = new File('${dir.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
-          virDir.serve(server);
-
-          return getHeaders(server.port, '/file')
+          return getHeaders(virDir, '/file')
               .then((headers) {
                 expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull);
-                return HttpDate.parse(
+                var lastModified = HttpDate.parse(
                     headers.value(HttpHeaders.LAST_MODIFIED));
-              })
-              .then((lastModified) {
+
                 // Fake file changed by moving date back in time.
                 lastModified = lastModified.subtract(
                   const Duration(seconds: 10));
-                return getStatusCode(
-                    server.port, '/file', ifModifiedSince: lastModified);
+
+                return getStatusCodeForVirtDir(virDir, '/file',
+                    ifModifiedSince: lastModified);
               })
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
+              .then((result) {
+                expect(result, HttpStatus.OK);
               });
-        }), completion(equals(HttpStatus.OK)));
       });
     });
   });
 
   group('content-type', () {
     group('mime-type', () {
-      test('from-path', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+      testVirtualDir('from-path', (dir) {
           var file = new File('${dir.path}/file.jpg')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
-          virDir.serve(server);
-
-          return getHeaders(server.port, '/file.jpg')
-              .then((headers) => headers.contentType.toString())
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
+          return getHeaders(virDir, '/file.jpg')
+              .then((headers) {
+                var contentType = headers.contentType.toString();
+                expect(contentType, 'image/jpeg');
               });
-        }), completion(equals('image/jpeg')));
       });
 
-      test('from-magic-number', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+      testVirtualDir('from-magic-number', (dir) {
           var file = new File('${dir.path}/file.jpg')..createSync();
           file.writeAsBytesSync(
               [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
           var virDir = new VirtualDirectory(dir.path);
 
-          virDir.serve(server);
-
-          return getHeaders(server.port, '/file.jpg')
-              .then((headers) => headers.contentType.toString())
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
+          return getHeaders(virDir, '/file.jpg')
+              .then((headers) {
+                var contentType = headers.contentType.toString();
+                expect(contentType, 'image/png');
               });
-        }), completion(equals('image/png')));
       });
     });
   });
 
   group('error-page', () {
-    test('default', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-        var virDir = new VirtualDirectory(dir.path);
-        dir.deleteSync();
+    testVirtualDir('default', (dir) {
+        var virDir = new VirtualDirectory(pathos.join(dir.path, 'foo'));
 
-        virDir.serve(server);
-
-        return getAsString(server.port, '/')
-            .whenComplete(() {
-              server.close();
-            });
-      }), completion(matches(new RegExp('404.*Not Found'))));
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, matches(new RegExp('404.*Not Found')));
+          });
     });
 
-    test('custom', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-        var virDir = new VirtualDirectory(dir.path);
-        dir.deleteSync();
+    testVirtualDir('custom', (dir) {
+        var virDir = new VirtualDirectory(pathos.join(dir.path, 'foo'));
 
         virDir.errorPageHandler = (request) {
           request.response.write('my-page ');
           request.response.write(request.response.statusCode);
           request.response.close();
         };
-        virDir.serve(server);
 
-        return getAsString(server.port, '/')
-            .whenComplete(() {
-              server.close();
-            });
-      }), completion(equals('my-page 404')));
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, 'my-page 404');
+          });
     });
   });
 
   group('escape-root', () {
-    test('escape1', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('escape1', (dir) {
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/../')
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync();
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+        return getStatusCodeForVirtDir(virDir, '/../')
+          .then((result) {
+            expect(result, HttpStatus.NOT_FOUND);
+          });
     });
 
-    test('escape2', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('escape2', (dir) {
         new Directory('${dir.path}/dir').createSync();
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/dir/../../')
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync(recursive: true);
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+        return getStatusCodeForVirtDir(virDir, '/dir/../../')
+          .then((result) {
+            expect(result, HttpStatus.NOT_FOUND);
+          });
     });
   });
 
   group('url-decode', () {
-    test('with-space', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('with-space', (dir) {
         var file = new File('${dir.path}/my file')..createSync();
         var virDir = new VirtualDirectory(dir.path);
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/my file')
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync(recursive: true);
-            });
-      }), completion(equals(HttpStatus.OK)));
+        return getStatusCodeForVirtDir(virDir, '/my file')
+          .then((result) {
+            expect(result, HttpStatus.OK);
+          });
     });
 
-    test('encoded-space', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('encoded-space', (dir) {
         var file = new File('${dir.path}/my file')..createSync();
         var virDir = new VirtualDirectory(dir.path);
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/my%20file')
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync(recursive: true);
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+        return getStatusCodeForVirtDir(virDir, '/my%20file')
+          .then((result) {
+            expect(result, HttpStatus.NOT_FOUND);
+          });
     });
 
-    test('encoded-path-separator', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('encoded-path-separator', (dir) {
         new Directory('${dir.path}/a').createSync();
         new Directory('${dir.path}/a/b').createSync();
         new Directory('${dir.path}/a/b/c').createSync();
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/a%2fb/c', rawPath: true)
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync(recursive: true);
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+        return getStatusCodeForVirtDir(virDir, '/a%2fb/c', rawPath: true)
+          .then((result) {
+            expect(result, HttpStatus.NOT_FOUND);
+          });
     });
 
-    test('encoded-null', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('encoded-null', (dir) {
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
 
-        virDir.serve(server);
-
-        return getStatusCode(server.port, '/%00', rawPath: true)
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync(recursive: true);
-            });
-      }), completion(equals(HttpStatus.NOT_FOUND)));
+        return getStatusCodeForVirtDir(virDir, '/%00', rawPath: true)
+          .then((result) {
+            expect(result, HttpStatus.NOT_FOUND);
+          });
     });
 
-    testEncoding(name, expected, [bool create = true]) {
-      test('encode-$name', () {
-        expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
-          if (create) new File('${dir.path}/$name').createSync();
-          var virDir = new VirtualDirectory(dir.path);
-          virDir.allowDirectoryListing = true;
-
-          virDir.serve(server);
-
-          return getStatusCode(server.port, '/$name')
-              .whenComplete(() {
-                server.close();
-                dir.deleteSync(recursive: true);
-              });
-        }), completion(equals(expected)));
-      });
-    }
-    testEncoding('..', HttpStatus.NOT_FOUND, false);
-    testEncoding('%2e%2e', HttpStatus.OK);
-    testEncoding('%252e%252e', HttpStatus.OK);
-    testEncoding('/', HttpStatus.OK, false);
-    testEncoding('%2f', HttpStatus.NOT_FOUND, false);
-    testEncoding('%2f', HttpStatus.OK, true);
+    _testEncoding('..', HttpStatus.NOT_FOUND, false);
+    _testEncoding('%2e%2e', HttpStatus.OK);
+    _testEncoding('%252e%252e', HttpStatus.OK);
+    _testEncoding('/', HttpStatus.OK, false);
+    _testEncoding('%2f', HttpStatus.NOT_FOUND, false);
+    _testEncoding('%2f', HttpStatus.OK, true);
   });
 
   group('serve-file', () {
-    test('from-dir-handler', () {
-      expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
+    testVirtualDir('from-dir-handler', (dir) {
         new File('${dir.path}/file')..writeAsStringSync('file contents');
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
         virDir.directoryHandler = (d, request) {
           expect(FileSystemEntity.identicalSync(dir.path, d.path), isTrue);
-          virDir.serveFile(new File('${d.path}/file'), request);
+          return virDir.serveFile(new File('${d.path}/file'), request);
         };
 
-        virDir.serve(server);
-
-        return getAsString(server.port, '/')
-            .whenComplete(() {
-              server.close();
-              dir.deleteSync(recursive: true);
-            });
-      }), completion(equals('file contents')));
+        return getAsString(virDir, '/')
+          .then((result) {
+            expect(result, 'file contents');
+          });
     });
   });
 }
-
diff --git a/pkg/intl/LICENSE b/pkg/intl/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/intl/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/intl/lib/extract_messages.dart b/pkg/intl/lib/extract_messages.dart
index b140dfb..66b2258 100644
--- a/pkg/intl/lib/extract_messages.dart
+++ b/pkg/intl/lib/extract_messages.dart
@@ -147,7 +147,9 @@
    */
   void visitMethodDeclaration(MethodDeclaration node) {
     parameters = node.parameters;
-    if (parameters == null) parameters = new FormalParameterList(null, [], null, null, null);
+    if (parameters == null) {
+      parameters = new FormalParameterList(null, [], null, null, null);
+    }
     name = node.name.name;
     super.visitMethodDeclaration(node);
   }
@@ -158,7 +160,9 @@
    */
   void visitFunctionDeclaration(FunctionDeclaration node) {
     parameters = node.functionExpression.parameters;
-    if (parameters == null) parameters = new FormalParameterList(null, [], null, null, null);
+    if (parameters == null) {
+      parameters = new FormalParameterList(null, [], null, null, null);
+    }
     name = node.name.name;
     super.visitFunctionDeclaration(node);
   }
@@ -225,8 +229,11 @@
     for (var namedArgument in arguments.where((x) => x is NamedExpression)) {
       var name = namedArgument.name.label.name;
       var exp = namedArgument.expression;
-      var string = exp is SimpleStringLiteral ? exp.value : exp.toString();
-      setAttribute(message, name, string);
+      var evaluator = new ConstantEvaluator();
+      var basicValue = exp.accept(evaluator);
+      var value = basicValue == ConstantEvaluator.NOT_A_CONSTANT ?
+          exp.toString() : basicValue;
+      setAttribute(message, name, value);
     }
     return message;
   }
@@ -254,7 +261,7 @@
       }
     }
 
-    void setValue(MainMessage message, String fieldName, String fieldValue) {
+    void setValue(MainMessage message, String fieldName, Object fieldValue) {
       message[fieldName] = fieldValue;
     }
 
diff --git a/pkg/intl/lib/intl.dart b/pkg/intl/lib/intl.dart
index 7fff850..ba517d3 100644
--- a/pkg/intl/lib/intl.dart
+++ b/pkg/intl/lib/intl.dart
@@ -129,22 +129,36 @@
   }
 
   /**
-   * Returns a message that can be internationalized. It takes a
-   * [message_str] that will be translated, which may be interpolated
-   * based on one or more variables, a [desc] providing a description of usage
-   * for the [message_str], and a map of [examples] for each data element to be
-   * substituted into the message. For example, if message="Hello, $name", then
-   * examples = {'name': 'Sparky'}. If not using the user's default locale, or
-   * if the locale is not easily detectable, explicitly pass [locale].
-   * The values of [desc] and [examples] are not used at run-time but are only
-   * made available to the translators, so they MUST be simple Strings available
-   * at compile time: no String interpolation or concatenation.
-   * The expected usage of this is inside a function that takes as parameters
-   * the variables used in the interpolated string, and additionally also a
-   * locale (optional).
-   * Ultimately, the information about the enclosing function and its arguments
-   * will be extracted automatically but for the time being it must be passed
-   * explicitly in the [name] and [args] arguments.
+   * Use this for a message that will be translated for different locales. The
+   * expected usage is that this is inside an enclosing function that only
+   * returns the value of this call and provides a scope for the variables that
+   * will be substituted in the message.
+   *
+   * The parameters are a
+   * [message_str] to be translated, which may be interpolated
+   * based on one or more variables, the [name] of the message, which should
+   * match the enclosing function name, the [args] of the enclosing
+   * function, a [desc] providing a description of usage
+   * and a map of [examples] for each interpolated variable. For example
+   *       hello(yourName) => Intl.message(
+   *         "Hello, $yourName",
+   *         name: "hello",
+   *         args: [name],
+   *         desc: "Say hello",
+   *         examples = {"yourName": "Sparky"}.
+   * The source code will be processed via the analyzer to extract out the
+   * message data, so only a subset of valid Dart code is accepted. In
+   * particular, everything must be literal and cannot refer to variables
+   * outside the scope of the enclosing function. The [examples] map must
+   * be a valid const literal map. Similarly, the [desc] argument must
+   * be a single, simple string. These two arguments will not be used at runtime
+   * but will be extracted from
+   * the source code and used as additional data for translators.
+   *
+   * The [name] and [args] arguments are required, and are used at runtime
+   * to look up the localized version and pass the appropriate arguments to it.
+   * We may in the future modify the code during compilation to make manually
+   * passing those arguments unnecessary.
    */
   static String message(String message_str, {final String desc: '',
       final Map examples: const {}, String locale, String name,
diff --git a/pkg/intl/lib/src/intl_message.dart b/pkg/intl/lib/src/intl_message.dart
index 13aad62..a502326 100644
--- a/pkg/intl/lib/src/intl_message.dart
+++ b/pkg/intl/lib/src/intl_message.dart
@@ -57,10 +57,18 @@
 
   /**
    * We find the arguments from the top-level [MainMessage] and use those to
-   * do variable substitutions.
+   * do variable substitutions. [MainMessage] overrides this to return
+   * the actual arguments.
    */
   get arguments => parent == null ? const [] : parent.arguments;
 
+  /**
+   * We find the examples from the top-level [MainMessage] and use those
+   * when writing out variables. [MainMessage] overrides this to return
+   * the actual examples.
+   */
+  get examples => parent == null ? const [] : parent.examples;
+
   String checkValidity(MethodInvocation node, List arguments,
                        String outerName, FormalParameterList outerArgs) {
     var hasArgs = arguments.any(
@@ -315,7 +323,7 @@
   String description;
 
   /** The examples from the Intl.message call */
-  String examples;
+  Map<String, dynamic> examples;
 
   /**
    * The name, which may come from the function name, from the arguments
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index 44b4944..0b84918 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -1,11 +1,11 @@
 name: intl
-version: 0.9.1
+version: 0.9.4
 author: Dart Team <misc@dartlang.org>
 description: Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/intl
 dependencies:
-  analyzer: ">=0.10.1 <0.11.0"
+  analyzer: ">=0.11.5 <0.12.0"
   path: ">=0.9.0 <2.0.0"
 dev_dependencies:
   serialization: ">=0.9.0 <0.10.0"
diff --git a/pkg/intl/test/message_extraction/examples_parsing_test.dart b/pkg/intl/test/message_extraction/examples_parsing_test.dart
new file mode 100644
index 0000000..8a336db
--- /dev/null
+++ b/pkg/intl/test/message_extraction/examples_parsing_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Test for parsing the examples argument from an Intl.message call. Very
+ * minimal so far.
+ */
+import 'package:unittest/unittest.dart';
+import 'package:intl/extract_messages.dart';
+import '../data_directory.dart';
+import 'package:path/path.dart' as path;
+import 'dart:io';
+
+main() {
+  test("Message examples are correctly extracted", () {
+    var file = path.join(
+        intlDirectory,
+        'test',
+        'message_extraction',
+        'sample_with_messages.dart');
+    var messages = parseFile(new File(file));
+    expect(messages['message2'].examples, {"x" : 3});
+  });
+}
\ No newline at end of file
diff --git a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
index 657c53c..e958564 100644
--- a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
+++ b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
@@ -225,7 +225,7 @@
 
 main(List<String> args) {
   if (args.length == 0) {
-    print('Usage: generate_hardcoded_translation [--output-dir=<dir>] '
+    print('Usage: make_hardcoded_translation [--output-dir=<dir>] '
         '[originalFile.json]');
     exit(0);
   }
diff --git a/pkg/intl/test/message_extraction/sample_with_messages.dart b/pkg/intl/test/message_extraction/sample_with_messages.dart
index f678a35..b978ca8 100644
--- a/pkg/intl/test/message_extraction/sample_with_messages.dart
+++ b/pkg/intl/test/message_extraction/sample_with_messages.dart
@@ -19,7 +19,7 @@
 message1() => Intl.message("This is a message", name: 'message1', desc: 'foo' );
 
 message2(x) => Intl.message("Another message with parameter $x",
-    name: 'message2', desc: 'Description 2', args: [x]);
+    name: 'message2', desc: 'Description 2', args: [x], examples: {'x' : 3});
 
 // A string with multiple adjacent strings concatenated together, verify
 // that the parser handles this properly.
diff --git a/pkg/json/LICENSE b/pkg/json/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/json/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/json/lib/json.dart b/pkg/json/lib/json.dart
index f706338..4c67322 100644
--- a/pkg/json/lib/json.dart
+++ b/pkg/json/lib/json.dart
@@ -769,7 +769,7 @@
    */
   bool stringifyJsonValue(final object) {
     if (object is num) {
-      // TODO: use writeOn.
+      if (!object.isFinite) return false;
       sink.write(numberToString(object));
       return true;
     } else if (identical(object, true)) {
diff --git a/pkg/json/pubspec.yaml b/pkg/json/pubspec.yaml
index de9f8cc..b4e3112 100644
--- a/pkg/json/pubspec.yaml
+++ b/pkg/json/pubspec.yaml
@@ -1,5 +1,5 @@
 name: json
-version: 0.9.0
+version: 0.9.1
 author: Dart Team <misc@dartlang.org>
 description: >
  A JSON library. Intended for advanced use where the built-in facilities are
diff --git a/pkg/json/test/json_test.dart b/pkg/json/test/json_test.dart
index d146ce3..c3aaf70 100644
--- a/pkg/json/test/json_test.dart
+++ b/pkg/json/test/json_test.dart
@@ -123,6 +123,17 @@
       json.stringify([new Object()]);
     }, throwsJsonError);
 
+    expect(() {
+      json.stringify([double.NAN]);
+    }, throwsJsonError);
+
+    expect(() {
+      json.stringify([double.INFINITY]);
+    }, throwsJsonError);
+
+    expect(() {
+      json.stringify([-double.INFINITY]);
+    }, throwsJsonError);
   });
 
   test('stringify throws if argument cannot be converted', () {
diff --git a/pkg/logging/pubspec.yaml b/pkg/logging/pubspec.yaml
index ef3a4cc..199f653 100644
--- a/pkg/logging/pubspec.yaml
+++ b/pkg/logging/pubspec.yaml
@@ -1,5 +1,5 @@
 name: logging
-version: 0.9.1
+version: 0.9.1+1
 author: Dart Team <misc@dartlang.org>
 description: >
   Provides APIs for debugging and error logging. This library introduces
diff --git a/pkg/mime/LICENSE b/pkg/mime/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/mime/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/mutation_observer/LICENSE b/pkg/mutation_observer/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/mutation_observer/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/oauth2/LICENSE b/pkg/oauth2/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/oauth2/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/oauth2/pubspec.yaml b/pkg/oauth2/pubspec.yaml
index b0d701d..74ee771 100644
--- a/pkg/oauth2/pubspec.yaml
+++ b/pkg/oauth2/pubspec.yaml
@@ -1,5 +1,5 @@
 name: oauth2
-version: 0.9.0
+version: 0.9.1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
@@ -7,7 +7,7 @@
   behalf of a user, and making authorized HTTP requests with the user's
   OAuth2 credentials. Currently only works with dart:io.
 dependencies:
-  http: ">=0.9.0 <0.10.0"
+  http: ">=0.9.2 <0.10.0"
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
 environment:
diff --git a/pkg/observe/lib/observe.dart b/pkg/observe/lib/observe.dart
index a8df890..218a036 100644
--- a/pkg/observe/lib/observe.dart
+++ b/pkg/observe/lib/observe.dart
@@ -76,6 +76,20 @@
  * form into the second form automatically, to get the best of both worlds.
  */
 library observe;
+import 'src/bind_property.dart';
+import 'src/change_notifier.dart';
+import 'src/change_record.dart';
+import 'src/compound_path_observer.dart';
+import 'src/list_path_observer.dart';
+import 'src/list_diff.dart';
+import 'src/metadata.dart';
+import 'src/observable.dart';
+import 'src/observable_box.dart';
+import 'src/observable_list.dart';
+import 'src/observable_map.dart';
+import 'src/path_observer.dart';
+import 'src/to_observable.dart';
+
 
 export 'src/bind_property.dart';
 export 'src/change_notifier.dart';
diff --git a/pkg/path/LICENSE b/pkg/path/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/path/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/pkg.status b/pkg/pkg.status
index 29e687f..0708373 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -23,8 +23,6 @@
 third_party/html5lib/test/dom_compat_test: Skip
 third_party/html5lib/test/browser/browser_test: Skip
 
-http/test/http_test: Pass, RuntimeError # Issue 15652
-
 [ $compiler == dart2js ]
 collection/test/equality_test/01: Fail # Issue 1533
 collection/test/equality_test/02: Fail # Issue 1533
@@ -32,6 +30,8 @@
 collection/test/equality_test/04: Fail # Issue 1533
 collection/test/equality_test/05: Fail # Issue 1533
 collection/test/equality_test/none: Pass, Fail # Issue 14348
+third_party/angular_tests/browser_test: Pass, Slow # Large dart2js compile time
+third_party/angular_tests/browser_test/core/parser/parser: Fail # Issue 15915
 typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
 
 [ $compiler == dart2js && $checked ]
@@ -72,6 +72,7 @@
 polymer/test/take_attributes_test: Skip #uses dart:html
 polymer/test/template_distribute_dynamic_test: Skip #uses dart:html
 polymer/test/unbind_test: Skip # uses dart:html
+third_party/angular_tests/browser_test: Skip # uses dart:html
 
 [$compiler == dart2dart]
 *: Skip
@@ -123,6 +124,8 @@
 unittest/test/mock_stepwise_negative_test: Skip
 polymer/example/canonicalization: Skip
 
+third_party/angular_tests/browser_test: StaticWarning # Issue 15890
+
 [ $compiler == dart2analyzer ]
 # These tests are runtime negative but statically positive, so we skip
 # them in the analyzer.
@@ -130,6 +133,8 @@
 unittest/test/mock_stepwise_negative_test: Skip
 polymer/example/canonicalization: Skip
 
+third_party/angular_tests/browser_test: StaticWarning # Issue 15890
+
 [ $compiler == dart2js && $runtime == none]
 polymer/example/canonicalization: Skip
 
@@ -183,6 +188,7 @@
 intl/test/find_default_locale_standalone_test: Fail, OK # Uses dart:io.
 intl/test/message_extraction/message_extraction_test: Fail, OK # Uses dart:io.
 intl/test/message_extraction/failed_extraction_test: Fail, OK # Users dart:io
+intl/test/message_extraction/examples_parsing_test: Fail, OK # Users dart:io
 oauth2/test/authorization_code_grant_test: Fail, OK # Uses dart:io.
 oauth2/test/client_test: Fail, OK # Uses dart:io.
 oauth2/test/credentials_test: Fail, OK # Uses dart:io.
@@ -190,30 +196,14 @@
 observe/test/transformer_test: Fail, OK # Uses dart:io.
 path/test/io_test: Fail, OK # Uses dart:io.
 polymer/test/build/*: Fail, OK # Uses dart:io.
+third_party/angular_tests/vm_test: Skip # Uses dart:io
 watcher/test/*: Fail, OK # Uses dart:io.
 
-scheduled_test/test/descriptor/async_test: Fail # http://dartbug.com/8440
-scheduled_test/test/descriptor/directory_test: Fail # http://dartbug.com/8440
-scheduled_test/test/descriptor/file_test: Fail # http://dartbug.com/8440
-scheduled_test/test/descriptor/nothing_test: Fail # http://dartbug.com/8440
-scheduled_test/test/descriptor/pattern_test: Fail # http://dartbug.com/8440
+scheduled_test/test/descriptor/*: Fail # http://dartbug.com/8440
 scheduled_test/test/scheduled_future_matchers_test: Fail # http://dartbug.com/8440
 scheduled_test/test/scheduled_process_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/abort_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/current_schedule_current_task_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/current_schedule_errors_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/current_schedule_state_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/nested_task_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/on_complete_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/on_exception_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/out_of_band_task_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/set_up_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/signal_error_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/simple_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/task_return_value_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/timeout_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/wrap_async_test: Fail # http://dartbug.com/8440
-scheduled_test/test/scheduled_test/wrap_future_test: Fail # http://dartbug.com/8440
+scheduled_test/test/scheduled_test/*: Fail # http://dartbug.com/8440
+scheduled_test/test/scheduled_stream/stream_matcher_test: Fail # http://dartbug.com/8440
 
 
 */test/analyzer_test: Skip  # No need to run analysis tests on browser bots
@@ -240,6 +230,9 @@
 barback/test/too_many_open_files_test: Skip # 14220
 third_party/html5lib/test/tokenizer_test: Pass, Slow
 
+[ $arch == simarm && $checked ]
+watcher/test/directory_watcher/linux_test: Skip # Issue 16118
+
 # Skip serialization test that explicitly has no library declaration in the
 # test on Dartium, which requires all tests to have a library.
 [ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
@@ -283,6 +276,7 @@
 
 [ $runtime == safari || $runtime == chrome || $runtime == ie9 || $runtime == ff || $runtime == dartium || $runtime == drt ]
 docgen/test/single_library_test: Skip # Uses dart:io
+docgen/test/multi_library_test: Skip # Uses dart:io
 scheduled_test/test/scheduled_server_test: Skip # Uses dart:io
 
 [ $browser || $runtime == vm ]
@@ -295,18 +289,8 @@
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 docgen/test/single_library_test: StaticWarning
-http_server/test/http_body_test: StaticWarning
-http_server/test/http_multipart_test: StaticWarning
-http_server/test/virtual_directory_test: StaticWarning
-http_server/test/virtual_host_test: StaticWarning
-http/test/client_test: StaticWarning
-http/test/http_test: StaticWarning
-http/test/mock_client_test: StaticWarning
-http/test/multipart_test: StaticWarning
-http/test/request_test: StaticWarning
-http/test/streamed_request_test: StaticWarning
+docgen/test/multi_library_test: StaticWarning
 unittest/test/matchers_test: StaticWarning, OK # testing error creating abstract class
-unittest/test/mock_test: StaticWarning, OK # testing unimplemented members
 
 [ $runtime == vm && ($system == windows || $system == macos) ]
 watcher/test/*/linux_test: Skip
@@ -314,5 +298,39 @@
 [ $runtime == vm && ($system == windows || $system == linux) ]
 watcher/test/*/mac_os_test: Skip
 
-[ $runtime == vm && $system == macos ]
-watcher/test/directory_watcher/mac_os_test: Pass, Fail # Issue 15024
+[ $runtime == safari || $runtime == chrome || $runtime == ie9 || $runtime == ff || $runtime == ie10 ]
+# Various issues due to limited browser testing in Angular.
+third_party/angular_tests/*: Skip
+
+[ $unchecked ]
+third_party/angular_tests/browser_test/angular: Skip # Requires checked mode.
+third_party/angular_tests/browser_test/core/scope: Skip # Requires checked mode.
+third_party/angular_tests/browser_test/core/zone: Skip # Requires checked mode.
+
+[ $use_repository_packages ]
+analyzer/test/error_test: PubGetError
+analyzer/test/generated/ast_test: PubGetError
+analyzer/test/generated/element_test: PubGetError
+analyzer/test/generated/parser_test: PubGetError
+analyzer/test/generated/resolver_test: PubGetError
+analyzer/test/generated/scanner_test: PubGetError
+analyzer/test/options_test: PubGetError
+analyzer/test/parse_compilation_unit_test: PubGetError
+analyzer/test/services/formatter_test: PubGetError
+args/test/args_test: PubGetError
+args/test/command_test: PubGetError
+args/test/parse_all_test: PubGetError
+args/test/parse_test: PubGetError
+args/test/usage_test: PubGetError
+async/test/stream_zip_test: PubGetError
+async/test/stream_zip_zone_test: PubGetError
+collection/test/algorithms_test: PubGetError
+collection/test/iterable_zip_test: PubGetError
+collection/test/priority_queue_test: PubGetError
+collection/test/unmodifiable_collection_test: PubGetError
+collection/test/wrapper_test: PubGetError
+stack_trace/test/chain_test: PubGetError
+stack_trace/test/frame_test: PubGetError
+stack_trace/test/trace_test: PubGetError
+stack_trace/test/vm_test: PubGetError
+
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
new file mode 100644
index 0000000..5f14a91
--- /dev/null
+++ b/pkg/pkgbuild.status
@@ -0,0 +1,19 @@
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+third_party/pkg/route_hierarchical: Fail
+
+samples/third_party/pop-pop-win: Pass, Slow
+samples/searchable_list: Pass, Slow
+pkg/docgen: Pass, Slow
+
+[ $use_repository_packages ]
+pkg/analyzer: PubGetError
+pkg/args: PubGetError
+pkg/async: PubGetError
+pkg/collection: PubGetError
+pkg/stack_trace: PubGetError
+
+[ $use_public_packages ]
+pkg/watcher: PubGetError # Issue 16026
diff --git a/pkg/polymer/CHANGELOG.md b/pkg/polymer/CHANGELOG.md
index 3aad33a..01e65d6 100644
--- a/pkg/polymer/CHANGELOG.md
+++ b/pkg/polymer/CHANGELOG.md
@@ -5,6 +5,9 @@
 impact polymer: custom_element, html_import, observe, shadow_dom,
 and template_binding.
 
+#### Pub version 0.9.4
+  * Removes unused dependency on csslib.
+
 #### Pub version 0.9.3+3
   * Removes workaround now that mirrors implement a missing feature. Requires
     SDK >= 1.1.0-dev.5.0.
diff --git a/pkg/polymer/example/canonicalization/pubspec.yaml b/pkg/polymer/example/canonicalization/pubspec.yaml
index 80a7923..3860a91 100644
--- a/pkg/polymer/example/canonicalization/pubspec.yaml
+++ b/pkg/polymer/example/canonicalization/pubspec.yaml
@@ -1,6 +1,5 @@
 name: canonicalization
 dependencies:
-  polymer:
-    path: ../../
+  polymer: any
 dev_dependencies:
   unittest: any
diff --git a/pkg/polymer/lib/src/build/runner.dart b/pkg/polymer/lib/src/build/runner.dart
index 87db2ae..af71282 100644
--- a/pkg/polymer/lib/src/build/runner.dart
+++ b/pkg/polymer/lib/src/build/runner.dart
@@ -47,9 +47,16 @@
    */
   final bool machineFormat;
 
+  /**
+   * Whether to follow symlinks when listing directories. By default this is
+   * false because directories have symlinks for the packages directory created
+   * by pub, but it can be turned on for custom uses of this library.
+   */
+  final bool followLinks;
+
   BarbackOptions(this.phases, this.outDir, {currentPackage, packageDirs,
       this.transformTests: false, this.transformPolymerDependencies: false,
-      this.machineFormat: false})
+      this.machineFormat: false, this.followLinks: false})
       : currentPackage = (currentPackage != null
           ? currentPackage : readCurrentPackageFromPubspec()),
         packageDirs = (packageDirs != null
@@ -110,9 +117,8 @@
 // TODO(sigmund): consider computing this list by recursively parsing
 // pubspec.yaml files in the `Options.packageDirs`.
 final Set<String> _polymerPackageDependencies = [
-    'analyzer', 'args', 'barback', 'browser', 'csslib',
-    'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
-    'logging', 'meta', 'mutation_observer', 'observe', 'path'
+    'analyzer', 'args', 'barback', 'browser', 'custom_element', 'html5lib',
+    'html_import', 'js', 'logging', 'mutation_observer', 'observe', 'path'
     'polymer_expressions', 'serialization', 'shadow_dom', 'source_maps',
     'stack_trace', 'template_binding', 'unittest', 'unmodifiable_collection',
     'yaml'].toSet();
@@ -124,7 +130,7 @@
   if (packageDir == null) return const [];
   var dir = new Directory(path.join(packageDir, subDir));
   if (!dir.existsSync()) return const [];
-  return dir.listSync(recursive: true, followLinks: false)
+  return dir.listSync(recursive: true, followLinks: options.followLinks)
       .where((f) => f is File)
       .map((f) => path.relative(f.path, from: packageDir));
 }
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 7a348ce..f52c8f8 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: polymer
-version: 0.9.3+3
+version: 0.9.4
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 description: >
   Polymer.dart is a new type of library for the web, built on top of Web
@@ -11,7 +11,6 @@
   args: ">=0.9.0 <0.10.0"
   barback: ">=0.9.0 <0.12.0"
   browser: ">=0.9.0 <0.10.0"
-  csslib: ">=0.9.0 <0.10.0"
   custom_element: ">=0.9.1+1 <0.10.0"
   html5lib: ">=0.9.1 <0.10.0"
   html_import: ">=0.9.0 <0.10.0"
diff --git a/pkg/scheduled_test/LICENSE b/pkg/scheduled_test/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/scheduled_test/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index 1d46d46..295efcb 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -65,14 +65,18 @@
 
   /// Whether the user has scheduled the end of this process by calling either
   /// [shouldExit] or [kill].
-  var _endScheduled = false;
+  bool get _endScheduled => _scheduledExitTask != null;
 
-  /// The task that runs immediately before this process is scheduled to end. If
-  /// the process ends during this task, we treat that as expected.
-  Task _taskBeforeEnd;
+  /// The task where this process is scheduled to exit -- either by waiting to
+  /// exit ([shouldExit]) or by killing the process ([kill]).
+  ///
+  /// It's legal for the process to exit before this task runs. This can happen
+  /// for example if there's still standard output to read from the process
+  /// after it exits.
+  Task _scheduledExitTask;
 
-  /// Whether the process is expected to terminate at this point.
-  var _endExpected = false;
+  /// The task during which the process actually exited.
+  Task _actualExitTask;
 
   /// Schedules a process to start. [executable], [arguments],
   /// [workingDirectory], and [environment] have the same meaning as for
@@ -173,26 +177,8 @@
     // queue where the process will be killed, rather than blocking the tasks
     // queue waiting for the process to exit.
     _process.then((p) => Chain.track(p.exitCode)).then((exitCode) {
-      if (_endExpected) {
-        exitCodeCompleter.complete(exitCode);
-        return;
-      }
-
-      wrapFuture(pumpEventQueue().then((_) {
-        if (currentSchedule.currentTask != _taskBeforeEnd) return null;
-        // If we're one task before the end was scheduled, wait for that task
-        // to complete and pump the event queue so that _endExpected will be
-        // set.
-        return _taskBeforeEnd.result.then((_) => pumpEventQueue());
-      }).then((_) {
-        exitCodeCompleter.complete(exitCode);
-
-        if (!_endExpected) {
-          fail("Process '$description' ended earlier than scheduled "
-               "with exit code $exitCode.");
-        }
-      }), "waiting to reach shouldExit() or kill() for process "
-          "'$description'");
+      _actualExitTask = currentSchedule.currentTask;
+      exitCodeCompleter.complete(exitCode);
     });
   }
 
@@ -224,7 +210,6 @@
       var killedPrematurely = false;
       if (!_exitCode.hasValue) {
         killedPrematurely = true;
-        _endExpected = true;
         _process.value.kill(ProcessSignal.SIGKILL);
         // Ensure that the onException queue waits for the process to actually
         // exit after being killed.
@@ -239,9 +224,22 @@
         var stdout = results[0].join("\n");
         var stderr = results[1].join("\n");
 
-        var exitDescription = killedPrematurely
-            ? "Process was killed prematurely."
-            : "Process exited with exit code ${_exitCode.value}.";
+        var exitDescription;
+        if (killedPrematurely) {
+          exitDescription = "Process was killed prematurely.";
+        } else {
+          exitDescription = "Process exited with exit code ${_exitCode.value}";
+          if (_actualExitTask != _scheduledExitTask) {
+            var taskString = _actualExitTask.toString();
+            if (taskString.contains("\n")) {
+              exitDescription += " in task:\n${prefixLines(taskString)}";
+            } else {
+              exitDescription += " in task $taskString";
+            }
+          }
+          exitDescription += ".";
+        }
+
         currentSchedule.addDebugInfo(
             "Results of running '$description':\n"
             "$exitDescription\n"
@@ -329,14 +327,12 @@
       throw new StateError("shouldExit() or kill() already called.");
     }
 
-    _endScheduled = true;
-    _taskBeforeEnd = currentSchedule.tasks.contents.last;
     schedule(() {
-      _endExpected = true;
       return _process
           .then((p) => p.kill(ProcessSignal.SIGKILL))
           .then((_) => _exitCode);
     }, "waiting for process '$description' to die");
+    _scheduledExitTask = currentSchedule.tasks.contents.last;
   }
 
   /// Waits for the process to exit, and verifies that the exit code matches
@@ -346,15 +342,13 @@
       throw new StateError("shouldExit() or kill() already called.");
     }
 
-    _endScheduled = true;
-    _taskBeforeEnd = currentSchedule.tasks.contents.last;
     schedule(() {
-      _endExpected = true;
       return _exitCode.then((exitCode) {
         if (expectedExitCode != null) {
           expect(exitCode, equals(expectedExitCode));
         }
       });
     }, "waiting for process '$description' to exit");
+    _scheduledExitTask = currentSchedule.tasks.contents.last;
   }
 }
diff --git a/pkg/scheduled_test/lib/scheduled_server.dart b/pkg/scheduled_test/lib/scheduled_server.dart
index 202fdb8..9466182 100644
--- a/pkg/scheduled_test/lib/scheduled_server.dart
+++ b/pkg/scheduled_test/lib/scheduled_server.dart
@@ -12,7 +12,6 @@
 
 import 'scheduled_test.dart';
 import 'src/scheduled_server/handler.dart';
-import 'src/scheduled_server/safe_http_server.dart';
 import 'src/utils.dart';
 
 typedef Future ScheduledHandler(HttpRequest request);
@@ -49,7 +48,7 @@
 
     var scheduledServer;
     scheduledServer = new ScheduledServer._(schedule(() {
-      return Chain.track(SafeHttpServer.bind("127.0.0.1", 0)).then((server) {
+      return Chain.track(HttpServer.bind("127.0.0.1", 0)).then((server) {
         Chain.track(server).listen(scheduledServer._handleRequest,
             onError: currentSchedule.signalError);
         currentSchedule.onComplete.schedule(server.close);
diff --git a/pkg/scheduled_test/lib/scheduled_stream.dart b/pkg/scheduled_test/lib/scheduled_stream.dart
new file mode 100644
index 0000000..2b8be67
--- /dev/null
+++ b/pkg/scheduled_test/lib/scheduled_stream.dart
@@ -0,0 +1,265 @@
+// 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 scheduled_test.scheduled_stream;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:stack_trace/stack_trace.dart';
+
+import 'scheduled_test.dart';
+import 'src/stream_matcher.dart';
+import 'src/utils.dart';
+
+export 'src/stream_matcher.dart';
+
+/// A wrapper for streams that supports a pull-based model of retrieving values
+/// as well as a set of [StreamMatcher]s for testing the values emitted by the
+/// stream.
+///
+/// The only method on [ScheduledStream] that's actually scheduled is [expect],
+/// which is the method that users testing streaming code are most likely to
+/// want to use.
+class ScheduledStream<T> {
+  /// The underlying stream.
+  final Stream<T> _stream;
+
+  /// The subscription to [_stream].
+  StreamSubscription<T> _subscription;
+
+  /// The completer for emitting a value requested by [next].
+  ///
+  /// If this is non-null, [_pendingValues] will always be empty, since any
+  /// value coming in will be passed to this completer.
+  Completer<T> _nextCompleter;
+
+  /// The completer for emitting a value requested by [hasNext].
+  Completer<bool> _hasNextCompleter;
+
+  /// The set of all streams forked from this one.
+  final _forks = new Set<ScheduledStream<T>>();
+  final _forkControllers = new Set<StreamController<T>>();
+
+  /// The queue of values emitted by [_stream] but not yet emitted through
+  /// [next].
+  final _pendingValues = new Queue<Fallible<T>>();
+
+  /// All values emitted by this stream so far.
+  ///
+  /// This does not include values emitted by the underlying stream but not yet
+  /// emitted through [next].
+  List<T> get emittedValues => new UnmodifiableListView(_emittedValues);
+  final _emittedValues = new List<T>();
+
+  /// All values emitted by the underlying stream.
+  ///
+  /// This is intended primarily for providing debugging information.
+  List<T> get allValues {
+    var list = new List<T>.from(_emittedValues);
+    list.addAll(_pendingValues.where((value) => value.hasValue)
+        .map((value) => value.value));
+    return new UnmodifiableListView(list);
+  }
+
+  /// Whether the wrapped stream has been closed.
+  bool _isDone = false;
+
+  /// Whether [next] has been called but has not yet returned.
+  ///
+  /// This is distinct from `_nextCompleter != null` when [next] is called while
+  /// there are pending values available, until the future it returns completes.
+  bool _isNextPending = false;
+
+  /// Creates a new scheduled stream wrapping [stream].
+  ScheduledStream(this._stream) {
+    _subscription = _stream.listen((value) {
+      for (var c in _forkControllers) {
+        c.add(value);
+      }
+      if (_hasNextCompleter != null) {
+        _hasNextCompleter.complete(true);
+        _hasNextCompleter = null;
+      }
+
+      if (_nextCompleter != null) {
+        _nextCompleter.complete(value);
+        _emittedValues.add(value);
+        _nextCompleter = null;
+        _isNextPending = false;
+      } else {
+        _pendingValues.add(new Fallible.withValue(value));
+      }
+    }, onError: (error, stackTrace) {
+      for (var c in _forkControllers) {
+        c.addError(error, stackTrace);
+      }
+      if (_hasNextCompleter != null) {
+        _hasNextCompleter.completeError(error, stackTrace);
+        _hasNextCompleter = null;
+      }
+
+      if (_nextCompleter != null) {
+        _nextCompleter.completeError(error, stackTrace);
+        _nextCompleter = null;
+      } else {
+        _pendingValues.add(new Fallible.withError(error, stackTrace));
+      }
+    }, onDone: _onDone);
+  }
+
+  /// Enqueue an expectation that [streamMatcher] will match the value(s)
+  /// emitted by the stream at this point in the schedule.
+  ///
+  /// If [streamMatcher] is a [StreamMatcher], it will match the stream as a
+  /// whole. If it's a [Matcher] or another object, it will match the next value
+  /// emitted by the stream (as though it were a [nextValue] matcher).
+  ///
+  /// This call is scheduled; the expectation won't be added until the schedule
+  /// reaches this point, and the schedule won't continue until the matcher has
+  /// matched the stream.
+  void expect(streamMatcher) {
+    streamMatcher = new StreamMatcher.wrap(streamMatcher);
+    var description = 'stream emits $streamMatcher';
+    schedule(() {
+      return streamMatcher.tryMatch(this).then((description) {
+        if (description == null) return;
+
+        var expected = prefixLines(streamMatcher.toString(),
+            firstPrefix: 'Expected: ',
+            prefix:      '        | ');
+
+        var actual = prefixLines(allValues.map((value) {
+          return prefixLines(value.toString(), firstPrefix: '* ');
+        }).join('\n'),
+            firstPrefix: ' Emitted: ',
+            prefix:      '          ');
+
+        var which = '';
+        if (description.length > 0) {
+          which = '\n' + prefixLines(description.toString(),
+              firstPrefix: '   Which: ',
+              prefix:      '        | ');
+        }
+
+        fail("$expected\n$actual$which");
+      });
+    }, description);
+  }
+
+  /// Returns a Future that completes to the next value emitted by this stream.
+  ///
+  /// It's a [StateError] to call [next] when another call's Future has not yet
+  /// completed, or when the stream has no more values. The latter can be
+  /// checked using [hasNext].
+  Future<T> next() {
+    if (_isNextPending) {
+      return new Future.error(
+          new StateError("There's already a pending call to "
+              "ScheduledStream.next."),
+          new Chain.current());
+    }
+
+    if (_pendingValues.isNotEmpty) {
+      _isNextPending = true;
+
+      var valueOrError = _pendingValues.removeFirst();
+      if (valueOrError.hasValue) {
+        _emittedValues.add(valueOrError.value);
+      }
+      return valueOrError.toFuture().whenComplete(() {
+        _isNextPending = false;
+      });
+    } else if (_isDone) {
+      return new Future.error(
+          new StateError("ScheduledStream has no more elements."),
+          new Chain.current());
+    }
+
+    _isNextPending = true;
+    _nextCompleter = new Completer();
+    return _nextCompleter.future;
+  }
+
+  /// Returns a Future that completes to a boolean indicating whether the stream
+  /// has additional values or not.
+  Future<bool> get hasNext {
+    if (_hasNextCompleter != null) return _hasNextCompleter.future;
+
+    if (_pendingValues.isNotEmpty) {
+      return _pendingValues.first.toFuture().then((_) => true);
+    } else if (_isDone) {
+      return new Future.value(false);
+    }
+
+    _hasNextCompleter = new Completer();
+    return _hasNextCompleter.future;
+  }
+
+  /// Returns a fork of this stream.
+  ///
+  /// The fork begins at the same point [this] is at. Values can be read from it
+  /// without consuming values in [this]. If [this] is closed, the fork will be
+  /// closed at whatever point it's currently at.
+  ScheduledStream<T> fork() {
+    var controller = new StreamController<T>();
+    for (var valueOrError in _pendingValues) {
+      if (valueOrError.hasValue) {
+        controller.add(valueOrError.value);
+      } else {
+        controller.addError(valueOrError.error, valueOrError.stackTrace);
+      }
+    }
+    if (_isDone) {
+      controller.close();
+    } else {
+      _forkControllers.add(controller);
+    }
+
+    var fork = new ScheduledStream<T>(controller.stream);
+    _forks.add(fork);
+    return fork;
+  }
+
+  /// Closes this stream.
+  ///
+  /// This cancels the subscription to the underlying stream and acts as though
+  /// [this] was closed immediately after the current position, regardless of
+  /// whether the underlying stream has emitted additional events.
+  void close() {
+    _subscription.cancel();
+    _pendingValues.clear();
+
+    for (var fork in _forks) {
+      fork.close();
+    }
+    _forks.clear();
+
+    if (!_isDone) _onDone();
+  }
+
+  /// Handles a "done" event from the underlying stream, as well as [this] being
+  /// closed.
+  void _onDone() {
+    for (var c in _forkControllers) {
+      c.close();
+    }
+    _forkControllers.clear();
+
+    if (_hasNextCompleter != null) {
+      _hasNextCompleter.complete(false);
+      _hasNextCompleter = null;
+    }
+
+    if (_nextCompleter != null) {
+      _nextCompleter.completeError(
+          new StateError("ScheduledStream has no more elements."),
+          new Chain.current());
+      _nextCompleter = null;
+      _isNextPending = false;
+    }
+
+    _isDone = true;
+  }
+}
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
deleted file mode 100644
index 4c9abe7..0000000
--- a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
+++ /dev/null
@@ -1,150 +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 safe_http_server;
-
-import 'dart:async';
-import 'dart:io';
-
-// TODO(nweiz): remove this when issue 9140 is fixed.
-/// A wrapper around [HttpServer] that swallows errors caused by requests
-/// behaving badly. This provides the following guarantees:
-///
-/// * The [SafeHttpServer.listen] onError callback will only emit server-wide
-///   errors. It will not emit errors for requests that were unparseable or
-///   where the connection was closed too soon.
-/// * [HttpResponse.done] will emit no errors.
-///
-/// The [HttpRequest] data stream can still emit errors.
-class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
-  final HttpServer _inner;
-
-  static Future<SafeHttpServer> bind([String host = "localhost",
-      int port = 0, int backlog = 0]) {
-    return HttpServer.bind(host, port, backlog: backlog)
-        .then((server) => new SafeHttpServer(server));
-  }
-
-  SafeHttpServer(HttpServer server)
-      : super(server),
-        _inner = server;
-
-  Future close({bool force: false}) => _inner.close(force: force);
-
-  InternetAddress get address => _inner.address;
-  int get port => _inner.port;
-
-  set sessionTimeout(int timeout) {
-    _inner.sessionTimeout = timeout;
-  }
-
-  HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
-
-  StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
-      {Function onError, void onDone(),
-      bool cancelOnError: false}) {
-    var subscription;
-    subscription = super.listen((request) {
-      onData(new _HttpRequestWrapper(request));
-    }, onError: (error, stackTrace) {
-      // Ignore socket error 104, which is caused by a request being cancelled
-      // before it writes any headers. There's no reason to care about such
-      // requests.
-      if (error is SocketException && error.osError.errorCode == 104) return;
-      // Ignore any parsing errors, which come from malformed requests.
-      if (error is HttpException) return;
-      // Manually handle cancelOnError so the above (ignored) errors don't
-      // cause unsubscription.
-      if (cancelOnError) subscription.cancel();
-      if (onError != null) {
-        if (onError is ZoneBinaryCallback) {
-          onError(error, stackTrace);
-        } else {
-          onError(error);
-        }
-      }
-    }, onDone: onDone);
-    return subscription;
-  }
-}
-
-/// A wrapper around [HttpRequest] for the sole purpose of swallowing errors on
-/// [HttpResponse.done].
-class _HttpRequestWrapper extends StreamView<List<int>> implements HttpRequest {
-  final HttpRequest _inner;
-  final HttpResponse response;
-
-  _HttpRequestWrapper(HttpRequest inner)
-      : super(inner),
-        _inner = inner,
-        response = new _HttpResponseWrapper(inner.response);
-
-  int get contentLength => _inner.contentLength;
-  String get method => _inner.method;
-  Uri get uri => _inner.uri;
-  HttpHeaders get headers => _inner.headers;
-  List<Cookie> get cookies => _inner.cookies;
-  bool get persistentConnection => _inner.persistentConnection;
-  X509Certificate get certificate => _inner.certificate;
-  HttpSession get session => _inner.session;
-  String get protocolVersion => _inner.protocolVersion;
-  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
-}
-
-/// A wrapper around [HttpResponse] for the sole purpose of swallowing errors on
-/// [done].
-class _HttpResponseWrapper implements HttpResponse {
-  final HttpResponse _inner;
-  Future<HttpResponse> _done;
-
-  _HttpResponseWrapper(this._inner);
-
-  /// Swallows all errors from writing to the response.
-  Future<HttpResponse> get done {
-    if (_done == null) _done = _inner.done.catchError((_) {});
-    return _done;
-  }
-
-  int get contentLength => _inner.contentLength;
-  set contentLength(int value) {
-    _inner.contentLength = value;
-  }
-
-  int get statusCode => _inner.statusCode;
-  set statusCode(int value) {
-    _inner.statusCode = value;
-  }
-
-  String get reasonPhrase => _inner.reasonPhrase;
-  set reasonPhrase(String value) {
-    _inner.reasonPhrase = value;
-  }
-
-  bool get persistentConnection => _inner.persistentConnection;
-  set persistentConnection(bool value) {
-    _inner.persistentConnection = value;
-  }
-
-  Encoding get encoding => _inner.encoding;
-  set encoding(Encoding value) {
-    _inner.encoding = value;
-  }
-
-  HttpHeaders get headers => _inner.headers;
-  List<Cookie> get cookies => _inner.cookies;
-  Future<Socket> detachSocket() => _inner.detachSocket();
-  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
-  void add(List<int> data) => _inner.add(data);
-  Future<HttpResponse> addStream(Stream<List<int>> stream) =>
-    _inner.addStream(stream);
-  Future close() => _inner.close();
-  Future flush() => _inner.flush();
-  void write(Object obj) => _inner.write(obj);
-  void writeAll(Iterable objects, [String separator = ""]) =>
-    _inner.writeAll(objects, separator);
-  void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
-  void writeln([Object obj = ""]) => _inner.writeln(obj);
-  void addError(error, [StackTrace stackTrace]) =>
-      _inner.addError(error, stackTrace);
-}
diff --git a/pkg/scheduled_test/lib/src/stream_matcher.dart b/pkg/scheduled_test/lib/src/stream_matcher.dart
new file mode 100644
index 0000000..f1e65da
--- /dev/null
+++ b/pkg/scheduled_test/lib/src/stream_matcher.dart
@@ -0,0 +1,294 @@
+// 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 scheduled_test.stream_matcher;
+
+import 'dart:async';
+import 'dart:collection';
+
+import '../scheduled_stream.dart';
+import '../scheduled_test.dart';
+import 'utils.dart';
+
+/// An abstract superclass for matchers that validate and consume zero or more
+/// values emitted by a [ScheduledStream].
+///
+/// [StreamMatcher]s are most commonly used by passing them to
+/// [ScheduledStream.expect].
+abstract class StreamMatcher {
+  /// Wrap a [Matcher], [StreamMatcher] or [Object] in a [StreamMatcher].
+  ///
+  /// If this isn't a [StreamMatcher], a [nextValue] matcher is used.
+  factory StreamMatcher.wrap(matcher) =>
+      matcher is StreamMatcher ? matcher : nextValue(matcher);
+
+  /// Tries to match [this] against [stream].
+  ///
+  /// If the match succeeds, this returns `null`. If it fails, this returns a
+  /// [Description] describing the failure.
+  Future<Description> tryMatch(ScheduledStream stream);
+
+  String toString();
+}
+
+/// A matcher that consumes and matches a single value.
+///
+/// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
+StreamMatcher nextValue(matcher) => new _NextValueMatcher(matcher);
+
+/// A matcher that consumes [n] values and matches a list containing those
+/// objects against [matcher].
+///
+/// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
+StreamMatcher nextValues(int n, matcher) => new _NextValuesMatcher(n, matcher);
+
+/// A matcher that matches several sub-matchers in sequence.
+///
+/// Each element of [streamMatchers] can be a [StreamMatcher], a [Matcher], or
+/// an [Object].
+StreamMatcher inOrder(Iterable streamMatchers) {
+  streamMatchers = streamMatchers.toList();
+  if (streamMatchers.length == 1) {
+    return new StreamMatcher.wrap(streamMatchers.first);
+  } else {
+    return new _InOrderMatcher(streamMatchers);
+  }
+}
+
+/// A matcher that consumes values emitted by a stream until one matching
+/// [matcher] is emitted.
+///
+/// This will fail if the stream never emits a value that matches [matcher].
+///
+/// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
+StreamMatcher consumeThrough(matcher) => new _ConsumeThroughMatcher(matcher);
+
+/// A matcher that matches either [streamMatcher1], [streamMatcher2], or both.
+///
+/// If both matchers match the stream, the one that consumed more values will be
+/// used.
+///
+/// Both [streamMatcher1] and [streamMatcher2] can be a [StreamMatcher], a
+/// [Matcher], or an [Object].
+StreamMatcher either(streamMatcher1, streamMatcher2) =>
+  new _EitherMatcher(streamMatcher1, streamMatcher2);
+
+/// A matcher that consumes [streamMatcher] if it matches, or nothing otherwise.
+///
+/// This matcher will always match a stream. It exists to consume values that
+/// may or may not be emitted by a stream.
+///
+/// [streamMatcher] can be a [StreamMatcher], a [Matcher], or an [Object].
+StreamMatcher allow(streamMatcher) => new _AllowMatcher(streamMatcher);
+
+/// A matcher that matches a stream that emits no more values.
+StreamMatcher get isDone => new _IsDoneMatcher();
+
+/// See [nextValue].
+class _NextValueMatcher implements StreamMatcher {
+  final Matcher _matcher;
+
+  _NextValueMatcher(matcher)
+      : _matcher = wrapMatcher(matcher);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    return stream.hasNext.then((hasNext) {
+      if (!hasNext) {
+        return new StringDescription("unexpected end of stream");
+      }
+      return stream.next().then((value) {
+        var matchState = {};
+        if (_matcher.matches(value, matchState)) return null;
+        return _matcher.describeMismatch(value, new StringDescription(),
+            matchState, false);
+      });
+    });
+  }
+
+  String toString() => _matcher.describe(new StringDescription()).toString();
+}
+
+/// See [nextValues].
+class _NextValuesMatcher implements StreamMatcher {
+  final int _n;
+  final Matcher _matcher;
+
+  _NextValuesMatcher(this._n, matcher)
+      : _matcher = wrapMatcher(matcher);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    var collectedValues = [];
+    collectValues(count) {
+      if (count == 0) return null;
+
+      return stream.hasNext.then((hasNext) {
+        if (!hasNext) return new StringDescription('unexpected end of stream');
+
+        return stream.next().then((value) {
+          collectedValues.add(value);
+          return collectValues(count - 1);
+        });
+      });
+    }
+
+    return collectValues(_n).then((description) {
+      if (description != null) return description;
+      var matchState = {};
+      if (_matcher.matches(collectedValues, matchState)) return null;
+      return _matcher.describeMismatch(collectedValues, new StringDescription(),
+          matchState, false);
+    });
+  }
+
+  String toString() {
+    return new StringDescription('$_n values that ')
+        .addDescriptionOf(_matcher)
+        .toString();
+  }
+}
+
+/// See [inOrder].
+class _InOrderMatcher implements StreamMatcher {
+  final List<StreamMatcher> _matchers;
+
+  _InOrderMatcher(Iterable streamMatchers)
+      : _matchers = streamMatchers.map((matcher) =>
+          new StreamMatcher.wrap(matcher)).toList();
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    var matchers = new Queue.from(_matchers);
+
+    matchNext() {
+      if (matchers.isEmpty) return new Future.value();
+      var matcher = matchers.removeFirst();
+      return matcher.tryMatch(stream).then((description) {
+        if (description == null) return matchNext();
+        var newDescription = new StringDescription(
+              'matcher #${_matchers.length - matchers.length} failed');
+        if (description.length != 0) newDescription.add(':\n$description');
+        return newDescription;
+      });
+    }
+
+    return matchNext();
+  }
+
+  String toString() => _matchers
+      .map((matcher) => prefixLines(matcher.toString(), firstPrefix: '* '))
+      .join('\n');
+}
+
+/// See [consumeThrough].
+class _ConsumeThroughMatcher implements StreamMatcher {
+  final Matcher _matcher;
+
+  _ConsumeThroughMatcher(matcher)
+      : _matcher = wrapMatcher(matcher);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    consumeNext() {
+      return stream.hasNext.then((hasNext) {
+        if (!hasNext) return new StringDescription("unexpected end of stream");
+
+        return stream.next().then((value) {
+          if (_matcher.matches(value, {})) return null;
+          return consumeNext();
+        });
+      });
+    }
+
+    return consumeNext();
+  }
+
+  String toString() {
+    return new StringDescription('values followed by ')
+      .addDescriptionOf(_matcher).toString();
+  }
+}
+
+/// See [either].
+class _EitherMatcher implements StreamMatcher {
+  final StreamMatcher _matcher1;
+  final StreamMatcher _matcher2;
+
+  _EitherMatcher(streamMatcher1, streamMatcher2)
+      : _matcher1 = new StreamMatcher.wrap(streamMatcher1),
+        _matcher2 = new StreamMatcher.wrap(streamMatcher2);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    var stream1 = stream.fork();
+    var stream2 = stream.fork();
+
+    return Future.wait([
+      _matcher1.tryMatch(stream1).whenComplete(stream1.close),
+      _matcher2.tryMatch(stream2).whenComplete(stream2.close)
+    ]).then((descriptions) {
+      var description1 = descriptions.first;
+      var description2 = descriptions.last;
+
+      // If both matchers matched, use the one that consumed more of the stream.
+      if (description1 == null && description2 == null) {
+        if (stream1.emittedValues.length >= stream2.emittedValues.length) {
+          return _matcher1.tryMatch(stream);
+        } else {
+          return _matcher2.tryMatch(stream);
+        }
+      } else if (description1 == null) {
+        return _matcher1.tryMatch(stream);
+      } else if (description2 == null) {
+        return _matcher2.tryMatch(stream);
+      } else {
+        return new StringDescription('both\n')
+            .add(prefixLines(description1.toString(), prefix: '  '))
+            .add('\nand\n')
+            .add(prefixLines(description2.toString(), prefix: '  '))
+            .toString();
+      }
+    });
+  }
+
+  String toString() {
+    return new StringDescription('either\n')
+        .add(prefixLines(_matcher1.toString(), prefix: '  '))
+        .add('\nor\n')
+        .add(prefixLines(_matcher2.toString(), prefix: '  '))
+        .toString();
+  }
+}
+
+/// See [allow].
+class _AllowMatcher implements StreamMatcher {
+  final StreamMatcher _matcher;
+
+  _AllowMatcher(streamMatcher)
+      : _matcher = new StreamMatcher.wrap(streamMatcher);
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    var fork = stream.fork();
+    return _matcher.tryMatch(fork).whenComplete(fork.close).then((description) {
+      if (description != null) return null;
+      return _matcher.tryMatch(stream);
+    });
+  }
+
+  String toString() {
+    return new StringDescription('allow\n')
+        .add(prefixLines(_matcher.toString()))
+        .toString();
+  }
+}
+
+/// See [isDone].
+class _IsDoneMatcher implements StreamMatcher {
+  _IsDoneMatcher();
+
+  Future<Description> tryMatch(ScheduledStream stream) {
+    return stream.hasNext.then((hasNext) {
+      if (!hasNext) return null;
+      return new StringDescription("stream wasn't finished");
+    });
+  }
+
+  String toString() => 'is done';
+}
diff --git a/pkg/scheduled_test/lib/src/utils.dart b/pkg/scheduled_test/lib/src/utils.dart
index 9cba044..e767e02 100644
--- a/pkg/scheduled_test/lib/src/utils.dart
+++ b/pkg/scheduled_test/lib/src/utils.dart
@@ -25,6 +25,81 @@
   int get hashCode => first.hashCode ^ last.hashCode;
 }
 
+/// A class that represents a value or an error.
+class Fallible<E> {
+  /// Whether [this] has a [value], as opposed to an [error].
+  final bool hasValue;
+
+  /// Whether [this] has an [error], as opposed to a [value].
+  bool get hasError => !hasValue;
+
+  /// The value.
+  ///
+  /// This will be `null` if [this] has an [error].
+  final E _value;
+
+  /// The value.
+  ///
+  /// This will throw a [StateError] if [this] has an [error].
+  E get value {
+    if (hasValue) return _value;
+    throw new StateError("Fallible has no value.\n"
+        "$_error$_stackTraceSuffix");
+  }
+
+  /// The error.
+  ///
+  /// This will be `null` if [this] has a [value].
+  final _error;
+
+  /// The error.
+  ///
+  /// This will throw a [StateError] if [this] has a [value].
+  get error {
+    if (hasError) return _error;
+    throw new StateError("Fallible has no error.");
+  }
+
+  /// The stack trace for [_error].
+  ///
+  /// This will be `null` if [this] has a [value], or if no stack trace was
+  /// provided.
+  final StackTrace _stackTrace;
+
+  /// The stack trace for [error].
+  ///
+  /// This will throw a [StateError] if [this] has a [value].
+  StackTrace get stackTrace {
+    if (hasError) return _stackTrace;
+    throw new StateError("Fallible has no error.");
+  }
+
+  Fallible.withValue(this._value)
+      : _error = null,
+        _stackTrace = null,
+        hasValue = true;
+
+  Fallible.withError(this._error, [this._stackTrace])
+      : _value = null,
+        hasValue = false;
+
+  /// Returns a completed Future with the same value or error as [this].
+  Future toFuture() {
+    if (hasValue) return new Future.value(value);
+    return new Future.error(error, stackTrace);
+  }
+
+  String toString() {
+    if (hasValue) return "Fallible value: $value";
+    return "Fallible error: $error$_stackTraceSuffix";
+  }
+
+  String get _stackTraceSuffix {
+    if (stackTrace == null) return "";
+    return "\nStack trace:\n${new Chain.forTrace(_stackTrace).terse}";
+  }
+}
+
 /// Configures [future] so that its result (success or exception) is passed on
 /// to [completer].
 void chainToCompleter(Future future, Completer completer) {
@@ -231,12 +306,5 @@
 /// Returns a string representation of [trace] that has the core and test frames
 /// folded together.
 String terseTraceString(StackTrace trace) {
-  return new Chain(new Chain.forTrace(trace).traces.map((trace) {
-    return trace.foldFrames((frame) {
-      return frame.package == 'scheduled_test' ||
-             frame.package == 'unittest' ||
-             frame.package == 'stack_trace' ||
-             frame.isCore;
-    });
-  })).terse.toString().trim();
+  return new Chain.forTrace(trace).terse.toString().trim();
 }
diff --git a/pkg/scheduled_test/pubspec.yaml b/pkg/scheduled_test/pubspec.yaml
index 7fd928e..69bbb2c 100644
--- a/pkg/scheduled_test/pubspec.yaml
+++ b/pkg/scheduled_test/pubspec.yaml
@@ -1,5 +1,5 @@
 name: scheduled_test
-version: 0.9.2
+version: 0.9.3-dev
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/scheduled_test/test/scheduled_stream/scheduled_stream_test.dart b/pkg/scheduled_test/test/scheduled_stream/scheduled_stream_test.dart
new file mode 100644
index 0000000..92dc027
--- /dev/null
+++ b/pkg/scheduled_test/test/scheduled_stream/scheduled_stream_test.dart
@@ -0,0 +1,396 @@
+// 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 scheduled_test.scheduled_stream_test;
+
+import 'dart:async';
+
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:unittest/unittest.dart';
+import 'package:scheduled_test/src/utils.dart';
+
+void main() {
+  group("a completed stream with no elements", () {
+    var stream;
+    setUp(() {
+      var controller = new StreamController()..close();
+      stream = new ScheduledStream(controller.stream);
+
+      // Wait for [stream] to register the wrapped stream's close event.
+      return pumpEventQueue();
+    });
+
+    test("throws an error for [next]", () {
+      expect(stream.next(), throwsStateError);
+    });
+
+    test("returns false for [hasNext]", () {
+      expect(stream.hasNext, completion(isFalse));
+    });
+
+    test("emittedValues is empty", () {
+      expect(stream.emittedValues, isEmpty);
+    });
+
+    test("allValues is empty", () {
+      expect(stream.allValues, isEmpty);
+    });
+
+    test("close() does nothing", () {
+      // This just shouldn't throw any exceptions.
+      stream.close();
+    });
+
+    test("fork() returns a closed stream", () {
+      var fork = stream.fork();
+      expect(fork.emittedValues, isEmpty);
+      expect(fork.allValues, isEmpty);
+      expect(fork.next(), throwsStateError);
+      expect(fork.hasNext, completion(isFalse));
+    });
+  });
+
+  group("a stream that completes later with no elements", () {
+    var controller;
+    var stream;
+    setUp(() {
+      controller = new StreamController();
+      stream = new ScheduledStream(controller.stream);
+    });
+
+    test("throws an error for [next]", () {
+      expect(stream.next(), throwsStateError);
+      return new Future(controller.close);
+    });
+
+    test("returns false for [hasNext]", () {
+      expect(stream.hasNext, completion(isFalse));
+      return new Future(controller.close);
+    });
+
+    test("emittedValues is empty", () {
+      expect(stream.emittedValues, isEmpty);
+    });
+
+    test("allValues is empty", () {
+      expect(stream.allValues, isEmpty);
+    });
+
+    test("fork() returns a stream that closes when the controller is closed",
+        () {
+      var fork = stream.fork();
+      expect(fork.emittedValues, isEmpty);
+      expect(fork.allValues, isEmpty);
+
+      var nextComplete = false;
+      expect(fork.next().whenComplete(() {
+        nextComplete = true;
+      }), throwsStateError);
+
+      var hasNextComplete = false;
+      expect(fork.hasNext.whenComplete(() {
+        hasNextComplete = true;
+      }), completion(isFalse));
+
+      // Pump the event queue to give [next] and [hasNext] a chance to
+      // (incorrectly) fire.
+      return pumpEventQueue().then((_) {
+        expect(nextComplete, isFalse);
+        expect(hasNextComplete, isFalse);
+
+        controller.close();
+      });
+    });
+  });
+
+  test("forking and then closing a stream closes the fork", () {
+    var stream = new ScheduledStream(new StreamController().stream);
+    var fork = stream.fork();
+    expect(fork.emittedValues, isEmpty);
+    expect(fork.allValues, isEmpty);
+
+    var nextComplete = false;
+    expect(fork.next().whenComplete(() {
+      nextComplete = true;
+    }), throwsStateError);
+
+    var hasNextComplete = false;
+    expect(fork.hasNext.whenComplete(() {
+      hasNextComplete = true;
+    }), completion(isFalse));
+
+    // Pump the event queue to give [next] and [hasNext] a chance to
+    // (incorrectly) fire.
+    return pumpEventQueue().then((_) {
+      expect(nextComplete, isFalse);
+      expect(hasNextComplete, isFalse);
+
+      stream.close();
+    });
+  });
+
+  group("a completed stream with several values", () {
+    var stream;
+    setUp(() {
+      var controller = new StreamController<int>()
+          ..add(1)..add(2)..add(3)..close();
+      stream = new ScheduledStream<int>(controller.stream);
+
+      return pumpEventQueue();
+    });
+
+    test("next() returns each value then throws an error", () {
+      return stream.next().then((value) {
+        expect(value, equals(1));
+        return stream.next();
+      }).then((value) {
+        expect(value, equals(2));
+        return stream.next();
+      }).then((value) {
+        expect(value, equals(3));
+        expect(stream.next(), throwsStateError);
+      });
+    });
+
+    test("parallel next() calls are disallowed", () {
+      expect(stream.next(), completion(equals(1)));
+      expect(stream.next(), throwsStateError);
+    });
+
+    test("parallel hasNext calls are allowed", () {
+      expect(stream.hasNext, completion(isTrue));
+      expect(stream.hasNext, completion(isTrue));
+    });
+
+    test("hasNext returns true until there are no more values", () {
+      return stream.hasNext.then((hasNext) {
+        expect(hasNext, isTrue);
+        return stream.next();
+      }).then((_) => stream.hasNext).then((hasNext) {
+        expect(hasNext, isTrue);
+        return stream.next();
+      }).then((_) => stream.hasNext).then((hasNext) {
+        expect(hasNext, isTrue);
+        return stream.next();
+      }).then((_) => expect(stream.hasNext, completion(isFalse)));
+    });
+
+    test("emittedValues returns the values that have been emitted", () {
+      expect(stream.emittedValues, isEmpty);
+
+      return stream.next().then((_) {
+        expect(stream.emittedValues, equals([1]));
+        return stream.next();
+      }).then((_) {
+        expect(stream.emittedValues, equals([1, 2]));
+        return stream.next();
+      }).then((_) {
+        expect(stream.emittedValues, equals([1, 2, 3]));
+      });
+    });
+
+    test("allValues returns all values that the inner stream emitted", () {
+      expect(stream.allValues, equals([1, 2, 3]));
+    });
+
+    test("closing the stream means it doesn't emit additional events", () {
+      return stream.next().then((_) {
+        stream.close();
+        expect(stream.next(), throwsStateError);
+      });
+    });
+
+    test("a fork created before any values are emitted emits all values", () {
+      var fork = stream.fork();
+      return fork.next().then((value) {
+        expect(value, equals(1));
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(2));
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(3));
+        expect(fork.next(), throwsStateError);
+      });
+    });
+
+    test("a fork created after some values are emitted emits remaining values",
+        () {
+      var fork;
+      return stream.next().then((_) {
+        fork = stream.fork();
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(2));
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(3));
+        expect(fork.next(), throwsStateError);
+      });
+    });
+
+    test("a fork doesn't push forward its parent stream", () {
+      var fork = stream.fork();
+      return fork.next().then((_) {
+        expect(stream.next(), completion(equals(1)));
+      });
+    });
+
+    test("closing a fork doesn't close its parent stream", () {
+      var fork = stream.fork();
+      fork.close();
+      expect(stream.next(), completion(equals(1)));
+    });
+
+    test("closing a stream closes its forks immediately", () {
+      var fork = stream.fork();
+      return stream.next().then((_) {
+        stream.close();
+        expect(fork.next(), throwsStateError);
+      });
+    });
+  });
+
+  group("a stream with several values added asynchronously", () {
+    var stream;
+    setUp(() {
+      var controller = new StreamController<int>();
+      stream = new ScheduledStream<int>(controller.stream);
+
+      pumpEventQueue().then((_) {
+        controller.add(1);
+        return pumpEventQueue();
+      }).then((_) {
+        controller.add(2);
+        return pumpEventQueue();
+      }).then((_) {
+        controller.add(3);
+        return pumpEventQueue();
+      }).then((_) {
+        controller.close();
+      });
+    });
+
+    test("next() returns each value then throws an error", () {
+      return stream.next().then((value) {
+        expect(value, equals(1));
+        return stream.next();
+      }).then((value) {
+        expect(value, equals(2));
+        return stream.next();
+      }).then((value) {
+        expect(value, equals(3));
+        expect(stream.next(), throwsStateError);
+      });
+    });
+
+    test("parallel next() calls are disallowed", () {
+      expect(stream.next(), completion(equals(1)));
+      expect(stream.next(), throwsStateError);
+    });
+
+    test("parallel hasNext calls are allowed", () {
+      expect(stream.hasNext, completion(isTrue));
+      expect(stream.hasNext, completion(isTrue));
+    });
+
+    test("hasNext returns true until there are no more values", () {
+      return stream.hasNext.then((hasNext) {
+        expect(hasNext, isTrue);
+        return stream.next();
+      }).then((_) => stream.hasNext).then((hasNext) {
+        expect(hasNext, isTrue);
+        return stream.next();
+      }).then((_) => stream.hasNext).then((hasNext) {
+        expect(hasNext, isTrue);
+        return stream.next();
+      }).then((_) => expect(stream.hasNext, completion(isFalse)));
+    });
+
+    test("emittedValues returns the values that have been emitted", () {
+      expect(stream.emittedValues, isEmpty);
+
+      return stream.next().then((_) {
+        expect(stream.emittedValues, equals([1]));
+        return stream.next();
+      }).then((_) {
+        expect(stream.emittedValues, equals([1, 2]));
+        return stream.next();
+      }).then((_) {
+        expect(stream.emittedValues, equals([1, 2, 3]));
+      });
+    });
+
+    test("allValues returns all values that the inner stream emitted", () {
+      expect(stream.allValues, isEmpty);
+
+      return stream.next().then((_) {
+        expect(stream.allValues, equals([1]));
+        return stream.next();
+      }).then((_) {
+        expect(stream.allValues, equals([1, 2]));
+        return stream.next();
+      }).then((_) {
+        expect(stream.allValues, equals([1, 2, 3]));
+      });
+    });
+
+    test("closing the stream means it doesn't emit additional events", () {
+      return stream.next().then((_) {
+        stream.close();
+        expect(stream.next(), throwsStateError);
+      });
+    });
+
+    test("a fork created before any values are emitted emits all values", () {
+      var fork = stream.fork();
+      return fork.next().then((value) {
+        expect(value, equals(1));
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(2));
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(3));
+        expect(fork.next(), throwsStateError);
+      });
+    });
+
+    test("a fork created after some values are emitted emits remaining values",
+        () {
+      var fork;
+      return stream.next().then((_) {
+        fork = stream.fork();
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(2));
+        return fork.next();
+      }).then((value) {
+        expect(value, equals(3));
+        expect(fork.next(), throwsStateError);
+      });
+    });
+
+    test("a fork doesn't push forward its parent stream", () {
+      var fork = stream.fork();
+      return fork.next().then((_) {
+        expect(stream.next(), completion(equals(1)));
+      });
+    });
+
+    test("closing a fork doesn't close its parent stream", () {
+      var fork = stream.fork();
+      fork.close();
+      expect(stream.next(), completion(equals(1)));
+    });
+
+    test("closing a stream closes its forks immediately", () {
+      var fork = stream.fork();
+      return stream.next().then((_) {
+        stream.close();
+        expect(fork.next(), throwsStateError);
+      });
+    });
+  });
+}
diff --git a/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart b/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart
new file mode 100644
index 0000000..b08fc37
--- /dev/null
+++ b/pkg/scheduled_test/test/scheduled_stream/stream_matcher_test.dart
@@ -0,0 +1,288 @@
+// 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 scheduled_test.stream_matcher_test;
+
+import 'dart:async';
+
+import 'package:scheduled_test/scheduled_stream.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+import 'package:scheduled_test/src/utils.dart';
+
+import '../metatest.dart';
+import '../utils.dart';
+
+/// Returns a [ScheduledStream] that asynchronously emits the numbers 1 through
+/// 5 and then closes.
+ScheduledStream createStream() {
+  var controller = new StreamController();
+  var stream = new ScheduledStream(controller.stream);
+
+  var future = pumpEventQueue();
+  for (var i = 1; i <= 5; i++) {
+    future = future.then((_) {
+      controller.add(i);
+      return pumpEventQueue();
+    });
+  }
+  future.then((_) => controller.close());
+
+  return stream;
+}
+
+void main(_, message) {
+  initMetatest(message);
+
+  setUpTimeout();
+
+  expectTestPasses("expect() with matching values passes", () {
+    var stream = createStream();
+    stream.expect(1);
+    stream.expect(2);
+    stream.expect(3);
+    stream.expect(4);
+    stream.expect(5);
+  });
+
+  expectTestFails("expect() with a non-matching value fails", () {
+    var stream = createStream();
+    stream.expect(1);
+    stream.expect(2);
+    stream.expect(100);
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: <100>\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3"));
+  });
+
+  expectTestFails("expect() with too few values fails", () {
+    var stream = createStream();
+    stream.expect(1);
+    stream.expect(2);
+    stream.expect(3);
+    stream.expect(4);
+    stream.expect(5);
+    stream.expect(6);
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: <6>\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "          * 4\n"
+        "          * 5\n"
+        "   Which: unexpected end of stream"));
+  });
+
+  expectTestPasses("expect() with matching matcher passes", () {
+    var stream = createStream();
+    stream.expect(greaterThan(0));
+    stream.expect(greaterThan(1));
+    stream.expect(greaterThan(2));
+    stream.expect(greaterThan(3));
+    stream.expect(greaterThan(4));
+  });
+
+  expectTestFails("expect() with a non-matching matcher fails", () {
+    var stream = createStream();
+    stream.expect(greaterThan(0));
+    stream.expect(greaterThan(1));
+    stream.expect(greaterThan(100));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: a value greater than <100>\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "   Which: is not a value greater than <100>"));
+  });
+
+  expectTestPasses("nextValues() with matching values succeeds", () {
+    createStream().expect(nextValues(3, unorderedEquals([3, 2, 1])));
+  });
+
+  expectTestFails("nextValues() without enough values fails", () {
+    createStream().expect(nextValues(6, unorderedEquals([3, 2, 1])));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: 6 values that equals [3, 2, 1] unordered\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "          * 4\n"
+        "          * 5\n"
+        "   Which: unexpected end of stream"));
+  });
+
+  expectTestFails("nextValues() with non-matching values fails", () {
+    createStream().expect(nextValues(3, unorderedEquals([2, 3, 4])));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: 3 values that equals [2, 3, 4] unordered\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "   Which: has no match for <4> at index 2"));
+  });
+
+  expectTestPasses("inOrder() with several values matches and consumes those "
+      "values", () {
+    var stream = createStream();
+    stream.expect(inOrder([1, 2, 3, 4]));
+    stream.expect(5);
+  });
+
+  expectTestPasses("inOrder() with several stream matchers matches them", () {
+    createStream().expect(inOrder([
+      consumeThrough(3),
+      nextValues(2, unorderedEquals([5, 4]))
+    ]));
+  });
+
+  expectTestPasses("inOrder() with no values succeeds and consumes nothing",
+      () {
+    var stream = createStream();
+    stream.expect(inOrder([]));
+    stream.expect(1);
+  });
+
+  expectTestFails("inOrder() fails if a sub-matcher fails", () {
+    createStream().expect(inOrder([
+      nextValues(3, unorderedEquals([2, 3, 4])),
+      consumeThrough(5)
+    ]));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: * 3 values that equals [2, 3, 4] unordered\n"
+        "        | * values followed by <5>\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "   Which: matcher #1 failed:\n"
+        "        | has no match for <4> at index 2"));
+  });
+
+  expectTestFails("inOrder() with one value has a simpler description", () {
+    createStream().expect(inOrder([100]));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: <100>\n"
+        " Emitted: * 1"));
+  });
+
+  expectTestPasses("consumeThrough() consumes values through the given matcher",
+      () {
+    var stream = createStream();
+    stream.expect(consumeThrough(greaterThan(2)));
+    stream.expect(4);
+  });
+
+  expectTestPasses("consumeThrough() will stop if the first value matches", () {
+    var stream = createStream();
+    stream.expect(consumeThrough(1));
+    stream.expect(2);
+  });
+
+  expectTestFails("consumeThrough() will fail if the stream ends before the "
+      "value is reached", () {
+    createStream().expect(consumeThrough(100));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: values followed by <100>\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "          * 4\n"
+        "          * 5\n"
+        "   Which: unexpected end of stream"));
+  });
+
+  expectTestPasses("either() will match if the first branch matches", () {
+    createStream().expect(either(1, 100));
+  });
+
+  expectTestPasses("either() will match if the second branch matches", () {
+    createStream().expect(either(100, 1));
+  });
+
+  expectTestPasses("either() will consume the maximal number of values if both "
+      "branches match", () {
+    // First branch consumes more.
+    var stream = createStream();
+    stream.expect(either(inOrder([1, 2, 3]), 1));
+    stream.expect(4);
+
+    // Second branch consumes more.
+    stream = createStream();
+    stream.expect(either(1, inOrder([1, 2, 3])));
+    stream.expect(4);
+  });
+
+  expectTestFails("either() will fail if neither branch matches", () {
+    createStream().expect(either(
+        inOrder([3, 2, 1]),
+        nextValues(4, unorderedEquals([5, 4, 3, 2]))));
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: either\n"
+        "        |   * <3>\n"
+        "        |   * <2>\n"
+        "        |   * <1>\n"
+        "        | or\n"
+        "        |   4 values that equals [5, 4, 3, 2] unordered\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "          * 4\n"
+        "   Which: both\n"
+        "        |   matcher #1 failed\n"
+        "        | and\n"
+        "        |   has no match for <5> at index 0"));
+  });
+
+  expectTestPasses("allow() consumes the matcher if it matches", () {
+    var stream = createStream();
+    stream.expect(allow(inOrder([1, 2, 3])));
+    stream.expect(4);
+  });
+
+  expectTestPasses("allow() consumes nothing if the matcher doesn't match", () {
+    var stream = createStream();
+    stream.expect(allow(inOrder([1, 2, 100])));
+    stream.expect(1);
+  });
+
+  expectTestPasses("isDone succeeds at the end of the stream", () {
+    var stream = createStream();
+    stream.expect(consumeThrough(5));
+    stream.expect(isDone);
+  });
+
+  expectTestFails("isDone fails before the end of the stream", () {
+    var stream = createStream();
+    stream.expect(consumeThrough(4));
+    stream.expect(isDone);
+  }, (errors) {
+    expect(errors, hasLength(1));
+    expect(errors.first.error.message, equals(
+        "Expected: is done\n"
+        " Emitted: * 1\n"
+        "          * 2\n"
+        "          * 3\n"
+        "          * 4\n"
+        "          * 5\n"
+        "   Which: stream wasn't finished"));
+  });
+}
diff --git a/pkg/scheduled_test/test/utils.dart b/pkg/scheduled_test/test/utils.dart
index 6fc24f3..e2b6fcd 100644
--- a/pkg/scheduled_test/test/utils.dart
+++ b/pkg/scheduled_test/test/utils.dart
@@ -58,3 +58,33 @@
     currentSchedule.timeout = new Duration(seconds: 10);
   });
 }
+
+/// Creates a metatest with [body] and asserts that it passes.
+///
+/// This is like [expectTestsPass], but the [test] is set up automatically.
+void expectTestPasses(String description, void body()) =>
+  expectTestsPass(description, () => test('test', body));
+
+/// Creates a metatest that runs [testBody], captures its schedule errors, and
+/// passes them to [validator].
+///
+/// [testBody] is expected to produce an error, while [validator] is expected to
+/// produce none.
+void expectTestFails(String description, void testBody(),
+    void validator(List<ScheduleError> errors)) {
+  expectTestsPass(description, () {
+    var errors;
+    test('test body', () {
+      currentSchedule.onException.schedule(() {
+        errors = currentSchedule.errors;
+      });
+
+      testBody();
+    });
+
+    test('validate errors', () {
+      expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
+      validator(errors);
+    });
+  }, passing: ['validate errors']);
+}
diff --git a/pkg/serialization/lib/serialization.dart b/pkg/serialization/lib/serialization.dart
index 2920d87..b2d3dce 100644
--- a/pkg/serialization/lib/serialization.dart
+++ b/pkg/serialization/lib/serialization.dart
@@ -109,7 +109,7 @@
  * of the object, and functions equivalent to the methods on [CustomRule]
  *
  * ## Constant values
- * 
+ *
  * There are cases where the constructor needs values that we can't easily get
  * from the serialized object. For example, we may just want to pass null, or a
  * constant value. To support this, we can specify as constructor fields
@@ -123,7 +123,7 @@
  * addFoo() method for each entry in the list. In these cases, if you are using
  * a BasicRule for the object you can call the setFieldWith() method.
  *
- *       s..addRuleFor(fooHolderInstance).setFieldWith("foo",
+ *       s..addRuleFor(FooHolder).setFieldWith("foo",
  *           (parent, value) => for (var each in value) parent.addFoo(value));
  *
  * ## Writing
@@ -352,7 +352,7 @@
   /**
    * This writes out an object graph rooted at [object] and returns the result.
    * The [format] parameter determines the form of the result. The default
-   * format returns a String in [json] format.
+   * format is [SimpleMapFormat] and returns a Map.
    */
   write(Object object, {Format format}) {
     return newWriter(format).write(object);
@@ -370,7 +370,7 @@
    * from the result. The [input] can be of any type that the [Format]
    * reads/writes, but normally will be a [List], [Map], or a simple type.
    * The [format] parameter determines the form of the result. The default
-   * format returns a String in [json] format.
+   * format is [SimpleMapFormat] and expects a Map as input.
    * If there are objects that need to be resolved
    * in the current context, they should be provided in [externals] as a
    * Map from names to values. In particular, in the current implementation
@@ -447,26 +447,22 @@
     // or we might just be able to validate that they're correctly set up
     // on the other side.
 
-    // Make some bogus rule instances so we have something to feed rule creation
-    // and get their types. If only we had class literals implemented...
-   var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
-
     var meta = new Serialization()
       ..selfDescribing = false
-      ..addRuleFor(new ListRule())
-      ..addRuleFor(new MapRule())
-      ..addRuleFor(new PrimitiveRule())
-      ..addRuleFor(new ListRuleEssential())
-      ..addRuleFor(basicRule,
+      ..addRuleFor(ListRule)
+      ..addRuleFor(MapRule)
+      ..addRuleFor(PrimitiveRule)
+      ..addRuleFor(ListRuleEssential)
+      ..addRuleFor(BasicRule,
           constructorFields: ['type',
             'constructorName',
             'constructorFields', 'regularFields', []],
           fields: [])
       ..addRule(new NamedObjectRule())
       ..addRule(new MirrorRule())
-      ..addRuleFor(new MirrorRule())
-      ..addRuleFor(new SymbolRule())
-      ..addRuleFor(new DateTimeRule());
+      ..addRuleFor(MirrorRule)
+      ..addRuleFor(SymbolRule)
+      ..addRuleFor(DateTimeRule);
     meta.namedObjects = namedObjects;
     return meta;
   }
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index 7c6b884..36d9aa7 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -97,7 +97,7 @@
    *
    * For example, to serialize a Serialization, we need its rules to be
    * individually added rather than just setting the rules field.
-   *      ..addRuleFor(new Serialization()).setFieldWith('rules',
+   *      ..addRuleFor(Serialization).setFieldWith('rules',
    *          (InstanceMirror s, List rules) {
    *            rules.forEach((x) => s.reflectee.addRule(x));
    * Note that the function is passed the owning object as well as the field
diff --git a/pkg/source_maps/LICENSE b/pkg/source_maps/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/source_maps/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/stack_trace/LICENSE b/pkg/stack_trace/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/stack_trace/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index 74aafcd..7b9c7b1 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -11,16 +11,27 @@
 
 // #1      Foo._bar (file:///home/nweiz/code/stuff.dart:42:21)
 final _vmFrame = new RegExp(
-    r'^#\d+\s+([^\s].*) \((.+?):(\d+)(?::(\d+))?\)$');
+    r'^#\d+\s+(\S.*) \((.+?):(\d+)(?::(\d+))?\)$');
 
 //     at VW.call$0 (http://pub.dartlang.org/stuff.dart.js:560:28)
+//     at VW.call$0 (eval as fn
+//         (http://pub.dartlang.org/stuff.dart.js:560:28), efn:3:28)
 //     at http://pub.dartlang.org/stuff.dart.js:560:28
 final _v8Frame = new RegExp(
-    r'^\s*at (?:([^\s].*?)(?: \[as [^\]]+\])? '
-    r'\((.+):(\d+):(\d+)\)|(.+):(\d+):(\d+))$');
+    r'^\s*at (?:(\S.*?)(?: \[as [^\]]+\])? \((.*)\)|(.*))$');
 
-/// foo$bar$0@http://pub.dartlang.org/stuff.dart.js:560:28
-/// http://pub.dartlang.org/stuff.dart.js:560:28
+// http://pub.dartlang.org/stuff.dart.js:560:28
+final _v8UrlLocation = new RegExp(r'^(.*):(\d+):(\d+)$');
+
+// eval as function (http://pub.dartlang.org/stuff.dart.js:560:28), efn:3:28
+// eval as function (http://pub.dartlang.org/stuff.dart.js:560:28)
+// eval as function (eval as otherFunction
+//     (http://pub.dartlang.org/stuff.dart.js:560:28))
+final _v8EvalLocation = new RegExp(
+    r'^eval at (?:\S.*?) \((.*)\)(?:, .*?:\d+:\d+)?$');
+
+// foo$bar$0@http://pub.dartlang.org/stuff.dart.js:560:28
+// http://pub.dartlang.org/stuff.dart.js:560:28
 final _safariFrame = new RegExp(r"^(?:([0-9A-Za-z_$]*)@)?(.*):(\d*):(\d*)$");
 
 // .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560
@@ -32,7 +43,7 @@
 // foo/bar.dart 10:11 in Foo._bar
 // http://dartlang.org/foo/bar.dart in Foo._bar
 final _friendlyFrame = new RegExp(
-    r'^([^\s]+)(?: (\d+)(?::(\d+))?)?\s+([^\d][^\s]*)$');
+    r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d]\S*)$');
 
 final _initialDot = new RegExp(r"^\.");
 
@@ -139,20 +150,37 @@
       throw new FormatException("Couldn't parse V8 stack trace line '$frame'.");
     }
 
+    // v8 location strings can be arbitrarily-nested, since it adds a layer of
+    // nesting for each eval performed on that line.
+    parseLocation(location, member) {
+      var evalMatch = _v8EvalLocation.firstMatch(location);
+      while (evalMatch != null) {
+        location = evalMatch[1];
+        evalMatch = _v8EvalLocation.firstMatch(location);
+      }
+
+      var urlMatch = _v8UrlLocation.firstMatch(location);
+      if (urlMatch == null) {
+        throw new FormatException(
+            "Couldn't parse V8 stack trace line '$frame'.");
+      }
+
+      return new Frame(
+          _uriOrPathToUri(urlMatch[1]),
+          int.parse(urlMatch[2]),
+          int.parse(urlMatch[3]),
+          member);
+    }
+
     // V8 stack frames can be in two forms.
     if (match[2] != null) {
-      // The first form looks like " at FUNCTION (PATH:LINE:COL)". PATH is
-      // usually an absolute URL, but it can be a path if the stack frame came
-      // from d8.
-      var uri = _uriOrPathToUri(match[2]);
-      var member = match[1].replaceAll("<anonymous>", "<fn>");
-      return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member);
+      // The first form looks like " at FUNCTION (LOCATION)".
+      return parseLocation(
+          match[2], match[1].replaceAll("<anonymous>", "<fn>"));
     } else {
-      // The second form looks like " at PATH:LINE:COL", and is used for
-      // anonymous functions. PATH is usually an absolute URL, but it can be a
-      // path if the stack frame came from d8.
-      var uri = _uriOrPathToUri(match[5]);
-      return new Frame(uri, int.parse(match[6]), int.parse(match[7]), "<fn>");
+      // The second form looks like " at LOCATION", and is used for anonymous
+      // functions.
+      return parseLocation(match[3], "<fn>");
     }
   }
 
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index 88b9275..c1d751f 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -92,6 +92,13 @@
   /// If [trace] is a native [StackTrace], its data will be parsed out; if it's
   /// a [Trace], it will be returned as-is.
   factory Trace.from(StackTrace trace) {
+    // Normally explicitly validating null arguments is bad Dart style, but here
+    // the natural failure will only occur when the LazyTrace is materialized,
+    // and we want to provide an error that's more local to the actual problem.
+    if (trace == null) {
+      throw new ArgumentError("Cannot create a Trace from null.");
+    }
+
     if (trace is Trace) return trace;
     if (trace is Chain) return trace.toTrace();
     return new LazyTrace(() => new Trace.parse(trace.toString()));
@@ -126,7 +133,10 @@
 
   /// Parses a string representation of a Dart VM stack trace.
   Trace.parseVM(String trace)
-      : this(trace.trim().split("\n").map((line) => new Frame.parseVM(line)));
+      : this(trace.trim().split("\n").
+            // TODO(nweiz): remove this when issue 15920 is fixed.
+            where((line) => line.isNotEmpty).
+            map((line) => new Frame.parseVM(line)));
 
   /// Parses a string representation of a Chrome/V8 stack trace.
   Trace.parseV8(String trace)
@@ -161,6 +171,7 @@
   /// Parses a string representation of a Safari 6.1+ stack trace.
   Trace.parseSafari6_1(String trace)
       : this(trace.trim().split("\n")
+          .where((line) => line.isNotEmpty)
           .map((line) => new Frame.parseSafari6_1(line)));
 
   /// Parses a string representation of a Safari 6.0 stack trace.
diff --git a/pkg/stack_trace/pubspec.yaml b/pkg/stack_trace/pubspec.yaml
index ac41d93..5a023c0 100644
--- a/pkg/stack_trace/pubspec.yaml
+++ b/pkg/stack_trace/pubspec.yaml
@@ -1,5 +1,5 @@
 name: stack_trace
-version: 0.9.1
+version: 0.9.1-dev+1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/stack_trace/test/frame_test.dart b/pkg/stack_trace/test/frame_test.dart
index 9722d38..482794c 100644
--- a/pkg/stack_trace/test/frame_test.dart
+++ b/pkg/stack_trace/test/frame_test.dart
@@ -149,6 +149,36 @@
       expect(frame.member, equals('VW.call\$0'));
     });
 
+    test('parses a basic eval stack frame correctly', () {
+      var frame = new Frame.parseV8("    at eval (eval at <anonymous> "
+          "(http://pub.dartlang.org/stuff.dart.js:560:28))");
+      expect(frame.uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.dart.js")));
+      expect(frame.line, equals(560));
+      expect(frame.column, equals(28));
+      expect(frame.member, equals('eval'));
+    });
+
+    test('parses an eval stack frame with inner position info correctly', () {
+      var frame = new Frame.parseV8("    at eval (eval at <anonymous> "
+          "(http://pub.dartlang.org/stuff.dart.js:560:28), <anonymous>:3:28)");
+      expect(frame.uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.dart.js")));
+      expect(frame.line, equals(560));
+      expect(frame.column, equals(28));
+      expect(frame.member, equals('eval'));
+    });
+
+    test('parses a nested eval stack frame correctly', () {
+      var frame = new Frame.parseV8("    at eval (eval at <anonymous> "
+          "(eval at sub (http://pub.dartlang.org/stuff.dart.js:560:28)))");
+      expect(frame.uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.dart.js")));
+      expect(frame.line, equals(560));
+      expect(frame.column, equals(28));
+      expect(frame.member, equals('eval'));
+    });
+
     test('converts "<anonymous>" to "<fn>"', () {
       String parsedMember(String member) =>
           new Frame.parseV8('    at $member (foo:0:0)').member;
diff --git a/pkg/stack_trace/test/trace_test.dart b/pkg/stack_trace/test/trace_test.dart
index 4c3278f..eeeff28 100644
--- a/pkg/stack_trace/test/trace_test.dart
+++ b/pkg/stack_trace/test/trace_test.dart
@@ -160,6 +160,21 @@
           equals(Uri.parse("http://pub.dartlang.org/thing.js")));
     });
 
+    test('parses a Safari 6.1 stack trace with an empty line correctly', () {
+      var trace = new Trace.parse(
+          'http://pub.dartlang.org/stuff.js:42:43\n'
+          '\n'
+          'zip@http://pub.dartlang.org/stuff.js:0:1\n'
+          'zip\$zap@http://pub.dartlang.org/thing.js:1:2');
+
+      expect(trace.frames[0].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[1].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[2].uri,
+          equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+    });
+
     test('parses a package:stack_trace stack trace correctly', () {
       var trace = new Trace.parse(
           'http://dartlang.org/foo/bar.dart 10:11  Foo.<fn>.bar\n'
diff --git a/pkg/third_party/angular_tests/browser_test.dart b/pkg/third_party/angular_tests/browser_test.dart
new file mode 100644
index 0000000..345d281
--- /dev/null
+++ b/pkg/third_party/angular_tests/browser_test.dart
@@ -0,0 +1,304 @@
+/// auto-generated by update_angular.sh
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 angular_browser_tests;
+
+import 'package:angular/mock/module.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import '../../../third_party/pkg/angular/test/angular_spec.dart' as test_0;
+import '../../../third_party/pkg/angular/test/bootstrap_spec.dart' as test_1;
+import '../../../third_party/pkg/angular/test/core/cache_spec.dart' as test_2;
+import '../../../third_party/pkg/angular/test/core/interpolate_spec.dart' as test_3;
+import '../../../third_party/pkg/angular/test/core/parser/generated_getter_setter_spec.dart' as test_4;
+import '../../../third_party/pkg/angular/test/core/parser/lexer_spec.dart' as test_5;
+import '../../../third_party/pkg/angular/test/core/parser/parser_spec.dart' as test_6;
+import '../../../third_party/pkg/angular/test/core/parser/static_parser_spec.dart' as test_7;
+import '../../../third_party/pkg/angular/test/core/registry_spec.dart' as test_8;
+import '../../../third_party/pkg/angular/test/core/scope_spec.dart' as test_9;
+import '../../../third_party/pkg/angular/test/core/templateurl_spec.dart' as test_10;
+import '../../../third_party/pkg/angular/test/core/zone_spec.dart' as test_11;
+import '../../../third_party/pkg/angular/test/core_dom/block_spec.dart' as test_12;
+import '../../../third_party/pkg/angular/test/core_dom/compiler_spec.dart' as test_13;
+import '../../../third_party/pkg/angular/test/core_dom/cookies_spec.dart' as test_14;
+import '../../../third_party/pkg/angular/test/core_dom/directive_spec.dart' as test_15;
+import '../../../third_party/pkg/angular/test/core_dom/http_spec.dart' as test_16;
+import '../../../third_party/pkg/angular/test/core_dom/ng_mustache_spec.dart' as test_17;
+import '../../../third_party/pkg/angular/test/core_dom/node_cursor_spec.dart' as test_18;
+import '../../../third_party/pkg/angular/test/core_dom/selector_spec.dart' as test_19;
+import '../../../third_party/pkg/angular/test/core_dom/shadow_root_options_spec.dart' as test_20;
+import '../../../third_party/pkg/angular/test/directive/input_select_spec.dart' as test_21;
+import '../../../third_party/pkg/angular/test/directive/ng_a_spec.dart' as test_22;
+import '../../../third_party/pkg/angular/test/directive/ng_bind_html_spec.dart' as test_23;
+import '../../../third_party/pkg/angular/test/directive/ng_bind_spec.dart' as test_24;
+import '../../../third_party/pkg/angular/test/directive/ng_bind_template_spec.dart' as test_25;
+import '../../../third_party/pkg/angular/test/directive/ng_class_spec.dart' as test_26;
+import '../../../third_party/pkg/angular/test/directive/ng_cloak_spec.dart' as test_27;
+import '../../../third_party/pkg/angular/test/directive/ng_events_spec.dart' as test_28;
+import '../../../third_party/pkg/angular/test/directive/ng_form_spec.dart' as test_29;
+import '../../../third_party/pkg/angular/test/directive/ng_if_spec.dart' as test_30;
+import '../../../third_party/pkg/angular/test/directive/ng_include_spec.dart' as test_31;
+import '../../../third_party/pkg/angular/test/directive/ng_model_spec.dart' as test_32;
+import '../../../third_party/pkg/angular/test/directive/ng_non_bindable_spec.dart' as test_33;
+import '../../../third_party/pkg/angular/test/directive/ng_switch_spec.dart' as test_34;
+import '../../../third_party/pkg/angular/test/directive/ng_repeat_spec.dart' as test_35;
+import '../../../third_party/pkg/angular/test/directive/ng_show_hide_spec.dart' as test_36;
+import '../../../third_party/pkg/angular/test/directive/ng_src_boolean_spec.dart' as test_37;
+import '../../../third_party/pkg/angular/test/directive/ng_style_spec.dart' as test_38;
+import '../../../third_party/pkg/angular/test/directive/ng_template_spec.dart' as test_39;
+import '../../../third_party/pkg/angular/test/filter/currency_spec.dart' as test_40;
+import '../../../third_party/pkg/angular/test/filter/date_spec.dart' as test_41;
+import '../../../third_party/pkg/angular/test/filter/filter_spec.dart' as test_42;
+import '../../../third_party/pkg/angular/test/filter/json_spec.dart' as test_43;
+import '../../../third_party/pkg/angular/test/filter/limit_to_spec.dart' as test_44;
+import '../../../third_party/pkg/angular/test/filter/lowercase_spec.dart' as test_45;
+import '../../../third_party/pkg/angular/test/filter/number_spec.dart' as test_46;
+import '../../../third_party/pkg/angular/test/filter/order_by_spec.dart' as test_47;
+import '../../../third_party/pkg/angular/test/filter/uppercase_spec.dart' as test_48;
+import '../../../third_party/pkg/angular/test/introspection_spec.dart' as test_49;
+import '../../../third_party/pkg/angular/test/mock/http_backend_spec.dart' as test_50;
+import '../../../third_party/pkg/angular/test/mock/test_bed_spec.dart' as test_51;
+import '../../../third_party/pkg/angular/test/mock/zone_spec.dart' as test_52;
+import '../../../third_party/pkg/angular/test/routing/ng_bind_route_spec.dart' as test_53;
+import '../../../third_party/pkg/angular/test/routing/ng_view_spec.dart' as test_54;
+import '../../../third_party/pkg/angular/test/routing/routing_spec.dart' as test_55;
+import '../../../third_party/pkg/angular/test/_specs_spec.dart' as test_56;
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  setUp(() {
+    setUpInjector();
+  });
+
+  group('angular', () {
+    test_0.main();
+  });
+
+  group('bootstrap', () {
+    test_1.main();
+  });
+
+  group('core/cache', () {
+    test_2.main();
+  });
+
+  group('core/interpolate', () {
+    test_3.main();
+  });
+
+  group('core/parser/generated_getter_setter', () {
+    test_4.main();
+  });
+
+  group('core/parser/lexer', () {
+    test_5.main();
+  });
+
+  group('core/parser/parser', () {
+    test_6.main();
+  });
+
+  group('core/parser/static_parser', () {
+    test_7.main();
+  });
+
+  group('core/registry', () {
+    test_8.main();
+  });
+
+  group('core/scope', () {
+    test_9.main();
+  });
+
+  group('core/templateurl', () {
+    test_10.main();
+  });
+
+  group('core/zone', () {
+    test_11.main();
+  });
+
+  group('core_dom/block', () {
+    test_12.main();
+  });
+
+  group('core_dom/compiler', () {
+    test_13.main();
+  });
+
+  group('core_dom/cookies', () {
+    test_14.main();
+  });
+
+  group('core_dom/directive', () {
+    test_15.main();
+  });
+
+  group('core_dom/http', () {
+    test_16.main();
+  });
+
+  group('core_dom/ng_mustache', () {
+    test_17.main();
+  });
+
+  group('core_dom/node_cursor', () {
+    test_18.main();
+  });
+
+  group('core_dom/selector', () {
+    test_19.main();
+  });
+
+  group('core_dom/shadow_root_options', () {
+    test_20.main();
+  });
+
+  group('directive/input_select', () {
+    test_21.main();
+  });
+
+  group('directive/ng_a', () {
+    test_22.main();
+  });
+
+  group('directive/ng_bind_html', () {
+    test_23.main();
+  });
+
+  group('directive/ng_bind', () {
+    test_24.main();
+  });
+
+  group('directive/ng_bind_template', () {
+    test_25.main();
+  });
+
+  group('directive/ng_class', () {
+    test_26.main();
+  });
+
+  group('directive/ng_cloak', () {
+    test_27.main();
+  });
+
+  group('directive/ng_events', () {
+    test_28.main();
+  });
+
+  group('directive/ng_form', () {
+    test_29.main();
+  });
+
+  group('directive/ng_if', () {
+    test_30.main();
+  });
+
+  group('directive/ng_include', () {
+    test_31.main();
+  });
+
+  group('directive/ng_model', () {
+    test_32.main();
+  });
+
+  group('directive/ng_non_bindable', () {
+    test_33.main();
+  });
+
+  group('directive/ng_switch', () {
+    test_34.main();
+  });
+
+  group('directive/ng_repeat', () {
+    test_35.main();
+  });
+
+  group('directive/ng_show_hide', () {
+    test_36.main();
+  });
+
+  group('directive/ng_src_boolean', () {
+    test_37.main();
+  });
+
+  group('directive/ng_style', () {
+    test_38.main();
+  });
+
+  group('directive/ng_template', () {
+    test_39.main();
+  });
+
+  group('filter/currency', () {
+    test_40.main();
+  });
+
+  group('filter/date', () {
+    test_41.main();
+  });
+
+  group('filter/filter', () {
+    test_42.main();
+  });
+
+  group('filter/json', () {
+    test_43.main();
+  });
+
+  group('filter/limit_to', () {
+    test_44.main();
+  });
+
+  group('filter/lowercase', () {
+    test_45.main();
+  });
+
+  group('filter/number', () {
+    test_46.main();
+  });
+
+  group('filter/order_by', () {
+    test_47.main();
+  });
+
+  group('filter/uppercase', () {
+    test_48.main();
+  });
+
+  group('introspection', () {
+    test_49.main();
+  });
+
+  group('mock/http_backend', () {
+    test_50.main();
+  });
+
+  group('mock/test_bed', () {
+    test_51.main();
+  });
+
+  group('mock/zone', () {
+    test_52.main();
+  });
+
+  group('routing/ng_bind_route', () {
+    test_53.main();
+  });
+
+  group('routing/ng_view', () {
+    test_54.main();
+  });
+
+  group('routing/routing', () {
+    test_55.main();
+  });
+
+  group('_specs', () {
+    test_56.main();
+  });
+}
diff --git a/pkg/third_party/angular_tests/browser_test.html b/pkg/third_party/angular_tests/browser_test.html
new file mode 100644
index 0000000..941c511
--- /dev/null
+++ b/pkg/third_party/angular_tests/browser_test.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> browser_test.dart </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/shadow_dom/shadow_dom.debug.js"></script>
+</head>
+<body>
+  <h1> Running browser_test.dart </h1>
+  <script type="text/javascript"
+      src="/packages/unittest/test_controller.js"></script>
+  <script type="text/javascript"
+      src="/packages/browser/interop.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/pkg/third_party/angular_tests/vm_test.dart b/pkg/third_party/angular_tests/vm_test.dart
new file mode 100644
index 0000000..d7a71af
--- /dev/null
+++ b/pkg/third_party/angular_tests/vm_test.dart
@@ -0,0 +1,29 @@
+/// auto-generated by update_angular.sh
+
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 angular_vm_tests;
+
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+import '../../../third_party/pkg/angular/test/tools/html_extractor_spec.dart' as test_0;
+import '../../../third_party/pkg/angular/test/tools/selector_spec.dart' as test_1;
+import '../../../third_party/pkg/angular/test/tools/source_metadata_extractor_spec.dart' as test_2;
+
+main() {
+  useCompactVMConfiguration();
+
+  group('tools/html_extractor', () {
+    test_0.main();
+  });
+
+  group('tools/selector', () {
+    test_1.main();
+  });
+
+  group('tools/source_metadata_extractor', () {
+    test_2.main();
+  });
+}
diff --git a/pkg/third_party/di_tests/di_test.dart b/pkg/third_party/di_tests/di_test.dart
new file mode 100644
index 0000000..4260fa0
--- /dev/null
+++ b/pkg/third_party/di_tests/di_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+library angular.di.test;
+
+import 'package:unittest/unittest.dart';
+import '../../../third_party/pkg/di/test/main.dart' as di;
+
+/**
+ * Tests Angular's DI package
+ */
+main() {
+
+  group('main', () {
+    di.main();
+  });
+}
diff --git a/pkg/unittest/LICENSE b/pkg/unittest/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/unittest/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/unittest/lib/mock.dart b/pkg/unittest/lib/mock.dart
index ad4886c..a4216cf 100644
--- a/pkg/unittest/lib/mock.dart
+++ b/pkg/unittest/lib/mock.dart
@@ -1244,6 +1244,7 @@
 LogEntryList sharedLog = null;
 
 /** The base class for all mocked objects. */
+@proxy
 class Mock {
   /** The mock name. Needed if the log is shared; optional otherwise. */
   final String name;
diff --git a/pkg/unittest/pubspec.yaml b/pkg/unittest/pubspec.yaml
index f1c1d4a..25df81a 100644
--- a/pkg/unittest/pubspec.yaml
+++ b/pkg/unittest/pubspec.yaml
@@ -1,5 +1,5 @@
 name: unittest
-version: 0.9.2+1
+version: 0.9.3
 author: Dart Team <misc@dartlang.org>
 description: A library for writing dart unit tests.
 homepage: http://www.dartlang.org
diff --git a/pkg/unittest/test/mock_test.dart b/pkg/unittest/test/mock_test.dart
index 1204c39..b2c01f4 100644
--- a/pkg/unittest/test/mock_test.dart
+++ b/pkg/unittest/test/mock_test.dart
@@ -7,6 +7,7 @@
 import 'package:unittest/mock.dart';
 
 class MockList extends Mock implements List {
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class Foo {
@@ -19,6 +20,8 @@
     real = new Foo();
     this.when(callsTo('sum')).alwaysCall(real.sum);
   }
+
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 makeTestLogEntry(String methodName, List args, int time,
@@ -666,10 +669,10 @@
     // This is distinct from value ordering, i.e.
     //
     // m.when(...).thenReturn(1).thenReturn(2)
-    // 
+    //
     // Here we want to test using distinct matchers being
     // applied in order, so we have a single call that
-    // matches 3 different behaviors, and test that 
+    // matches 3 different behaviors, and test that
     // the behaviors are applied in the order they are
     // defined.
     var m = new Mock();
diff --git a/pkg/unmodifiable_collection/LICENSE b/pkg/unmodifiable_collection/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/unmodifiable_collection/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/utf/LICENSE b/pkg/utf/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/utf/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/watcher/LICENSE b/pkg/watcher/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/watcher/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/watcher/lib/src/directory_watcher/mac_os.dart b/pkg/watcher/lib/src/directory_watcher/mac_os.dart
index 90036cc..ba0ede4 100644
--- a/pkg/watcher/lib/src/directory_watcher/mac_os.dart
+++ b/pkg/watcher/lib/src/directory_watcher/mac_os.dart
@@ -24,7 +24,7 @@
 /// succession, it won't report them in the order they occurred. See issue
 /// 14373.
 ///
-/// This also works around issues 15458 and 14849 in the implementation of
+/// This also works around issues 16003 and 14849 in the implementation of
 /// [Directory.watch].
 class MacOSDirectoryWatcher extends ResubscribableDirectoryWatcher {
   // TODO(nweiz): remove these when issue 15042 is fixed.
@@ -50,14 +50,6 @@
   Future get ready => _readyCompleter.future;
   final _readyCompleter = new Completer();
 
-  /// The number of event batches that have been received from
-  /// [Directory.watch].
-  ///
-  /// This is used to determine if the [Directory.watch] stream was falsely
-  /// closed due to issue 14849. A close caused by events in the past will only
-  /// happen before or immediately after the first batch of events.
-  int batches = 0;
-
   /// The set of files that are known to exist recursively within the watched
   /// directory.
   ///
@@ -73,11 +65,17 @@
   /// needs to be resubscribed in order to work around issue 14849.
   StreamSubscription<FileSystemEvent> _watchSubscription;
 
-  /// A set of subscriptions that this watcher subscribes to.
-  ///
-  /// These are gathered together so that they may all be canceled when the
-  /// watcher is closed. This does not include [_watchSubscription].
-  final _subscriptions = new Set<StreamSubscription>();
+  /// The subscription to the [Directory.list] call for the initial listing of
+  /// the directory to determine its initial state.
+  StreamSubscription<FileSystemEntity> _initialListSubscription;
+
+  /// The subscription to the [Directory.list] call for listing the contents of
+  /// a subdirectory that was moved into the watched directory.
+  StreamSubscription<FileSystemEntity> _listSubscription;
+
+  /// The timer for tracking how long we wait for an initial batch of bogus
+  /// events (see issue 14373).
+  Timer _bogusEventTimer;
 
   _MacOSDirectoryWatcher(String directory, int parentId)
       : directory = directory,
@@ -85,12 +83,20 @@
         _id = "$parentId/${_count++}" {
     _startWatch();
 
-    _listen(Chain.track(new Directory(directory).list(recursive: true)),
-        (entity) {
-      if (entity is! Directory) _files.add(entity.path);
-    },
-        onError: _emitError,
-        onDone: () {
+    // Before we're ready to emit events, wait for [_listDir] to complete and
+    // for enough time to elapse that if bogus events (issue 14373) would be
+    // emitted, they will be.
+    //
+    // If we do receive a batch of events, [_onBatch] will ensure that these
+    // futures don't fire and that the directory is re-listed.
+    Future.wait([
+      _listDir().then((_) {
+        if (MacOSDirectoryWatcher.logDebugInfo) {
+          print("[$_id] finished initial directory list");
+        }
+      }),
+      _waitForBogusEvents()
+    ]).then((_) {
       if (MacOSDirectoryWatcher.logDebugInfo) {
         print("[$_id] watcher is ready, known files:");
         for (var file in _files.toSet()) {
@@ -98,20 +104,19 @@
         }
       }
       _readyCompleter.complete();
-    },
-        cancelOnError: true);
+    });
   }
 
   void close() {
     if (MacOSDirectoryWatcher.logDebugInfo) {
       print("[$_id] watcher is closed");
     }
-    for (var subscription in _subscriptions) {
-      subscription.cancel();
-    }
-    _subscriptions.clear();
     if (_watchSubscription != null) _watchSubscription.cancel();
+    if (_initialListSubscription != null) _initialListSubscription.cancel();
+    if (_listSubscription != null) _listSubscription.cancel();
     _watchSubscription = null;
+    _initialListSubscription = null;
+    _listSubscription = null;
     _eventsController.close();
   }
 
@@ -129,12 +134,33 @@
       }
     }
 
-    batches++;
+    // If we get a batch of events before we're ready to begin emitting events,
+    // it's probable that it's a batch of pre-watcher events (see issue 14373).
+    // Ignore those events and re-list the directory.
+    if (!isReady) {
+      if (MacOSDirectoryWatcher.logDebugInfo) {
+        print("[$_id] not ready to emit events, re-listing directory");
+      }
+
+      // Cancel the timer because bogus events only occur in the first batch, so
+      // we can fire [ready] as soon as we're done listing the directory.
+      _bogusEventTimer.cancel();
+      _listDir().then((_) {
+        if (MacOSDirectoryWatcher.logDebugInfo) {
+          print("[$_id] watcher is ready, known files:");
+          for (var file in _files.toSet()) {
+            print("[$_id]   ${p.relative(file, from: directory)}");
+          }
+        }
+        _readyCompleter.complete();
+      });
+      return;
+    }
 
     _sortEvents(batch).forEach((path, events) {
       var relativePath = p.relative(path, from: directory);
       if (MacOSDirectoryWatcher.logDebugInfo) {
-        print("[$_id] events for $relativePath:\n");
+        print("[$_id] events for $relativePath:");
         for (var event in events) {
           print("[$_id]   ${_formatEvent(event)}");
         }
@@ -165,9 +191,11 @@
 
           if (_files.containsDir(path)) continue;
 
-          _listen(Chain.track(new Directory(path).list(recursive: true)),
-              (entity) {
+          var stream = Chain.track(new Directory(path).list(recursive: true));
+          _listSubscription = stream.listen((entity) {
             if (entity is Directory) return;
+            if (_files.contains(path)) return;
+
             _emitEvent(ChangeType.ADD, entity.path);
             _files.add(entity.path);
           }, onError: (e, stackTrace) {
@@ -293,12 +321,14 @@
 
     switch (type) {
       case FileSystemEvent.CREATE:
-        return new ConstructableFileSystemCreateEvent(batch.first.path, isDir);
-      case FileSystemEvent.DELETE:
-        // Issue 15458 means that DELETE events for directories can actually
-        // mean CREATE, so we always check the filesystem for them.
+        // Issue 16003 means that a CREATE event for a directory can indicate
+        // that the directory was moved and then re-created.
+        // [_eventsBasedOnFileSystem] will handle this correctly by producing a
+        // DELETE event followed by a CREATE event if the directory exists.
         if (isDir) return null;
         return new ConstructableFileSystemCreateEvent(batch.first.path, false);
+      case FileSystemEvent.DELETE:
+        return new ConstructableFileSystemDeleteEvent(batch.first.path, isDir);
       case FileSystemEvent.MODIFY:
         return new ConstructableFileSystemModifyEvent(
             batch.first.path, isDir, false);
@@ -320,10 +350,12 @@
     var dirExists = new Directory(path).existsSync();
 
     if (MacOSDirectoryWatcher.logDebugInfo) {
-      print("[$_id] file existed: $fileExisted");
-      print("[$_id] dir existed: $dirExisted");
-      print("[$_id] file exists: $fileExists");
-      print("[$_id] dir exists: $dirExists");
+      print("[$_id] checking file system for "
+          "${p.relative(path, from: directory)}");
+      print("[$_id]   file existed: $fileExisted");
+      print("[$_id]   dir existed: $dirExisted");
+      print("[$_id]   file exists: $fileExists");
+      print("[$_id]   dir exists: $dirExists");
     }
 
     var events = [];
@@ -356,19 +388,24 @@
 
   /// The callback that's run when the [Directory.watch] stream is closed.
   void _onDone() {
+    if (MacOSDirectoryWatcher.logDebugInfo) print("[$_id] stream closed");
+
     _watchSubscription = null;
 
-    // If the directory still exists and we haven't seen more than one batch,
+    // If the directory still exists and we're still expecting bogus events,
     // this is probably issue 14849 rather than a real close event. We should
     // just restart the watcher.
-    if (batches < 2 && new Directory(directory).existsSync()) {
+    if (!isReady && new Directory(directory).existsSync()) {
+      if (MacOSDirectoryWatcher.logDebugInfo) {
+        print("[$_id] fake closure (issue 14849), re-opening stream");
+      }
       _startWatch();
       return;
     }
 
     // FSEvents can fail to report the contents of the directory being removed
-    // when the directory itself is removed, so we need to manually mark the as
-    // removed.
+    // when the directory itself is removed, so we need to manually mark the
+    // files as removed.
     for (var file in _files.toSet()) {
       _emitEvent(ChangeType.REMOVE, file);
     }
@@ -387,6 +424,37 @@
         onDone: _onDone);
   }
 
+  /// Starts or restarts listing the watched directory to get an initial picture
+  /// of its state.
+  Future _listDir() {
+    assert(!isReady);
+    if (_initialListSubscription != null) _initialListSubscription.cancel();
+
+    _files.clear();
+    var completer = new Completer();
+    var stream = Chain.track(new Directory(directory).list(recursive: true));
+    _initialListSubscription = stream.listen((entity) {
+      if (entity is! Directory) _files.add(entity.path);
+    },
+        onError: _emitError,
+        onDone: completer.complete,
+        cancelOnError: true);
+    return completer.future;
+  }
+
+  /// Wait 200ms for a batch of bogus events (issue 14373) to come in.
+  ///
+  /// 200ms is short in terms of human interaction, but longer than any Mac OS
+  /// watcher tests take on the bots, so it should be safe to assume that any
+  /// bogus events will be signaled in that time frame.
+  Future _waitForBogusEvents() {
+    var completer = new Completer();
+    _bogusEventTimer = new Timer(
+        new Duration(milliseconds: 200),
+        completer.complete);
+    return completer.future;
+  }
+
   /// Emit an event with the given [type] and [path].
   void _emitEvent(ChangeType type, String path) {
     if (!isReady) return;
@@ -404,18 +472,6 @@
     close();
   }
 
-  /// Like [Stream.listen], but automatically adds the subscription to
-  /// [_subscriptions] so that it can be canceled when [close] is called.
-  void _listen(Stream stream, void onData(event), {Function onError,
-      void onDone(), bool cancelOnError}) {
-    var subscription;
-    subscription = stream.listen(onData, onError: onError, onDone: () {
-      _subscriptions.remove(subscription);
-      if (onDone != null) onDone();
-    }, cancelOnError: cancelOnError);
-    _subscriptions.add(subscription);
-  }
-
   // TODO(nweiz): remove this when issue 15042 is fixed.
   /// Return a human-friendly string representation of [event].
   String _formatEvent(FileSystemEvent event) {
diff --git a/pkg/watcher/lib/src/directory_watcher/polling.dart b/pkg/watcher/lib/src/directory_watcher/polling.dart
index 684f7aa..12a3245 100644
--- a/pkg/watcher/lib/src/directory_watcher/polling.dart
+++ b/pkg/watcher/lib/src/directory_watcher/polling.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:crypto/crypto.dart';
 import 'package:stack_trace/stack_trace.dart';
 
 import '../async_queue.dart';
@@ -46,10 +45,10 @@
   /// directory contents.
   final Duration _pollingDelay;
 
-  /// The previous status of the files in the directory.
+  /// The previous modification times of the files in the directory.
   ///
   /// Used to tell which files have been modified.
-  final _statuses = new Map<String, _FileStatus>();
+  final _lastModifieds = new Map<String, DateTime>();
 
   /// The subscription used while [directory] is being listed.
   ///
@@ -89,7 +88,7 @@
     // Don't process any remaining files.
     _filesToProcess.clear();
     _polledFiles.clear();
-    _statuses.clear();
+    _lastModifieds.clear();
   }
 
   /// Scans the contents of the directory once to see which files have been
@@ -135,32 +134,25 @@
     return getModificationTime(file).then((modified) {
       if (_events.isClosed) return null;
 
-      var lastStatus = _statuses[file];
+      var lastModified = _lastModifieds[file];
 
       // If its modification time hasn't changed, assume the file is unchanged.
-      if (lastStatus != null && lastStatus.modified == modified) {
+      if (lastModified != null && lastModified == modified) {
         // The file is still here.
         _polledFiles.add(file);
         return null;
       }
 
-      return _hashFile(file).then((hash) {
-        if (_events.isClosed) return;
+      if (_events.isClosed) return null;
 
-        var status = new _FileStatus(modified, hash);
-        _statuses[file] = status;
-        _polledFiles.add(file);
+      _lastModifieds[file] = modified;
+      _polledFiles.add(file);
 
-        // Only notify if we're ready to emit events.
-        if (!isReady) return;
+      // Only notify if we're ready to emit events.
+      if (!isReady) return null;
 
-        // And the file is different.
-        var changed = lastStatus == null || !_sameHash(lastStatus.hash, hash);
-        if (!changed) return;
-
-        var type = lastStatus == null ? ChangeType.ADD : ChangeType.MODIFY;
-        _events.add(new WatchEvent(type, file));
-      });
+      var type = lastModified == null ? ChangeType.ADD : ChangeType.MODIFY;
+      _events.add(new WatchEvent(type, file));
     });
   }
 
@@ -169,10 +161,10 @@
   Future _completePoll() {
     // Any files that were not seen in the last poll but that we have a
     // status for must have been removed.
-    var removedFiles = _statuses.keys.toSet().difference(_polledFiles);
+    var removedFiles = _lastModifieds.keys.toSet().difference(_polledFiles);
     for (var removed in removedFiles) {
       if (isReady) _events.add(new WatchEvent(ChangeType.REMOVE, removed));
-      _statuses.remove(removed);
+      _lastModifieds.remove(removed);
     }
 
     if (!isReady) _ready.complete();
@@ -183,37 +175,4 @@
       _poll();
     });
   }
-
-  /// Calculates the SHA-1 hash of the file at [path].
-  Future<List<int>> _hashFile(String path) {
-    return Chain.track(new File(path).readAsBytes()).then((bytes) {
-      var sha1 = new SHA1();
-      sha1.add(bytes);
-      return sha1.close();
-    });
-  }
-
-  /// Returns `true` if [a] and [b] are the same hash value, i.e. the same
-  /// series of byte values.
-  bool _sameHash(List<int> a, List<int> b) {
-    // Hashes should always be the same size.
-    assert(a.length == b.length);
-
-    for (var i = 0; i < a.length; i++) {
-      if (a[i] != b[i]) return false;
-    }
-
-    return true;
-  }
 }
-
-class _FileStatus {
-  /// The last time the file was modified.
-  DateTime modified;
-
-  /// The SHA-1 hash of the contents of the file.
-  List<int> hash;
-
-  _FileStatus(this.modified, this.hash);
-}
-
diff --git a/pkg/watcher/lib/src/utils.dart b/pkg/watcher/lib/src/utils.dart
index a235f7d..163e9f4 100644
--- a/pkg/watcher/lib/src/utils.dart
+++ b/pkg/watcher/lib/src/utils.dart
@@ -73,6 +73,18 @@
 /// under the covers.
 Future newFuture(callback()) => new Future.value().then((_) => callback());
 
+/// Returns a [Future] that completes after pumping the event queue [times]
+/// times. By default, this should pump the event queue enough times to allow
+/// any code to run, as long as it's not waiting on some external event.
+Future pumpEventQueue([int times=20]) {
+  if (times == 0) return new Future.value();
+  // We use a delayed future to allow microtask events to finish. The
+  // Future.value or Future() constructors use scheduleMicrotask themselves and
+  // would therefore not wait for microtask callbacks that are scheduled after
+  // invoking this method.
+  return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
+}
+
 /// A stream transformer that batches all events that are sent at the same time.
 ///
 /// When multiple events are synchronously added to a stream controller, the
diff --git a/pkg/watcher/pubspec.yaml b/pkg/watcher/pubspec.yaml
index a967294..bf00d9e 100644
--- a/pkg/watcher/pubspec.yaml
+++ b/pkg/watcher/pubspec.yaml
@@ -1,17 +1,15 @@
 name: watcher
-version: 0.9.2
+version: 0.9.3-dev
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
-  A file watcher. It monitors (currently by polling) for changes to contents
-  of directories and notifies you when files have been added, removed, or
-  modified.
+  A file watcher. It monitors for changes to contents of directories and
+  notifies you when files have been added, removed, or modified.
 dependencies:
-  crypto: ">=0.9.0 <0.10.0"
   path: ">=0.9.0 <2.0.0"
   stack_trace: ">=0.9.1 <0.10.0"
 dev_dependencies:
-  scheduled_test: ">=0.9.0 <0.10.0"
-  unittest: ">=0.9.0 <0.10.0"
+  scheduled_test: ">=0.9.3-dev <0.10.0"
+  unittest: ">=0.9.2 <0.10.0"
 environment:
   sdk: ">=0.8.10+6 <2.0.0"
diff --git a/pkg/watcher/test/directory_watcher/linux_test.dart b/pkg/watcher/test/directory_watcher/linux_test.dart
index f53b272..cae38ad 100644
--- a/pkg/watcher/test/directory_watcher/linux_test.dart
+++ b/pkg/watcher/test/directory_watcher/linux_test.dart
@@ -23,16 +23,6 @@
         new isInstanceOf<LinuxDirectoryWatcher>());
   });
 
-  test('notifies even if the file contents are unchanged', () {
-    writeFile("a.txt", contents: "same");
-    writeFile("b.txt", contents: "before");
-    startWatcher();
-    writeFile("a.txt", contents: "same");
-    writeFile("b.txt", contents: "after");
-    expectModifyEvent("a.txt");
-    expectModifyEvent("b.txt");
-  });
-
   test('emits events for many nested files moved out then immediately back in',
       () {
     withPermutations((i, j, k) =>
@@ -42,14 +32,15 @@
     renameDir("dir/sub", "sub");
     renameDir("sub", "dir/sub");
 
-    inAnyOrder(() {
-      withPermutations((i, j, k) =>
-          expectRemoveEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
-    });
+    allowEither(() {
+      inAnyOrder(withPermutations((i, j, k) =>
+          isRemoveEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
 
-    inAnyOrder(() {
-      withPermutations((i, j, k) =>
-          expectAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
+      inAnyOrder(withPermutations((i, j, k) =>
+          isAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
+    }, () {
+      inAnyOrder(withPermutations((i, j, k) =>
+          isModifyEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
     });
   });
 }
diff --git a/pkg/watcher/test/directory_watcher/mac_os_test.dart b/pkg/watcher/test/directory_watcher/mac_os_test.dart
index 8fc2d3e..1e9bd7d 100644
--- a/pkg/watcher/test/directory_watcher/mac_os_test.dart
+++ b/pkg/watcher/test/directory_watcher/mac_os_test.dart
@@ -36,16 +36,6 @@
     expectAddEvent("dir/newer.txt");
   });
 
-  test('notifies even if the file contents are unchanged', () {
-    writeFile("a.txt", contents: "same");
-    writeFile("b.txt", contents: "before");
-    startWatcher();
-    writeFile("a.txt", contents: "same");
-    writeFile("b.txt", contents: "after");
-    expectModifyEvent("a.txt");
-    expectModifyEvent("b.txt");
-  });
-
   test('emits events for many nested files moved out then immediately back in',
       () {
     withPermutations((i, j, k) =>
@@ -56,14 +46,15 @@
     renameDir("dir/sub", "sub");
     renameDir("sub", "dir/sub");
 
-    inAnyOrder(() {
-      withPermutations((i, j, k) =>
-          expectRemoveEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
-    });
+    allowEither(() {
+      inAnyOrder(withPermutations((i, j, k) =>
+          isRemoveEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
 
-    inAnyOrder(() {
-      withPermutations((i, j, k) =>
-          expectAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
+      inAnyOrder(withPermutations((i, j, k) =>
+          isAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
+    }, () {
+      inAnyOrder(withPermutations((i, j, k) =>
+          isModifyEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
     });
   });
 }
diff --git a/pkg/watcher/test/directory_watcher/polling_test.dart b/pkg/watcher/test/directory_watcher/polling_test.dart
index 02ed5d2..da29207 100644
--- a/pkg/watcher/test/directory_watcher/polling_test.dart
+++ b/pkg/watcher/test/directory_watcher/polling_test.dart
@@ -19,15 +19,6 @@
 
   sharedTests();
 
-  test('does not notify if the file contents are unchanged', () {
-    writeFile("a.txt", contents: "same");
-    writeFile("b.txt", contents: "before");
-    startWatcher();
-    writeFile("a.txt", contents: "same");
-    writeFile("b.txt", contents: "after");
-    expectModifyEvent("b.txt");
-  });
-
   test('does not notify if the modification time did not change', () {
     writeFile("a.txt", contents: "before");
     writeFile("b.txt", contents: "before");
diff --git a/pkg/watcher/test/directory_watcher/shared.dart b/pkg/watcher/test/directory_watcher/shared.dart
index fe76a03..849cea00 100644
--- a/pkg/watcher/test/directory_watcher/shared.dart
+++ b/pkg/watcher/test/directory_watcher/shared.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:scheduled_test/scheduled_test.dart';
+import 'package:watcher/src/utils.dart';
 
 import '../utils.dart';
 
@@ -51,6 +52,19 @@
     expectModifyEvent("file.txt");
   });
 
+  test('notifies even if the file contents are unchanged', () {
+    writeFile("a.txt", contents: "same");
+    writeFile("b.txt", contents: "before");
+    startWatcher();
+
+    writeFile("a.txt", contents: "same");
+    writeFile("b.txt", contents: "after");
+    inAnyOrder([
+      isModifyEvent("a.txt"),
+      isModifyEvent("b.txt")
+    ]);
+  });
+
   test('when the watched directory is deleted, removes all files', () {
     writeFile("dir/a.txt");
     writeFile("dir/b.txt");
@@ -58,10 +72,10 @@
     startWatcher(dir: "dir");
 
     deleteDir("dir");
-    inAnyOrder(() {
-      expectRemoveEvent("dir/a.txt");
-      expectRemoveEvent("dir/b.txt");
-    });
+    inAnyOrder([
+      isRemoveEvent("dir/a.txt"),
+      isRemoveEvent("dir/b.txt")
+    ]);
   });
 
   group("moves", () {
@@ -70,10 +84,10 @@
       startWatcher();
       renameFile("old.txt", "new.txt");
 
-      inAnyOrder(() {
-        expectAddEvent("new.txt");
-        expectRemoveEvent("old.txt");
-      });
+      inAnyOrder([
+        isAddEvent("new.txt"),
+        isRemoveEvent("old.txt")
+      ]);
     });
 
     test('notifies when a file is moved from outside the watched directory',
@@ -95,6 +109,13 @@
     });
   });
 
+  // Most of the time, when multiple filesystem actions happen in sequence,
+  // they'll be batched together and the watcher will see them all at once.
+  // These tests verify that the watcher normalizes and combine these events
+  // properly. However, very occasionally the events will be reported in
+  // separate batches, and the watcher will report them as though they occurred
+  // far apart in time, so each of these tests has a "backup case" to allow for
+  // that as well.
   group("clustered changes", () {
     test("doesn't notify when a file is created and then immediately removed",
         () {
@@ -102,7 +123,12 @@
       writeFile("file.txt");
       deleteFile("file.txt");
 
-      // [startWatcher] will assert that no events were fired.
+      // Backup case.
+      startClosingEventStream();
+      allowEvents(() {
+        expectAddEvent("file.txt");
+        expectRemoveEvent("file.txt");
+      });
     });
 
     test("reports a modification when a file is deleted and then immediately "
@@ -112,7 +138,14 @@
 
       deleteFile("file.txt");
       writeFile("file.txt", contents: "re-created");
-      expectModifyEvent("file.txt");
+
+      allowEither(() {
+        expectModifyEvent("file.txt");
+      }, () {
+        // Backup case.
+        expectRemoveEvent("file.txt");
+        expectAddEvent("file.txt");
+      });
     });
 
     test("reports a modification when a file is moved and then immediately "
@@ -122,9 +155,17 @@
 
       renameFile("old.txt", "new.txt");
       writeFile("old.txt", contents: "re-created");
-      inAnyOrder(() {
-        expectModifyEvent("old.txt");
+
+      allowEither(() {
+        inAnyOrder([
+          isModifyEvent("old.txt"),
+          isAddEvent("new.txt")
+        ]);
+      }, () {
+        // Backup case.
+        expectRemoveEvent("old.txt");
         expectAddEvent("new.txt");
+        expectAddEvent("old.txt");
       });
     });
 
@@ -135,6 +176,10 @@
 
       writeFile("file.txt", contents: "modified");
       deleteFile("file.txt");
+
+      // Backup case.
+      allowModifyEvent("file.txt");
+
       expectRemoveEvent("file.txt");
     });
 
@@ -144,7 +189,12 @@
 
       writeFile("file.txt");
       writeFile("file.txt", contents: "modified");
+
       expectAddEvent("file.txt");
+
+      // Backup case.
+      startClosingEventStream();
+      allowModifyEvent("file.txt");
     });
   });
 
@@ -161,10 +211,10 @@
       startWatcher();
 
       renameDir("old", "new");
-      inAnyOrder(() {
-        expectRemoveEvent("old/file.txt");
-        expectAddEvent("new/file.txt");
-      });
+      inAnyOrder([
+        isRemoveEvent("old/file.txt"),
+        isAddEvent("new/file.txt")
+      ]);
 
       writeFile("new/file.txt", contents: "modified");
       expectModifyEvent("new/file.txt");
@@ -178,10 +228,8 @@
       startWatcher(dir: "dir");
       renameDir("sub", "dir/sub");
 
-      inAnyOrder(() {
-        withPermutations((i, j, k)  =>
-            expectAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
-      });
+      inAnyOrder(withPermutations((i, j, k)  =>
+          isAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
     });
 
     test('emits events for many nested files removed at once', () {
@@ -197,10 +245,8 @@
       // directory.
       renameDir("dir/sub", "sub");
 
-      inAnyOrder(() {
-        withPermutations((i, j, k) =>
-            expectRemoveEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
-      });
+      inAnyOrder(withPermutations((i, j, k) =>
+          isRemoveEvent("dir/sub/sub-$i/sub-$j/file-$k.txt")));
     });
 
     test('emits events for many nested files moved at once', () {
@@ -211,12 +257,12 @@
       startWatcher(dir: "dir");
       renameDir("dir/old", "dir/new");
 
-      inAnyOrder(() {
-        withPermutations((i, j, k) {
-          expectRemoveEvent("dir/old/sub-$i/sub-$j/file-$k.txt");
-          expectAddEvent("dir/new/sub-$i/sub-$j/file-$k.txt");
-        });
-      });
+      inAnyOrder(unionAll(withPermutations((i, j, k) {
+        return new Set.from([
+          isRemoveEvent("dir/old/sub-$i/sub-$j/file-$k.txt"),
+          isAddEvent("dir/new/sub-$i/sub-$j/file-$k.txt")
+        ]);
+      })));
     });
 
     test("emits events for many files added at once in a subdirectory with the "
@@ -228,11 +274,11 @@
 
       deleteFile("dir/sub");
       renameDir("old", "dir/sub");
-      inAnyOrder(() {
-        expectRemoveEvent("dir/sub");
-        withPermutations((i, j, k)  =>
-            expectAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
-      });
+
+      var events = withPermutations((i, j, k)  =>
+          isAddEvent("dir/sub/sub-$i/sub-$j/file-$k.txt"));
+      events.add(isRemoveEvent("dir/sub"));
+      inAnyOrder(events);
     });
   });
 }
diff --git a/pkg/watcher/test/utils.dart b/pkg/watcher/test/utils.dart
index a7bd9b6..b520bbd 100644
--- a/pkg/watcher/test/utils.dart
+++ b/pkg/watcher/test/utils.dart
@@ -5,10 +5,10 @@
 library watcher.test.utils;
 
 import 'dart:async';
-import 'dart:collection';
 import 'dart:io';
 
 import 'package:path/path.dart' as p;
+import 'package:scheduled_test/scheduled_stream.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:unittest/compact_vm_config.dart';
 import 'package:watcher/watcher.dart';
@@ -25,11 +25,6 @@
 /// The [DirectoryWatcher] being used for the current scheduled test.
 DirectoryWatcher _watcher;
 
-/// The index in [_watcher]'s event stream for the next event. When event
-/// expectations are set using [expectEvent] (et. al.), they use this to
-/// expect a series of events in order.
-var _nextEvent = 0;
-
 /// The mock modification times (in milliseconds since epoch) for each file.
 ///
 /// The actual file system has pretty coarse granularity for file modification
@@ -111,7 +106,7 @@
 }
 
 /// The stream of events from the watcher started with [startWatcher].
-Stream _watcherEvents;
+ScheduledStream<WatchEvent> _watcherEvents;
 
 /// Creates a new [DirectoryWatcher] that watches a temporary directory and
 /// starts monitoring it for events.
@@ -120,7 +115,7 @@
 void startWatcher({String dir}) {
   var testCase = currentTestCase.description;
   if (MacOSDirectoryWatcher.logDebugInfo) {
-    print("starting watcher for $testCase");
+    print("starting watcher for $testCase (${new DateTime.now()})");
   }
 
   // We want to wait until we're ready *after* we subscribe to the watcher's
@@ -130,82 +125,102 @@
   // Schedule [_watcher.events.listen] so that the watcher doesn't start
   // watching [dir] before it exists. Expose [_watcherEvents] immediately so
   // that it can be accessed synchronously after this.
-  _watcherEvents = futureStream(schedule(() {
-    var allEvents = new Queue();
-    var subscription = _watcher.events.listen(allEvents.add,
-        onError: currentSchedule.signalError);
-
+  _watcherEvents = new ScheduledStream(futureStream(schedule(() {
     currentSchedule.onComplete.schedule(() {
       if (MacOSDirectoryWatcher.logDebugInfo) {
-        print("stopping watcher for $testCase");
+        print("stopping watcher for $testCase (${new DateTime.now()})");
       }
 
-      var numEvents = _nextEvent;
-      subscription.cancel();
-      _nextEvent = 0;
       _watcher = null;
+      if (!_closePending) _watcherEvents.close();
 
       // If there are already errors, don't add this to the output and make
       // people think it might be the root cause.
       if (currentSchedule.errors.isEmpty) {
-        expect(allEvents, hasLength(numEvents));
-      } else {
-        currentSchedule.addDebugInfo("Events fired:\n${allEvents.join('\n')}");
+        _watcherEvents.expect(isDone);
       }
     }, "reset watcher");
 
     return _watcher.events;
-  }, "create watcher"), broadcast: true);
+  }, "create watcher"), broadcast: true));
 
   schedule(() => _watcher.ready, "wait for watcher to be ready");
 }
 
-/// A future set by [inAnyOrder] that will complete to the set of events that
-/// occur in the [inAnyOrder] block.
-Future<Set<WatchEvent>> _unorderedEventFuture;
+/// Whether an event to close [_watcherEvents] has been scheduled.
+bool _closePending = false;
 
-/// Runs [block] and allows multiple [expectEvent] calls in that block to match
-/// events in any order.
-void inAnyOrder(block()) {
-  var oldFuture = _unorderedEventFuture;
+/// Schedule closing the directory watcher stream after the event queue has been
+/// pumped.
+///
+/// This is necessary when events are allowed to occur, but don't have to occur,
+/// at the end of a test. Otherwise, if they don't occur, the test will wait
+/// indefinitely because they might in the future and because the watcher is
+/// normally only closed after the test completes.
+void startClosingEventStream() {
+  schedule(() {
+    _closePending = true;
+    pumpEventQueue().then((_) => _watcherEvents.close()).whenComplete(() {
+      _closePending = false;
+    });
+  }, 'start closing event stream');
+}
+
+/// A list of [StreamMatcher]s that have been collected using
+/// [_collectStreamMatcher].
+List<StreamMatcher> _collectedStreamMatchers;
+
+/// Collects all stream matchers that are registered within [block] into a
+/// single stream matcher.
+///
+/// The returned matcher will match each of the collected matchers in order.
+StreamMatcher _collectStreamMatcher(block()) {
+  var oldStreamMatchers = _collectedStreamMatchers;
+  _collectedStreamMatchers = new List<StreamMatcher>();
   try {
-    var firstEvent = _nextEvent;
-    var completer = new Completer();
-    _unorderedEventFuture = completer.future;
     block();
-
-    _watcherEvents.skip(firstEvent).take(_nextEvent - firstEvent).toSet()
-        .then(completer.complete, onError: completer.completeError);
-    currentSchedule.wrapFuture(_unorderedEventFuture,
-        "waiting for ${_nextEvent - firstEvent} events");
+    return inOrder(_collectedStreamMatchers);
   } finally {
-    _unorderedEventFuture = oldFuture;
+    _collectedStreamMatchers = oldStreamMatchers;
   }
 }
 
-/// Expects that the next set of event will be a change of [type] on [path].
+/// Either add [streamMatcher] as an expectation to [_watcherEvents], or collect
+/// it with [_collectStreamMatcher].
 ///
-/// Multiple calls to [expectEvent] require that the events are received in that
-/// order unless they're called in an [inAnyOrder] block.
-void expectEvent(ChangeType type, String path) {
-  if (_unorderedEventFuture != null) {
-    // Assign this to a local variable since it will be un-assigned by the time
-    // the scheduled callback runs.
-    var future = _unorderedEventFuture;
-
-    expect(
-        schedule(() => future, "should fire $type event on $path"),
-        completion(contains(isWatchEvent(type, path))));
+/// [streamMatcher] can be a [StreamMatcher], a [Matcher], or a value.
+void _expectOrCollect(streamMatcher) {
+  if (_collectedStreamMatchers != null) {
+    _collectedStreamMatchers.add(new StreamMatcher.wrap(streamMatcher));
   } else {
-    var future = currentSchedule.wrapFuture(
-        _watcherEvents.elementAt(_nextEvent),
-        "waiting for $type event on $path");
-
-    expect(
-        schedule(() => future, "should fire $type event on $path"),
-        completion(isWatchEvent(type, path)));
+    _watcherEvents.expect(streamMatcher);
   }
-  _nextEvent++;
+}
+
+/// Expects that [matchers] will match emitted events in any order.
+///
+/// [matchers] may be [Matcher]s or values, but not [StreamMatcher]s.
+void inAnyOrder(Iterable matchers) {
+  matchers = matchers.toSet();
+  _expectOrCollect(nextValues(matchers.length, unorderedMatches(matchers)));
+}
+
+/// Expects that the expectations established in either [block1] or [block2]
+/// will match the emitted events.
+///
+/// If both blocks match, the one that consumed more events will be used.
+void allowEither(block1(), block2()) {
+  _expectOrCollect(either(
+      _collectStreamMatcher(block1), _collectStreamMatcher(block2)));
+}
+
+/// Allows the expectations established in [block] to match the emitted events.
+///
+/// If the expectations in [block] don't match, no error will be raised and no
+/// events will be consumed. If this is used at the end of a test,
+/// [startClosingEventStream] should be called before it.
+void allowEvents(block()) {
+  _expectOrCollect(allow(_collectStreamMatcher(block)));
 }
 
 /// Returns a matcher that matches a [WatchEvent] with the given [type] and
@@ -217,9 +232,53 @@
   }, "is $type $path");
 }
 
-void expectAddEvent(String path) => expectEvent(ChangeType.ADD, path);
-void expectModifyEvent(String path) => expectEvent(ChangeType.MODIFY, path);
-void expectRemoveEvent(String path) => expectEvent(ChangeType.REMOVE, path);
+/// Returns a [Matcher] that matches a [WatchEvent] for an add event for [path].
+Matcher isAddEvent(String path) => isWatchEvent(ChangeType.ADD, path);
+
+/// Returns a [Matcher] that matches a [WatchEvent] for a modification event for
+/// [path].
+Matcher isModifyEvent(String path) => isWatchEvent(ChangeType.MODIFY, path);
+
+/// Returns a [Matcher] that matches a [WatchEvent] for a removal event for
+/// [path].
+Matcher isRemoveEvent(String path) => isWatchEvent(ChangeType.REMOVE, path);
+
+/// Expects that the next event emitted will be for an add event for [path].
+void expectAddEvent(String path) =>
+  _expectOrCollect(isWatchEvent(ChangeType.ADD, path));
+
+/// Expects that the next event emitted will be for a modification event for
+/// [path].
+void expectModifyEvent(String path) =>
+  _expectOrCollect(isWatchEvent(ChangeType.MODIFY, path));
+
+/// Expects that the next event emitted will be for a removal event for [path].
+void expectRemoveEvent(String path) =>
+  _expectOrCollect(isWatchEvent(ChangeType.REMOVE, path));
+
+/// Consumes an add event for [path] if one is emitted at this point in the
+/// schedule, but doesn't throw an error if it isn't.
+///
+/// If this is used at the end of a test, [startClosingEventStream] should be
+/// called before it.
+void allowAddEvent(String path) =>
+  _expectOrCollect(allow(isWatchEvent(ChangeType.ADD, path)));
+
+/// Consumes a modification event for [path] if one is emitted at this point in
+/// the schedule, but doesn't throw an error if it isn't.
+///
+/// If this is used at the end of a test, [startClosingEventStream] should be
+/// called before it.
+void allowModifyEvent(String path) =>
+  _expectOrCollect(allow(isWatchEvent(ChangeType.MODIFY, path)));
+
+/// Consumes a removal event for [path] if one is emitted at this point in the
+/// schedule, but doesn't throw an error if it isn't.
+///
+/// If this is used at the end of a test, [startClosingEventStream] should be
+/// called before it.
+void allowRemoveEvent(String path) =>
+  _expectOrCollect(allow(isWatchEvent(ChangeType.REMOVE, path)));
 
 /// Schedules writing a file in the sandbox at [path] with [contents].
 ///
@@ -238,6 +297,9 @@
       dir.createSync(recursive: true);
     }
 
+    if (MacOSDirectoryWatcher.logDebugInfo) {
+      print("[test] writing file $path");
+    }
     new File(fullPath).writeAsStringSync(contents);
 
     // Manually update the mock modification time for the file.
@@ -254,6 +316,9 @@
 /// Schedules deleting a file in the sandbox at [path].
 void deleteFile(String path) {
   schedule(() {
+    if (MacOSDirectoryWatcher.logDebugInfo) {
+      print("[test] deleting file $path");
+    }
     new File(p.join(_sandboxDir, path)).deleteSync();
   }, "delete file $path");
 }
@@ -263,6 +328,10 @@
 /// If [contents] is omitted, creates an empty file.
 void renameFile(String from, String to) {
   schedule(() {
+    if (MacOSDirectoryWatcher.logDebugInfo) {
+      print("[test] renaming file $from to $to");
+    }
+
     new File(p.join(_sandboxDir, from)).renameSync(p.join(_sandboxDir, to));
 
     // Make sure we always use the same separator on Windows.
@@ -277,6 +346,9 @@
 /// Schedules creating a directory in the sandbox at [path].
 void createDir(String path) {
   schedule(() {
+    if (MacOSDirectoryWatcher.logDebugInfo) {
+      print("[test] creating directory $path");
+    }
     new Directory(p.join(_sandboxDir, path)).createSync();
   }, "create directory $path");
 }
@@ -284,6 +356,9 @@
 /// Schedules renaming a directory in the sandbox from [from] to [to].
 void renameDir(String from, String to) {
   schedule(() {
+    if (MacOSDirectoryWatcher.logDebugInfo) {
+      print("[test] renaming directory $from to $to");
+    }
     new Directory(p.join(_sandboxDir, from))
         .renameSync(p.join(_sandboxDir, to));
   }, "rename directory $from to $to");
@@ -292,6 +367,9 @@
 /// Schedules deleting a directory in the sandbox at [path].
 void deleteDir(String path) {
   schedule(() {
+    if (MacOSDirectoryWatcher.logDebugInfo) {
+      print("[test] deleting directory $path");
+    }
     new Directory(p.join(_sandboxDir, path)).deleteSync(recursive: true);
   }, "delete directory $path");
 }
@@ -299,14 +377,18 @@
 /// Runs [callback] with every permutation of non-negative [i], [j], and [k]
 /// less than [limit].
 ///
+/// Returns a set of all values returns by [callback].
+///
 /// [limit] defaults to 3.
-void withPermutations(callback(int i, int j, int k), {int limit}) {
+Set withPermutations(callback(int i, int j, int k), {int limit}) {
   if (limit == null) limit = 3;
+  var results = new Set();
   for (var i = 0; i < limit; i++) {
     for (var j = 0; j < limit; j++) {
       for (var k = 0; k < limit; k++) {
-        callback(i, j, k);
+        results.add(callback(i, j, k));
       }
     }
   }
+  return results;
 }
diff --git a/pkg/yaml/LICENSE b/pkg/yaml/LICENSE
new file mode 100644
index 0000000..5c60afe
--- /dev/null
+++ b/pkg/yaml/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2014, 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/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 664adc7..2a0b6be 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -369,6 +369,9 @@
             'python',
             'tools/create_resources.py',
             '--output', '<(resources_cc_file)',
+            '--outer_namespace', 'dart',
+            '--inner_namespace', 'bin',
+            '--table_name', 'service_bin',
             '--root_prefix', 'bin/',
             '<@(_sources)'
           ],
@@ -396,7 +399,6 @@
         'builtin_nolib.cc',
         'builtin.h',
         'io_natives.h',
-        'resources.h',
         'vmservice.h',
         'vmservice_impl.cc',
         'vmservice_impl.h',
@@ -446,7 +448,6 @@
         'builtin_natives.cc',
         'builtin.h',
         'io_natives.h',
-        'resources.h',
         'vmservice.h',
         'vmservice_impl.cc',
         'vmservice_impl.h',
diff --git a/runtime/bin/crypto.cc b/runtime/bin/crypto.cc
index 4c0943a..6becae8 100644
--- a/runtime/bin/crypto.cc
+++ b/runtime/bin/crypto.cc
@@ -13,23 +13,29 @@
 
 void FUNCTION_NAME(Crypto_GetRandomBytes)(Dart_NativeArguments args) {
   Dart_Handle count_obj = Dart_GetNativeArgument(args, 0);
-  int64_t count = 0;
-  if (!DartUtils::GetInt64Value(count_obj, &count)) {
+  const int64_t kMaxRandomBytes = 4096;
+  int64_t count64 = 0;
+  if (!DartUtils::GetInt64Value(count_obj, &count64) ||
+      (count64 < 0) || (count64 > kMaxRandomBytes)) {
     Dart_Handle error =
-        DartUtils::NewString("Invalid argument, must be an int.");
+        DartUtils::NewString("Invalid argument: count must be a positive int "
+                             "less than or equal to 4096.");
     Dart_ThrowException(error);
   }
+  intptr_t count = static_cast<intptr_t>(count64);
   uint8_t* buffer = new uint8_t[count];
   ASSERT(buffer != NULL);
   if (!Crypto::GetRandomBytes(count, buffer)) {
     delete[] buffer;
     Dart_ThrowException(DartUtils::NewDartOSError());
+    UNREACHABLE();
   }
   Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, count);
   if (Dart_IsError(result)) {
     delete[] buffer;
     Dart_Handle error = DartUtils::NewString("Failed to allocate storage.");
     Dart_ThrowException(error);
+    UNREACHABLE();
   }
   Dart_ListSetAsBytes(result, 0, buffer, count);
   Dart_SetReturnValue(args, result);
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 6e9aa00..2b8e495 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -26,13 +26,14 @@
 const char* DartUtils::kDartExtensionScheme = "dart-ext:";
 const char* DartUtils::kAsyncLibURL = "dart:async";
 const char* DartUtils::kBuiltinLibURL = "dart:builtin";
-const char* DartUtils::kCollectionDevLibURL = "dart:_collection-dev";
 const char* DartUtils::kCoreLibURL = "dart:core";
+const char* DartUtils::kInternalLibURL = "dart:_internal";
 const char* DartUtils::kIsolateLibURL = "dart:isolate";
 const char* DartUtils::kIOLibURL = "dart:io";
 const char* DartUtils::kIOLibPatchURL = "dart:io-patch";
 const char* DartUtils::kUriLibURL = "dart:uri";
 const char* DartUtils::kHttpScheme = "http:";
+const char* DartUtils::kVMServiceLibURL = "dart:vmservice";
 
 const char* DartUtils::kIdFieldName = "_id";
 
@@ -126,7 +127,7 @@
 
 void DartUtils::SetIntegerField(Dart_Handle handle,
                                 const char* name,
-                                intptr_t val) {
+                                int64_t val) {
   Dart_Handle result = Dart_SetField(handle,
                                      NewString(name),
                                      Dart_NewInteger(val));
@@ -134,15 +135,6 @@
 }
 
 
-intptr_t DartUtils::GetIntegerField(Dart_Handle handle,
-                                    const char* name) {
-  Dart_Handle result = Dart_GetField(handle, NewString(name));
-  if (Dart_IsError(result)) Dart_PropagateError(result);
-  intptr_t value = DartUtils::GetIntegerValue(result);
-  return value;
-}
-
-
 void DartUtils::SetStringField(Dart_Handle handle,
                                const char* name,
                                const char* val) {
@@ -223,19 +215,24 @@
 
 
 void DartUtils::ReadFile(const uint8_t** data,
-                         intptr_t* file_len,
+                         intptr_t* len,
                          void* stream) {
   ASSERT(data != NULL);
-  ASSERT(file_len != NULL);
+  ASSERT(len != NULL);
   ASSERT(stream != NULL);
   File* file_stream = reinterpret_cast<File*>(stream);
-  *file_len = file_stream->Length();
-  ASSERT(*file_len > 0);
-  uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*file_len));
-  ASSERT(text_buffer != NULL);
-  if (!file_stream->ReadFully(text_buffer, *file_len)) {
+  int64_t file_len = file_stream->Length();
+  if ((file_len < 0) || (file_len > kIntptrMax)) {
     *data = NULL;
-    *file_len = -1;  // Indicates read was not successful.
+    *len = -1;  // Indicates read was not successful.
+    return;
+  }
+  *len = static_cast<intptr_t>(file_len);
+  uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*len));
+  ASSERT(text_buffer != NULL);
+  if (!file_stream->ReadFully(text_buffer, *len)) {
+    *data = NULL;
+    *len = -1;  // Indicates read was not successful.
     return;
   }
   *data = text_buffer;
@@ -299,7 +296,7 @@
   if (Dart_IsError(result)) {
     return result;
   }
-  intptr_t responseCode = DartUtils::GetIntegerValue(result);
+  int64_t responseCode = DartUtils::GetIntegerValue(result);
   if (responseCode != HttpResponseCodeOK) {
     // Return error.
     Dart_Handle responseStatus =
@@ -682,11 +679,11 @@
   // Setup the internal library's 'internalPrint' function.
   Dart_Handle print = Dart_Invoke(
       builtin_lib, NewString("_getPrintClosure"), 0, NULL);
-  Dart_Handle url = NewString(kCollectionDevLibURL);
+  Dart_Handle url = NewString(kInternalLibURL);
   DART_CHECK_VALID(url);
-  Dart_Handle collection_dev_lib = Dart_LookupLibrary(url);
-  DART_CHECK_VALID(collection_dev_lib);
-  Dart_Handle result = Dart_SetField(collection_dev_lib,
+  Dart_Handle internal_lib = Dart_LookupLibrary(url);
+  DART_CHECK_VALID(internal_lib);
+  Dart_Handle result = Dart_SetField(internal_lib,
                                      NewString("_printClosure"),
                                      print);
   DART_CHECK_VALID(result);
@@ -1034,10 +1031,10 @@
   // Make sure that we do not have an integer overflow here. Actual check
   // against max elements will be done at the time of writing, as the constant
   // is not part of the public API.
-  if (length > kIntptrMax) {
+  if ((length < 0) || (length > kIntptrMax)) {
     return NULL;
   }
-  uint8_t* data = IOBuffer::Allocate(length);
+  uint8_t* data = IOBuffer::Allocate(static_cast<intptr_t>(length));
   ASSERT(data != NULL);
   return NewExternalUint8Array(
       static_cast<intptr_t>(length), data, data, IOBuffer::Finalizer);
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 3e1dbe9..fc7963b 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -104,9 +104,7 @@
 
   static void SetIntegerField(Dart_Handle handle,
                               const char* name,
-                              intptr_t val);
-  static intptr_t GetIntegerField(Dart_Handle handle,
-                                  const char* name);
+                              int64_t val);
   static void SetStringField(Dart_Handle handle,
                              const char* name,
                              const char* val);
@@ -209,13 +207,14 @@
   static const char* kDartExtensionScheme;
   static const char* kAsyncLibURL;
   static const char* kBuiltinLibURL;
-  static const char* kCollectionDevLibURL;
   static const char* kCoreLibURL;
+  static const char* kInternalLibURL;
   static const char* kIsolateLibURL;
   static const char* kIOLibURL;
   static const char* kIOLibPatchURL;
   static const char* kUriLibURL;
   static const char* kHttpScheme;
+  static const char* kVMServiceLibURL;
 
   static const char* kIdFieldName;
 
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 55f2db4..ebd8a07 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -264,7 +264,7 @@
   }
   if (print_text_field) {
     buf->Printf(",\"text\":\"");
-    const intptr_t max_chars = 250;
+    const intptr_t max_chars = 1024;
     FormatTextualValue(buf, object, max_chars, true);
     buf->Printf("\"");
   }
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index 02f841d..e89dd05 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -79,11 +79,6 @@
   }
 
   if (lister_ == 0) {
-    if (!listing->path_buffer().Add(File::PathSeparator())) {
-      done_ = true;
-      return kListError;
-    }
-    path_length_ = listing->path_buffer().length();
     do {
       lister_ = reinterpret_cast<intptr_t>(
           opendir(listing->path_buffer().AsString()));
@@ -93,6 +88,12 @@
       done_ = true;
       return kListError;
     }
+    if (parent_ != NULL) {
+      if (!listing->path_buffer().Add(File::PathSeparator())) {
+        return kListError;
+      }
+    }
+    path_length_ = listing->path_buffer().length();
   }
   // Reset.
   listing->path_buffer().Reset(path_length_);
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index 3b9d016..c37b58b 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -80,11 +80,6 @@
   }
 
   if (lister_ == 0) {
-    if (!listing->path_buffer().Add(File::PathSeparator())) {
-      done_ = true;
-      return kListError;
-    }
-    path_length_ = listing->path_buffer().length();
     do {
       lister_ = reinterpret_cast<intptr_t>(
           opendir(listing->path_buffer().AsString()));
@@ -94,6 +89,12 @@
       done_ = true;
       return kListError;
     }
+    if (parent_ != NULL) {
+      if (!listing->path_buffer().Add(File::PathSeparator())) {
+        return kListError;
+      }
+    }
+    path_length_ = listing->path_buffer().length();
   }
   // Reset.
   listing->path_buffer().Reset(path_length_);
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index feb9a9c..94b495d 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -79,11 +79,6 @@
   }
 
   if (lister_ == 0) {
-    if (!listing->path_buffer().Add(File::PathSeparator())) {
-      done_ = true;
-      return kListError;
-    }
-    path_length_ = listing->path_buffer().length();
     do {
       lister_ = reinterpret_cast<intptr_t>(
           opendir(listing->path_buffer().AsString()));
@@ -93,6 +88,12 @@
       done_ = true;
       return kListError;
     }
+    if (parent_ != NULL) {
+      if (!listing->path_buffer().Add(File::PathSeparator())) {
+        return kListError;
+      }
+    }
+    path_length_ = listing->path_buffer().length();
   }
   // Reset.
   listing->path_buffer().Reset(path_length_);
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index 3733a71..27b0eea 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -170,7 +170,8 @@
   WIN32_FIND_DATAW find_file_data;
 
   if (lister_ == 0) {
-    if (!listing->path_buffer().AddW(L"\\*")) {
+    const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*";
+    if (!listing->path_buffer().AddW(tail)) {
       done_ = true;
       return kListError;
     }
diff --git a/runtime/bin/eventhandler.cc b/runtime/bin/eventhandler.cc
index e19e928..0c5b765 100644
--- a/runtime/bin/eventhandler.cc
+++ b/runtime/bin/eventhandler.cc
@@ -92,11 +92,21 @@
   } else {
     id = Socket::GetSocketIdNativeField(sender);
   }
+  // Get the _id field out of the port.
   Dart_Handle handle = Dart_GetNativeArgument(args, 1);
-  Dart_Port dart_port =
-      DartUtils::GetIntegerField(handle, DartUtils::kIdFieldName);
+  handle = Dart_GetField(handle, DartUtils::NewString(DartUtils::kIdFieldName));
+  if (Dart_IsError(handle)) {
+    Dart_PropagateError(handle);
+    UNREACHABLE();
+  }
+  Dart_Port dart_port;
+  handle = Dart_IntegerToInt64(handle, &dart_port);
+  if (Dart_IsError(handle)) {
+    Dart_PropagateError(handle);
+    UNREACHABLE();
+  }
   int64_t data = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
-  if (id == kTimerId && data == 0) {
+  if ((id == kTimerId) && (data == 0)) {
     // This is a 0-timer. Simply queue a 'null' on the port.
     DartUtils::PostNull(dart_port);
   } else {
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index 6c7744f..bf047a4 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -256,7 +256,9 @@
           DartUtils::PostInt32(msg[i].dart_port, 1 << kCloseEvent);
         } else {
           // Setup events to wait for.
-          sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
+          ASSERT((msg[i].data > 0) && (msg[i].data < kIntptrMax));
+          sd->SetPortAndMask(msg[i].dart_port,
+                             static_cast<intptr_t>(msg[i].data));
           UpdateKqueue(kqueue_fd_, sd);
         }
       }
@@ -411,8 +413,10 @@
     struct timespec* timeout = NULL;
     struct timespec ts;
     if (millis >= 0) {
-      ts.tv_sec = millis / 1000;
-      ts.tv_nsec = (millis - (ts.tv_sec * 1000)) * 1000000;
+      int32_t millis32 = static_cast<int32_t>(millis);
+      int32_t secs = millis32 / 1000;
+      ts.tv_sec = secs;
+      ts.tv_nsec = (millis32 - (secs * 1000)) * 1000000;
       timeout = &ts;
     }
     intptr_t result = TEMP_FAILURE_RETRY(kevent(handler_impl->kqueue_fd_,
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 7f40f96..d7fcaed 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -333,7 +333,7 @@
 void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) {
   File* file = GetFilePointer(Dart_GetNativeArgument(args, 0));
   ASSERT(file != NULL);
-  off64_t return_value = file->Length();
+  int64_t return_value = file->Length();
   if (return_value >= 0) {
     Dart_SetReturnValue(args, Dart_NewInteger(return_value));
   } else {
@@ -347,7 +347,7 @@
 void FUNCTION_NAME(File_LengthFromPath)(Dart_NativeArguments args) {
   const char* path =
       DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
-  off64_t return_value = File::LengthFromPath(path);
+  int64_t return_value = File::LengthFromPath(path);
   if (return_value >= 0) {
     Dart_SetReturnValue(args, Dart_NewInteger(return_value));
   } else {
@@ -789,7 +789,7 @@
     File* file = CObjectToFilePointer(request[0]);
     ASSERT(file != NULL);
     if (!file->IsClosed()) {
-      off64_t position = CObjectInt32OrInt64ToInt64(request[1]);
+      int64_t position = CObjectInt32OrInt64ToInt64(request[1]);
       if (file->SetPosition(position)) {
         return CObject::True();
       } else {
@@ -829,7 +829,7 @@
     File* file = CObjectToFilePointer(request[0]);
     ASSERT(file != NULL);
     if (!file->IsClosed()) {
-      off64_t return_value = file->Length();
+      int64_t return_value = file->Length();
       if (return_value >= 0) {
         return new CObjectInt64(CObject::NewInt64(return_value));
       } else {
@@ -846,7 +846,7 @@
 CObject* File::LengthFromPathRequest(const CObjectArray& request) {
   if (request.Length() == 1 && request[0]->IsString()) {
     CObjectString filepath(request[0]);
-    off64_t return_value = File::LengthFromPath(filepath.CString());
+    int64_t return_value = File::LengthFromPath(filepath.CString());
     if (return_value >= 0) {
       return new CObjectInt64(CObject::NewInt64(return_value));
     } else {
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index ec1bac8..fd6427b 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -90,17 +90,17 @@
 
   // Get the length of the file. Returns a negative value if the length cannot
   // be determined (e.g. not seekable device).
-  off64_t Length();
+  int64_t Length();
 
   // Get the current position in the file.
   // Returns a negative value if position cannot be determined.
-  off64_t Position();
+  int64_t Position();
 
   // Set the byte position in the file.
-  bool SetPosition(off64_t position);
+  bool SetPosition(int64_t position);
 
   // Truncate (or extend) the file to the given length in bytes.
-  bool Truncate(off64_t length);
+  bool Truncate(int64_t length);
 
   // Flush contents of file.
   bool Flush();
@@ -127,7 +127,7 @@
   static bool Rename(const char* old_path, const char* new_path);
   static bool RenameLink(const char* old_path, const char* new_path);
   static bool Copy(const char* old_path, const char* new_path);
-  static off64_t LengthFromPath(const char* path);
+  static int64_t LengthFromPath(const char* path);
   static void Stat(const char* path, int64_t* data);
   static time_t LastModified(const char* path);
   static char* LinkTarget(const char* pathname);
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 3851c32..b00e22d 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -78,19 +78,19 @@
 }
 
 
-off64_t File::Position() {
+int64_t File::Position() {
   ASSERT(handle_->fd() >= 0);
   return lseek64(handle_->fd(), 0, SEEK_CUR);
 }
 
 
-bool File::SetPosition(off64_t position) {
+bool File::SetPosition(int64_t position) {
   ASSERT(handle_->fd() >= 0);
   return lseek64(handle_->fd(), position, SEEK_SET) >= 0;
 }
 
 
-bool File::Truncate(off64_t length) {
+bool File::Truncate(int64_t length) {
   ASSERT(handle_->fd() >= 0);
   return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
       ftruncate(handle_->fd(), length) != -1);
@@ -103,7 +103,7 @@
 }
 
 
-off64_t File::Length() {
+int64_t File::Length() {
   ASSERT(handle_->fd() >= 0);
   struct stat st;
   if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fstat(handle_->fd(), &st)) == 0) {
@@ -135,7 +135,7 @@
     return NULL;
   }
   if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
-    off64_t position = lseek64(fd, 0, SEEK_END);
+    int64_t position = lseek64(fd, 0, SEEK_END);
     if (position < 0) {
       return NULL;
     }
@@ -285,7 +285,7 @@
 }
 
 
-off64_t File::LengthFromPath(const char* name) {
+int64_t File::LengthFromPath(const char* name) {
   struct stat st;
   if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) {
     return st.st_size;
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index b4c2b31..bc6f610 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -77,19 +77,19 @@
 }
 
 
-off64_t File::Position() {
+int64_t File::Position() {
   ASSERT(handle_->fd() >= 0);
   return lseek64(handle_->fd(), 0, SEEK_CUR);
 }
 
 
-bool File::SetPosition(off64_t position) {
+bool File::SetPosition(int64_t position) {
   ASSERT(handle_->fd() >= 0);
   return lseek64(handle_->fd(), position, SEEK_SET) >= 0;
 }
 
 
-bool File::Truncate(off64_t length) {
+bool File::Truncate(int64_t length) {
   ASSERT(handle_->fd() >= 0);
   return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
       ftruncate64(handle_->fd(), length) != -1);
@@ -102,7 +102,7 @@
 }
 
 
-off64_t File::Length() {
+int64_t File::Length() {
   ASSERT(handle_->fd() >= 0);
   struct stat64 st;
   if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fstat64(handle_->fd(), &st)) == 0) {
@@ -135,7 +135,7 @@
     return NULL;
   }
   if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
-    off64_t position = lseek64(fd, 0, SEEK_END);
+    int64_t position = lseek64(fd, 0, SEEK_END);
     if (position < 0) {
       return NULL;
     }
@@ -243,8 +243,8 @@
       VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(old_fd));
       return false;
     }
-    off64_t offset = 0;
-    int result = 1;
+    int64_t offset = 0;
+    intptr_t result = 1;
     while (result > 0) {
       // Loop to ensure we copy everything, and not only up to 2GB.
       result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
@@ -284,7 +284,7 @@
 }
 
 
-off64_t File::LengthFromPath(const char* name) {
+int64_t File::LengthFromPath(const char* name) {
   struct stat64 st;
   if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(name, &st)) == 0) {
     return st.st_size;
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index d750af8..6f704bf 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -78,19 +78,19 @@
 }
 
 
-off64_t File::Position() {
+int64_t File::Position() {
   ASSERT(handle_->fd() >= 0);
   return lseek(handle_->fd(), 0, SEEK_CUR);
 }
 
 
-bool File::SetPosition(off64_t position) {
+bool File::SetPosition(int64_t position) {
   ASSERT(handle_->fd() >= 0);
   return lseek(handle_->fd(), position, SEEK_SET) >= 0;
 }
 
 
-bool File::Truncate(off64_t length) {
+bool File::Truncate(int64_t length) {
   ASSERT(handle_->fd() >= 0);
   return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
       ftruncate(handle_->fd(), length) != -1);
@@ -103,7 +103,7 @@
 }
 
 
-off64_t File::Length() {
+int64_t File::Length() {
   ASSERT(handle_->fd() >= 0);
   struct stat st;
   if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fstat(handle_->fd(), &st)) == 0) {
@@ -136,7 +136,7 @@
   }
   FDUtils::SetCloseOnExec(fd);
   if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
-    off64_t position = lseek(fd, 0, SEEK_END);
+    int64_t position = lseek(fd, 0, SEEK_END);
     if (position < 0) {
       return NULL;
     }
@@ -239,7 +239,7 @@
 }
 
 
-off64_t File::LengthFromPath(const char* name) {
+int64_t File::LengthFromPath(const char* name) {
   struct stat st;
   if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) {
     return st.st_size;
diff --git a/runtime/bin/file_system_watcher_macos.cc b/runtime/bin/file_system_watcher_macos.cc
index c524e36..678f45f 100644
--- a/runtime/bin/file_system_watcher_macos.cc
+++ b/runtime/bin/file_system_watcher_macos.cc
@@ -181,7 +181,7 @@
     for (size_t i = 0; i < num_events; i++) {
       char *path = reinterpret_cast<char**>(event_paths)[i];
       FSEvent event;
-      event.data.exists = File::Exists(path);
+      event.data.exists = File::GetType(path, false) != File::kDoesNotExist;
       path += node->base_path_length();
       // If path is longer the base, skip next character ('/').
       if (path[0] != '\0') path += 1;
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 1be41cb..32905f4 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -72,19 +72,19 @@
 }
 
 
-off64_t File::Position() {
+int64_t File::Position() {
   ASSERT(handle_->fd() >= 0);
   return _lseeki64(handle_->fd(), 0, SEEK_CUR);
 }
 
 
-bool File::SetPosition(off64_t position) {
+bool File::SetPosition(int64_t position) {
   ASSERT(handle_->fd() >= 0);
   return _lseeki64(handle_->fd(), position, SEEK_SET) >= 0;
 }
 
 
-bool File::Truncate(off64_t length) {
+bool File::Truncate(int64_t length) {
   ASSERT(handle_->fd() >= 0);
   return _chsize_s(handle_->fd(), length) == 0;
 }
@@ -96,7 +96,7 @@
 }
 
 
-off64_t File::Length() {
+int64_t File::Length() {
   ASSERT(handle_->fd() >= 0);
   struct __stat64 st;
   if (_fstat64(handle_->fd(), &st) == 0) {
@@ -121,7 +121,7 @@
     return NULL;
   }
   if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
-    off64_t position = _lseeki64(fd, 0, SEEK_END);
+    int64_t position = _lseeki64(fd, 0, SEEK_END);
     if (position < 0) {
       return NULL;
     }
@@ -343,7 +343,7 @@
 }
 
 
-off64_t File::LengthFromPath(const char* name) {
+int64_t File::LengthFromPath(const char* name) {
   struct __stat64 st;
   const wchar_t* system_name = StringUtils::Utf8ToWide(name);
   int stat_status = _wstat64(system_name, &st);
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
index 3ea389d..34c0ee2 100644
--- a/runtime/bin/filter.cc
+++ b/runtime/bin/filter.cc
@@ -60,18 +60,19 @@
     Dart_ThrowException(DartUtils::NewInternalError(
         "Failed to get 'gzip' parameter"));
   }
-  int64_t level;
-  if (Dart_IsError(Dart_IntegerToInt64(level_obj, &level))) {
+  int64_t level = 0;
+  Dart_Handle result = Dart_IntegerToInt64(level_obj, &level);
+  if (Dart_IsError(result) || (level < kMinInt32) || (level > kMaxInt32)) {
     Dart_ThrowException(DartUtils::NewInternalError(
         "Failed to get 'level' parameter"));
   }
-  Filter* filter = new ZLibDeflateFilter(gzip, level);
+  Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level));
   if (filter == NULL || !filter->Init()) {
     delete filter;
     Dart_ThrowException(DartUtils::NewInternalError(
         "Failed to create ZLibDeflateFilter"));
   }
-  Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
+  result = Filter::SetFilterPointerNativeField(filter_obj, filter);
   if (Dart_IsError(result)) {
     delete filter;
     Dart_PropagateError(result);
diff --git a/runtime/bin/filter.h b/runtime/bin/filter.h
index 4c59759..16f1c6e 100644
--- a/runtime/bin/filter.h
+++ b/runtime/bin/filter.h
@@ -54,7 +54,7 @@
 
 class ZLibDeflateFilter : public Filter {
  public:
-  ZLibDeflateFilter(bool gzip = false, int level = 6)
+  ZLibDeflateFilter(bool gzip = false, int32_t level = 6)
     : gzip_(gzip), level_(level), current_buffer_(NULL) {}
   virtual ~ZLibDeflateFilter();
 
@@ -67,7 +67,7 @@
 
  private:
   const bool gzip_;
-  const int level_;
+  const int32_t level_;
   uint8_t* current_buffer_;
   z_stream stream_;
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 5debf11..9c0ab87 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -500,7 +500,8 @@
                        DartUtils::ReadFile,
                        DartUtils::WriteFile,
                        DartUtils::CloseFile,
-                       DartUtils::EntropySource)) {
+                       DartUtils::EntropySource,
+                       NULL)) {
     Log::PrintErr("VM initialization failed\n");
     return 255;
   }
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 59cf35a..c506ee4 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -424,16 +424,6 @@
 }
 
 
-#define CHECK_RESULT(result)                                                   \
-  if (Dart_IsError(result)) {                                                  \
-    *error = strdup(Dart_GetError(result));                                    \
-    *is_compile_error = Dart_IsCompilationError(result);                       \
-    Dart_ExitScope();                                                          \
-    Dart_ShutdownIsolate();                                                    \
-    return NULL;                                                               \
-  }                                                                            \
-
-
 static Dart_Handle EnvironmentCallback(Dart_Handle name) {
   uint8_t* utf8_array;
   intptr_t utf8_len;
@@ -466,6 +456,15 @@
 }
 
 
+#define CHECK_RESULT(result)                                                   \
+  if (Dart_IsError(result)) {                                                  \
+    *error = strdup(Dart_GetError(result));                                    \
+    *is_compile_error = Dart_IsCompilationError(result);                       \
+    Dart_ExitScope();                                                          \
+    Dart_ShutdownIsolate();                                                    \
+    return NULL;                                                               \
+  }                                                                            \
+
 // Returns true on success, false on failure.
 static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
                                                 const char* main,
@@ -524,26 +523,23 @@
     return NULL;
   }
 
+
   Platform::SetPackageRoot(package_root);
-  Dart_Handle io_lib_url = DartUtils::NewString("dart:io");
+  Dart_Handle io_lib_url = DartUtils::NewString(DartUtils::kIOLibURL);
   CHECK_RESULT(io_lib_url);
   Dart_Handle io_lib = Dart_LookupLibrary(io_lib_url);
   CHECK_RESULT(io_lib);
-  Dart_Handle platform_class_name = DartUtils::NewString("Platform");
-  CHECK_RESULT(platform_class_name);
-  Dart_Handle platform_type =
-      Dart_GetType(io_lib, platform_class_name, 0, NULL);
+  Dart_Handle platform_type = DartUtils::GetDartType(DartUtils::kIOLibURL,
+                                                     "Platform");
   CHECK_RESULT(platform_type);
-  Dart_Handle script_name_name = DartUtils::NewString("_nativeScript");
-  CHECK_RESULT(script_name_name);
+  Dart_Handle script_name = DartUtils::NewString("_nativeScript");
+  CHECK_RESULT(script_name);
   Dart_Handle dart_script = DartUtils::NewString(script_uri);
   CHECK_RESULT(dart_script);
   Dart_Handle set_script_name =
-      Dart_SetField(platform_type, script_name_name, dart_script);
+      Dart_SetField(platform_type, script_name, dart_script);
   CHECK_RESULT(set_script_name);
 
-  VmService::SendIsolateStartupMessage();
-
   // Make the isolate runnable so that it is ready to handle messages.
   Dart_ExitScope();
   Dart_ExitIsolate();
@@ -558,6 +554,7 @@
   return isolate;
 }
 
+#undef CHECK_RESULT
 
 static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
                                           const char* main,
@@ -584,6 +581,64 @@
 }
 
 
+#define CHECK_RESULT(result)                                                   \
+  if (Dart_IsError(result)) {                                                  \
+    *error = strdup(Dart_GetError(result));                                    \
+    Dart_ExitScope();                                                          \
+    Dart_ShutdownIsolate();                                                    \
+    return NULL;                                                               \
+  }                                                                            \
+
+static Dart_Isolate CreateServiceIsolate(void* data, char** error) {
+  const char* script_uri = DartUtils::kVMServiceLibURL;
+  IsolateData* isolate_data = new IsolateData(script_uri);
+  Dart_Isolate isolate =
+      Dart_CreateIsolate(script_uri, "main", snapshot_buffer, isolate_data,
+                         error);
+  if (isolate == NULL) {
+    return NULL;
+  }
+  Dart_EnterScope();
+  if (snapshot_buffer != NULL) {
+    // Setup the native resolver as the snapshot does not carry it.
+    Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
+    Builtin::SetNativeResolver(Builtin::kIOLibrary);
+  }
+  // Set up the library tag handler for this isolate.
+  Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
+  CHECK_RESULT(result);
+  result = Dart_SetEnvironmentCallback(EnvironmentCallback);
+  CHECK_RESULT(result);
+  // Prepare builtin and its dependent libraries for use to resolve URIs.
+  Dart_Handle builtin_lib =
+      Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+  CHECK_RESULT(builtin_lib);
+  // Prepare for script loading by setting up the 'print' and 'timer'
+  // closures and setting up 'package root' for URI resolution.
+  result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
+  CHECK_RESULT(result);
+  Platform::SetPackageRoot(package_root);
+  Dart_Handle io_lib_url = DartUtils::NewString(DartUtils::kIOLibURL);
+  CHECK_RESULT(io_lib_url);
+  Dart_Handle io_lib = Dart_LookupLibrary(io_lib_url);
+  CHECK_RESULT(io_lib);
+  Dart_Handle platform_type = DartUtils::GetDartType(DartUtils::kIOLibURL,
+                                                     "Platform");
+  CHECK_RESULT(platform_type);
+  Dart_Handle script_name = DartUtils::NewString("_nativeScript");
+  CHECK_RESULT(script_name);
+  Dart_Handle dart_script = DartUtils::NewString(script_uri);
+  CHECK_RESULT(dart_script);
+  Dart_Handle set_script_name =
+      Dart_SetField(platform_type, script_name, dart_script);
+  CHECK_RESULT(set_script_name);
+  Dart_ExitScope();
+  Dart_ExitIsolate();
+  return isolate;
+}
+
+#undef CHECK_RESULT
+
 static void PrintVersion() {
   Log::PrintErr("Dart VM version: %s\n", Dart_VersionString());
 }
@@ -716,7 +771,6 @@
 
 
 static void ShutdownIsolate(void* callback_data) {
-  VmService::VmServiceShutdownCallback(callback_data);
   IsolateData* isolate_data = reinterpret_cast<IsolateData*>(callback_data);
   delete isolate_data;
 }
@@ -812,7 +866,8 @@
                        DartUtils::ReadFile,
                        DartUtils::WriteFile,
                        DartUtils::CloseFile,
-                       DartUtils::EntropySource)) {
+                       DartUtils::EntropySource,
+                       CreateServiceIsolate)) {
     fprintf(stderr, "%s", "VM initialization failed\n");
     fflush(stderr);
     exit(kErrorExitCode);
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index b83ec1b..cab5b49 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -198,7 +198,7 @@
       throw new ArgumentError("Environment is not a map: $environment");
     }
     if (identical(true, includeParentEnvironment)) {
-      environment = Platform.environment..addAll(environment);
+      environment = new Map.from(Platform.environment)..addAll(environment);
     }
     environment.forEach((key, value) {
       if (key is !String || value is !String) {
diff --git a/runtime/bin/resources.h b/runtime/bin/resources.h
deleted file mode 100644
index 02cc967..0000000
--- a/runtime/bin/resources.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef BIN_RESOURCES_H_
-#define BIN_RESOURCES_H_
-
-#include <stddef.h>
-#include <string.h>
-
-// Map from Blink to Dart VM.
-#if defined(_DEBUG)
-#define DEBUG
-#endif
-
-#include "platform/assert.h"
-
-
-namespace dart {
-namespace bin {
-
-class Resources {
- public:
-  static const int kNoSuchInstance = -1;
-
-  static int ResourceLookup(const char* path, const char** resource) {
-    for (int i = 0; i < get_resource_count(); i++) {
-      resource_map_entry* entry = get_resource(i);
-      if (strcmp(path, entry->path_) == 0) {
-        *resource = entry->resource_;
-        ASSERT(entry->length_ > 0);
-        return entry->length_;
-      }
-    }
-    return kNoSuchInstance;
-  }
-
-  static intptr_t get_resource_count() {
-    return builtin_resources_count_;
-  }
-
-  static const char* get_resource_path(intptr_t i) {
-    return get_resource(i)->path_;
-  }
-
- private:
-  struct resource_map_entry {
-    const char* path_;
-    const char* resource_;
-    intptr_t length_;
-  };
-
-  // These fields are generated by resources_gen.cc.
-  static resource_map_entry builtin_resources_[];
-  static const intptr_t builtin_resources_count_;
-
-  static resource_map_entry* get_resource(int i) {
-    ASSERT(i >= 0 && i < builtin_resources_count_);
-    return &builtin_resources_[i];
-  }
-
-  DISALLOW_ALLOCATION();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
-};
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // BIN_RESOURCES_H_
diff --git a/runtime/bin/resources_sources.gypi b/runtime/bin/resources_sources.gypi
index c5f7885..274909e 100644
--- a/runtime/bin/resources_sources.gypi
+++ b/runtime/bin/resources_sources.gypi
@@ -1,21 +1,15 @@
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 # for 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 Resources table.
 {
   'sources': [
-#  VM Service backend sources
-    'vmservice/client.dart',
-    'vmservice/constants.dart',
+# Standalone VM service sources.
     'vmservice/resources.dart',
-    'vmservice/running_isolate.dart',
-    'vmservice/running_isolates.dart',
     'vmservice/server.dart',
-    'vmservice/message.dart',
-    'vmservice/message_router.dart',
-    'vmservice/vmservice.dart',
     'vmservice/vmservice_io.dart',
-# VM Service frontend sources
+# Standalone VM frontend resources.
     'vmservice/client/deployed/web/index.html',
     'vmservice/client/deployed/web/favicon.ico',
     'vmservice/client/deployed/web/index.html_bootstrap.dart.js',
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 438a2cc..de890888 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -110,6 +110,7 @@
                                        dart::bin::DartUtils::ReadFile,
                                        dart::bin::DartUtils::WriteFile,
                                        dart::bin::DartUtils::CloseFile,
+                                       NULL,
                                        NULL);
   ASSERT(err_msg == NULL);
   // Apply the filter to all registered tests.
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 42fe373..351bfc6 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -53,7 +53,7 @@
   SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
   Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
   int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
-  intptr_t socket = Socket::CreateConnect(addr, port);
+  intptr_t socket = Socket::CreateConnect(addr, static_cast<intptr_t>(port));
   OSError error;
   if (socket >= 0) {
     Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
@@ -70,7 +70,9 @@
   Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
   int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
   bool reuse_addr = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
-  intptr_t socket = Socket::CreateBindDatagram(&addr, port, reuse_addr);
+  intptr_t socket = Socket::CreateBindDatagram(&addr,
+                                               static_cast<intptr_t>(port),
+                                               reuse_addr);
   if (socket >= 0) {
     Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
     Dart_SetReturnValue(args, Dart_True());
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html b/runtime/bin/vmservice/client/deployed/web/index.html
index 705a905..5ea5895 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html
+++ b/runtime/bin/vmservice/client/deployed/web/index.html
@@ -312,7 +312,7 @@
   <template>
   	<div class="row">
   	  <div class="col-md-1">
-        <img src="img/isolate_icon.png" class="img-polaroid">
+        <img src="packages/observatory/src/observatory_elements/img/isolate_icon.png" class="img-polaroid">
   	  </div>
   	  <div class="col-md-1">{{ isolate }}</div>
   	  <div class="col-md-10">{{ name }}</div>
@@ -345,6 +345,8 @@
         </li>
       </template>
       </ul>
+      (<a href="{{ app.locationManager.absoluteLink('cpu') }}">cpu</a>)
+      
   </template>
   
 </polymer-element><polymer-element name="instance-view" extends="observatory-element">
@@ -589,6 +591,9 @@
     <template if="{{ messageType == 'Script' }}">
       <script-view app="{{ app }}" script="{{ message }}"></script-view>
     </template>
+    <template if="{{ messageType == 'CPU' }}">
+      <json-view json="{{ message }}"></json-view>
+    </template>
     <!-- Add new views and message types in the future here. -->
   </template>
   
@@ -673,4 +678,4 @@
 </polymer-element>
   <observatory-application></observatory-application>
 
-</body></html>
+</body></html>
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
index e900a2c..cfdacaa 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
@@ -10540,7 +10540,7 @@
 call$0:[function(){if(B.G9()){var z=H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[null])
 z.L7(null,null)
 return z}return H.VM(new W.RO(document,"WebComponentsReady",!1),[null]).gFV(0)},"call$0" /* tearOffInfo */,null,0,0,null,"call"],
-$isEH:true}}],["dart._collection.dev","dart:_collection-dev",,H,{
+$isEH:true}}],["dart._collection.dev","dart:_internal",,H,{
 "":"",
 bQ:[function(a,b){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.mD)},"call$2" /* tearOffInfo */,"Mn",4,0,null,109,110],
@@ -18217,6 +18217,7 @@
 return"#/"+z+"/"+H.d(a)},"call$1" /* tearOffInfo */,"gVM",2,0,205,276,"currentIsolateRelativeLink",368],
 XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.dy,!1))},"call$1" /* tearOffInfo */,"gOs",2,0,205,506,"currentIsolateScriptLink",368],
 r4:[function(a,b){return"#/"+H.d(a)+"/"+H.d(b)},"call$2" /* tearOffInfo */,"gLc",4,0,507,508,276,"relativeLink",368],
+Lr:[function(a){return"#/"+H.d(a)},"call$1" /* tearOffInfo */,"geP",2,0,205,276,"absoluteLink",368],
 static:{"":"x4,K3D,qY,HT"}},
 us:{
 "":"Tp:228;a",
diff --git a/runtime/bin/vmservice/client/deployed/web/index_devtools.html b/runtime/bin/vmservice/client/deployed/web/index_devtools.html
index 5ede7ae..4d778cc 100644
--- a/runtime/bin/vmservice/client/deployed/web/index_devtools.html
+++ b/runtime/bin/vmservice/client/deployed/web/index_devtools.html
@@ -345,6 +345,8 @@
         </li>
       </template>
       </ul>
+      (<a href="{{ app.locationManager.absoluteLink('cpu') }}">cpu</a>)
+      
   </template>
   
 </polymer-element><polymer-element name="instance-view" extends="observatory-element">
@@ -589,6 +591,9 @@
     <template if="{{ messageType == 'Script' }}">
       <script-view app="{{ app }}" script="{{ message }}"></script-view>
     </template>
+    <template if="{{ messageType == 'CPU' }}">
+      <json-view json="{{ message }}"></json-view>
+    </template>
     <!-- Add new views and message types in the future here. -->
   </template>
   
diff --git a/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js b/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js
index 78826e9..f8f4a23 100644
--- a/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/client/deployed/web/index_devtools.html_bootstrap.dart.js
@@ -10540,7 +10540,7 @@
 call$0:[function(){if(B.G9()){var z=H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[null])
 z.L7(null,null)
 return z}return H.VM(new W.RO(document,"WebComponentsReady",!1),[null]).gFV(0)},"call$0" /* tearOffInfo */,null,0,0,null,"call"],
-$isEH:true}}],["dart._collection.dev","dart:_collection-dev",,H,{
+$isEH:true}}],["dart._collection.dev","dart:_internal",,H,{
 "":"",
 bQ:[function(a,b){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.mD)},"call$2" /* tearOffInfo */,"Mn",4,0,null,109,110],
@@ -18217,6 +18217,7 @@
 return"#/"+z+"/"+H.d(a)},"call$1" /* tearOffInfo */,"gVM",2,0,205,276,"currentIsolateRelativeLink",368],
 XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.dy,!1))},"call$1" /* tearOffInfo */,"gOs",2,0,205,506,"currentIsolateScriptLink",368],
 r4:[function(a,b){return"#/"+H.d(a)+"/"+H.d(b)},"call$2" /* tearOffInfo */,"gLc",4,0,507,508,276,"relativeLink",368],
+Lr:[function(a){return"#/"+H.d(a)},"call$1" /* tearOffInfo */,"geP",2,0,205,276,"absoluteLink",368],
 static:{"":"x4,K3D,qY,HT"}},
 us:{
 "":"Tp:228;a",
@@ -32714,7 +32715,7 @@
 call$0:[function(){if(B.G9()){var z=H.VM(new P.vs(0,$.X3,null,null,null,null,null,null),[null])
 z.L7(null,null)
 return z}return H.VM(new W.RO(document,"WebComponentsReady",!1),[null]).gFV(0)},"call$0" /* tearOffInfo */,null,0,0,null,"call"],
-$isEH:true}}],["dart._collection.dev","dart:_collection-dev",,H,{
+$isEH:true}}],["dart._collection.dev","dart:_internal",,H,{
 "":"",
 bQ:[function(a,b){var z
 for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();)b.call$1(z.mD)},"call$2" /* tearOffInfo */,"Mn",4,0,null,109,110],
@@ -40391,6 +40392,7 @@
 return"#/"+z+"/"+H.d(a)},"call$1" /* tearOffInfo */,"gVM",2,0,205,276,"currentIsolateRelativeLink",368],
 XY:[function(a){return this.kP("scripts/"+P.jW(C.yD,a,C.dy,!1))},"call$1" /* tearOffInfo */,"gOs",2,0,205,506,"currentIsolateScriptLink",368],
 r4:[function(a,b){return"#/"+H.d(a)+"/"+H.d(b)},"call$2" /* tearOffInfo */,"gLc",4,0,507,508,276,"relativeLink",368],
+Lr:[function(a){return"#/"+H.d(a)},"call$1" /* tearOffInfo */,"geP",2,0,205,276,"absoluteLink",368],
 static:{"":"x4,K3D,qY,HT"}},
 us:{
 "":"Tp:228;a",
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart b/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart
index 115e361..509385c 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart
@@ -110,4 +110,10 @@
   String relativeLink(String isolateId, String l) {
     return '#/$isolateId/$l';
   }
+
+  /// Create a request for [l] on [isolateId].
+  @observable
+  String absoluteLink(String l) {
+    return '#/$l';
+  }
 }
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_list.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_list.html
index a47ab42..fe5a1eb 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_list.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_list.html
@@ -11,6 +11,8 @@
         </li>
       </template>
       </ul>
+      (<a href="{{ app.locationManager.absoluteLink('cpu') }}">cpu</a>)
+      
   </template>
   <script type="application/dart" src="isolate_list.dart"></script>
 </polymer-element>
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html
index f66a3fa..ba4740e 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/message_viewer.html
@@ -7,6 +7,7 @@
   <link rel="import" href="function_view.html">
   <link rel="import" href="instance_view.html">
   <link rel="import" href="isolate_list.html">
+  <link rel="import" href="json_view.html">
   <link rel="import" href="library_view.html">
   <link rel="import" href="observatory_element.html">
   <link rel="import" href="script_view.html">
@@ -70,6 +71,9 @@
     <template if="{{ messageType == 'Script' }}">
       <script-view app="{{ app }}" script="{{ message }}"></script-view>
     </template>
+    <template if="{{ messageType == 'CPU' }}">
+      <json-view json="{{ message }}"></json-view>
+    </template>
     <!-- Add new views and message types in the future here. -->
   </template>
   <script type="application/dart" src="message_viewer.dart"></script>
diff --git a/runtime/bin/vmservice/resources.dart b/runtime/bin/vmservice/resources.dart
index a52d2ba..b774697 100644
--- a/runtime/bin/vmservice/resources.dart
+++ b/runtime/bin/vmservice/resources.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.
 
-part of vmservice;
+part of vmservice_io;
 
 String detectMimeType(String name) {
   var extensionStart = name.lastIndexOf('.');
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 8c77003..5101858 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -8,20 +8,20 @@
 import 'dart:convert';
 import 'dart:io';
 import 'dart:isolate';
-import 'vmservice.dart';
+import 'dart:vmservice';
 
+part 'resources.dart';
 part 'server.dart';
 
 // The TCP port that the HTTP server listens on.
 int _port;
 
-// The receive port that isolate startup / shutdown messages are delivered on.
-RawReceivePort _receivePort;
+// The VM service instance.
+VMService service;
 
 main() {
-  // Create VmService.
-  var service = new VMService();
-  _receivePort = service.receivePort;
+  // Get VMService.
+  service = new VMService();
   // Start HTTP server.
   var server = new Server(service, _port);
   server.startServer();
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 9e738cd..b35c67e 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -9,25 +9,11 @@
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
 #include "bin/isolate_data.h"
-#include "bin/resources.h"
 #include "bin/thread.h"
 
-#include "vm/dart_api_impl.h"
-#include "vm/dart_entry.h"
-#include "vm/isolate.h"
-#include "vm/message.h"
-#include "vm/native_entry.h"
-#include "vm/native_arguments.h"
-#include "vm/object.h"
-#include "vm/port.h"
-#include "vm/snapshot.h"
-
 namespace dart {
 namespace bin {
 
-// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
-// it is initialized to NULL.
-extern const uint8_t* snapshot_buffer;
 #define RETURN_ERROR_HANDLE(handle)                             \
   if (Dart_IsError(handle)) {                                   \
     return handle;                                              \
@@ -41,143 +27,110 @@
     return false;                                               \
   }
 
-#define kLibraryResourceNamePrefix "/vmservice"
-static const char* kVMServiceIOLibraryScriptResourceName =
-    kLibraryResourceNamePrefix "/vmservice_io.dart";
-static const char* kVMServiceLibraryName =
-    kLibraryResourceNamePrefix "/vmservice.dart";
-
+#define kLibrarySourceNamePrefix "/vmservice"
+static const char* kVMServiceIOLibraryScriptResourceName = "vmservice_io.dart";
 #define kClientResourceNamePrefix "/vmservice/client/deployed/web"
 
-Dart_Isolate VmService::isolate_ = NULL;
-Dart_Port VmService::port_ = ILLEGAL_PORT;
-dart::Monitor* VmService::monitor_ = NULL;
+struct ResourcesEntry {
+  const char* path_;
+  const char* resource_;
+  int length_;
+};
+
+extern ResourcesEntry __service_bin_resources_[];
+
+class Resources {
+ public:
+  static const int kNoSuchInstance = -1;
+  static int ResourceLookup(const char* path, const char** resource) {
+    ResourcesEntry* table = ResourcesTable();
+    for (int i = 0; table[i].path_ != NULL; i++) {
+      const ResourcesEntry& entry = table[i];
+      if (strcmp(path, entry.path_) == 0) {
+        *resource = entry.resource_;
+        ASSERT(entry.length_ > 0);
+        return entry.length_;
+      }
+    }
+    return kNoSuchInstance;
+  }
+
+  static const char* Path(int idx) {
+    ASSERT(idx >= 0);
+    ResourcesEntry* entry = At(idx);
+    if (entry == NULL) {
+      return NULL;
+    }
+    ASSERT(entry->path_ != NULL);
+    return entry->path_;
+  }
+
+ private:
+  static ResourcesEntry* At(int idx) {
+    ASSERT(idx >= 0);
+    ResourcesEntry* table = ResourcesTable();
+    for (int i = 0; table[i].path_ != NULL; i++) {
+      if (idx == i) {
+        return &table[i];
+      }
+    }
+    return NULL;
+  }
+  static ResourcesEntry* ResourcesTable() {
+    return &__service_bin_resources_[0];
+  }
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
+};
+
 const char* VmService::error_msg_ = NULL;
 
-// These must be kept in sync with vmservice/constants.dart
-#define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
-#define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
-
-
-static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
-                                                   int num_arguments,
-                                                   bool* auto_setup_scope);
-
-
 bool VmService::Start(intptr_t server_port) {
-  monitor_ = new dart::Monitor();
-  ASSERT(monitor_ != NULL);
-  error_msg_ = NULL;
-
-
-  {
-    // Take lock before spawning new thread.
-    MonitorLocker ml(monitor_);
-    // Spawn new thread.
-    dart::Thread::Start(ThreadMain, server_port);
-    // Wait until service is running on spawned thread.
-    ml.Wait();
+  bool r = _Start(server_port);
+  if (!r) {
+    return r;
   }
-  return port_ != ILLEGAL_PORT;
+  // Start processing messages in a new thread.
+  dart::Thread::Start(ThreadMain, NULL);
+  return true;
 }
 
 
 bool VmService::_Start(intptr_t server_port) {
-  ASSERT(isolate_ == NULL);
-  char* error = NULL;
-  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;
+  ASSERT(Dart_CurrentIsolate() == NULL);
+  Dart_Isolate isolate = Dart_GetServiceIsolate(NULL);
+  if (isolate == NULL) {
+    error_msg_ = "Internal error.";
     return false;
   }
-
+  Dart_EnterIsolate(isolate);
   Dart_EnterScope();
-
-  if (snapshot_buffer != NULL) {
-    // Setup the native resolver as the snapshot does not carry it.
-    Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
-    Builtin::SetNativeResolver(Builtin::kIOLibrary);
-  }
-
-  // Set up the library tag handler for this isolate.
-  Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
-  SHUTDOWN_ON_ERROR(result);
-
-  // Load the specified application script into the newly created isolate.
-
-  // Prepare builtin and its dependent libraries for use to resolve URIs.
-  // The builtin library is part of the core snapshot and would already be
-  // available here in the case of script snapshot loading.
-  Dart_Handle builtin_lib =
-      Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
-  SHUTDOWN_ON_ERROR(builtin_lib);
-
-  // Prepare for script loading by setting up the 'print' and 'timer'
-  // closures and setting up 'package root' for URI resolution.
-  result = DartUtils::PrepareForScriptLoading("", builtin_lib);
-  SHUTDOWN_ON_ERROR(result);
-
-  {
-    // Load source into service isolate.
-    Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
-    SHUTDOWN_ON_ERROR(library);
-  }
-
-  // Make the isolate runnable so that it is ready to handle messages.
+  // Install our own library tag handler.
+  Dart_SetLibraryTagHandler(LibraryTagHandler);
+  Dart_Handle result;
+  Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
+  // Expect a library.
+  ASSERT(library != Dart_Null());
+  SHUTDOWN_ON_ERROR(library);
   Dart_ExitScope();
   Dart_ExitIsolate();
-
-  bool retval = Dart_IsolateMakeRunnable(isolate_);
+  bool retval = Dart_IsolateMakeRunnable(isolate);
   if (!retval) {
-    Dart_EnterIsolate(isolate_);
+    Dart_EnterIsolate(isolate);
     Dart_ShutdownIsolate();
     error_msg_ = "Invalid isolate state - Unable to make it runnable.";
     return false;
   }
 
-  Dart_EnterIsolate(isolate_);
+  Dart_EnterIsolate(isolate);
   Dart_EnterScope();
-
-
-  Dart_Handle library = Dart_RootLibrary();
+  library = Dart_RootLibrary();
   // Set requested TCP port.
   DartUtils::SetIntegerField(library, "_port", server_port);
   result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
   SHUTDOWN_ON_ERROR(result);
-
-  // Retrieve the ReceivePort that the service is waiting on. The _receivePort
-  // variable is setup in the call to main.
-  Dart_Handle receivePort = Dart_GetField(library,
-                                          DartUtils::NewString("_receivePort"));
-  SHUTDOWN_ON_ERROR(receivePort);
-
-  {
-    // Extract the Dart_Port from the receive port.
-    HANDLESCOPE(Isolate::Current());
-    const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
-    const Instance& rp = Instance::Cast(unwrapped_rp);
-    // Extract ReceivePort port id.
-    const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp));
-    if (rp_id_obj.IsError()) {
-      const Error& error = Error::Cast(rp_id_obj);
-      error_msg_ = strdup(error.ToErrorCString());
-      Dart_ExitScope();
-      Dart_ShutdownIsolate();
-      return false;
-    }
-    ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint());
-    Integer& id = Integer::Handle();
-    id ^= rp_id_obj.raw();
-    port_ = static_cast<Dart_Port>(id.AsInt64Value());
-  }
-
-  Dart_Handle library_name = Dart_NewStringFromCString(kVMServiceLibraryName);
-  library = Dart_LookupLibrary(library_name);
-  SHUTDOWN_ON_ERROR(library);
+  // Load resources.
   result = LoadResources(library);
   SHUTDOWN_ON_ERROR(result);
 
@@ -188,36 +141,24 @@
 }
 
 
-void VmService::_Stop() {
-  port_ = ILLEGAL_PORT;
-}
-
-
 const char* VmService::GetErrorMessage() {
   return error_msg_ == NULL ? "No error." : error_msg_;
 }
 
 
-Dart_Port VmService::port() {
-  return port_;
-}
-
-
-bool VmService::IsRunning() {
-  return port_ != ILLEGAL_PORT;
-}
-
-
 Dart_Handle VmService::GetSource(const char* name) {
+  const intptr_t kBufferSize = 512;
+  char buffer[kBufferSize];
+  snprintf(&buffer[0], kBufferSize-1, "%s/%s", kLibrarySourceNamePrefix, name);
   const char* vmservice_source = NULL;
-  int r = Resources::ResourceLookup(name, &vmservice_source);
+  int r = Resources::ResourceLookup(buffer, &vmservice_source);
   ASSERT(r != Resources::kNoSuchInstance);
   return Dart_NewStringFromCString(vmservice_source);
 }
 
 
 Dart_Handle VmService::LoadScript(const char* name) {
-  Dart_Handle url = Dart_NewStringFromCString(name);
+  Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_io");
   Dart_Handle source = GetSource(name);
   return Dart_LoadScript(url, source, 0, 0);
 }
@@ -230,18 +171,6 @@
 }
 
 
-Dart_Handle VmService::LoadSources(Dart_Handle library, const char* names[]) {
-  Dart_Handle result = Dart_Null();
-  for (int i = 0; names[i] != NULL; i++) {
-    result = LoadSource(library, names[i]);
-    if (Dart_IsError(result)) {
-      break;
-    }
-  }
-  return result;
-}
-
-
 Dart_Handle VmService::LoadResource(Dart_Handle library,
                                     const char* resource_name,
                                     const char* prefix) {
@@ -285,8 +214,8 @@
 Dart_Handle VmService::LoadResources(Dart_Handle library) {
   Dart_Handle result = Dart_Null();
   intptr_t prefixLen = strlen(kClientResourceNamePrefix);
-  for (intptr_t i = 0; i < Resources::get_resource_count(); i++) {
-    const char* path = Resources::get_resource_path(i);
+  for (intptr_t i = 0; Resources::Path(i) != NULL; i++) {
+    const char* path = Resources::Path(i);
     if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) {
       result = LoadResource(library, path, kClientResourceNamePrefix);
       if (Dart_IsError(result)) {
@@ -298,19 +227,6 @@
 }
 
 
-static bool IsVMServiceURL(const char* url) {
-  static const intptr_t kLibraryResourceNamePrefixLen =
-      strlen(kLibraryResourceNamePrefix);
-  return 0 == strncmp(kLibraryResourceNamePrefix, url,
-                      kLibraryResourceNamePrefixLen);
-}
-
-
-static bool IsVMServiceLibrary(const char* url) {
-  return 0 == strcmp(kVMServiceLibraryName, url);
-}
-
-
 Dart_Handle VmService::LibraryTagHandler(Dart_LibraryTag tag,
                                          Dart_Handle library,
                                          Dart_Handle url) {
@@ -331,224 +247,37 @@
   if (Dart_IsError(result)) {
     return result;
   }
-  bool is_vm_service_url = IsVMServiceURL(url_string);
-  if (!is_vm_service_url) {
-    // Pass to DartUtils.
+  if (tag == Dart_kImportTag) {
+    // Embedder handles all requests for external libraries.
     return DartUtils::LibraryTagHandler(tag, library, url);
   }
-  switch (tag) {
-    case Dart_kCanonicalizeUrl:
-      // The URL is already canonicalized.
-      return url;
-    break;
-    case Dart_kImportTag: {
-      Dart_Handle source = GetSource(url_string);
-      if (Dart_IsError(source)) {
-        return source;
-      }
-      Dart_Handle lib = Dart_LoadLibrary(url, source);
-      if (Dart_IsError(lib)) {
-        return lib;
-      }
-      if (IsVMServiceLibrary(url_string)) {
-        // Install native resolver for this library.
-        result = Dart_SetNativeResolver(lib, VmServiceNativeResolver);
-        if (Dart_IsError(result)) {
-          return result;
-        }
-      }
-      return lib;
-    }
-    break;
-    case Dart_kSourceTag: {
-      Dart_Handle source = GetSource(url_string);
-      if (Dart_IsError(source)) {
-        return source;
-      }
-      return Dart_LoadSource(library, url, source);
-    }
-    break;
-    default:
-      UNIMPLEMENTED();
-    break;
+  ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
+  if (tag == Dart_kCanonicalizeUrl) {
+    // url is already canonicalized.
+    return url;
   }
-  UNREACHABLE();
-  return result;
+  Dart_Handle source = GetSource(url_string);
+  if (Dart_IsError(source)) {
+    return source;
+  }
+  return Dart_LoadSource(library, url, source);
 }
 
 
 void VmService::ThreadMain(uword parameters) {
   ASSERT(Dart_CurrentIsolate() == NULL);
-  ASSERT(isolate_ == NULL);
-
-  intptr_t server_port = static_cast<intptr_t>(parameters);
-  ASSERT(server_port >= 0);
-
-  // Lock scope.
-  {
-    MonitorLocker ml(monitor_);
-    bool r = _Start(server_port);
-    if (!r) {
-      port_ = ILLEGAL_PORT;
-      monitor_->Notify();
-      return;
-    }
-
-    Dart_EnterIsolate(isolate_);
-    Dart_EnterScope();
-
-    Dart_Handle receievePort = Dart_GetReceivePort(port_);
-    ASSERT(!Dart_IsError(receievePort));
-    monitor_->Notify();
-  }
-
-  // Keep handling messages until the last active receive port is closed.
+  Dart_Isolate service_isolate = Dart_GetServiceIsolate(NULL);
+  Dart_EnterIsolate(service_isolate);
+  Dart_EnterScope();
   Dart_Handle result = Dart_RunLoop();
   if (Dart_IsError(result)) {
-    printf("VmService has exited with an error:\n%s\n", Dart_GetError(result));
+    printf("Service exited with an error:\n%s\n", Dart_GetError(result));
   }
-
-  _Stop();
-
   Dart_ExitScope();
   Dart_ExitIsolate();
 }
 
 
-static Dart_Handle MakeServiceControlMessage(Dart_Port port_id, intptr_t code,
-                                             Dart_Handle name) {
-  Dart_Handle result;
-  Dart_Handle list = Dart_NewList(4);
-  ASSERT(!Dart_IsError(list));
-  Dart_Handle code_handle = Dart_NewInteger(code);
-  ASSERT(!Dart_IsError(code_handle));
-  result = Dart_ListSetAt(list, 0, code_handle);
-  ASSERT(!Dart_IsError(result));
-  Dart_Handle port_id_handle = Dart_NewInteger(port_id);
-  ASSERT(!Dart_IsError(port_id_handle));
-  result = Dart_ListSetAt(list, 1, port_id_handle);
-  ASSERT(!Dart_IsError(result));
-  Dart_Handle sendPort = Dart_NewSendPort(port_id);
-  ASSERT(!Dart_IsError(sendPort));
-  result = Dart_ListSetAt(list, 2, sendPort);
-  ASSERT(!Dart_IsError(result));
-  result = Dart_ListSetAt(list, 3, name);
-  ASSERT(!Dart_IsError(result));
-  return list;
-}
-
-
-bool VmService::SendIsolateStartupMessage() {
-  if (!IsRunning()) {
-    return false;
-  }
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate != NULL);
-  HANDLESCOPE(isolate);
-  Dart_Handle name = Api::NewHandle(isolate, String::New(isolate->name()));
-  ASSERT(!Dart_IsError(name));
-  Dart_Handle list =
-      MakeServiceControlMessage(Dart_GetMainPortId(),
-                                VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
-                                name);
-  ASSERT(!Dart_IsError(list));
-  return Dart_Post(port_, list);
-}
-
-
-bool VmService::SendIsolateShutdownMessage() {
-  if (!IsRunning()) {
-    return false;
-  }
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate != NULL);
-  HANDLESCOPE(isolate);
-  Dart_Handle list =
-      MakeServiceControlMessage(Dart_GetMainPortId(),
-                                VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID,
-                                Dart_Null());
-  ASSERT(!Dart_IsError(list));
-  return Dart_Post(port_, list);
-}
-
-
-void VmService::VmServiceShutdownCallback(void* callback_data) {
-  ASSERT(Dart_CurrentIsolate() != NULL);
-  Dart_EnterScope();
-  VmService::SendIsolateShutdownMessage();
-  Dart_ExitScope();
-}
-
-
-static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
-  void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
-  return reinterpret_cast<uint8_t*>(new_ptr);
-}
-
-
-static void SendServiceMessage(Dart_NativeArguments args) {
-  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  Isolate* isolate = arguments->isolate();
-  StackZone zone(isolate);
-  HANDLESCOPE(isolate);
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(1));
-
-  // Extract SendPort port id.
-  const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp));
-  if (sp_id_obj.IsError()) {
-    Exceptions::PropagateError(Error::Cast(sp_id_obj));
-  }
-  Integer& id = Integer::Handle();
-  id ^= sp_id_obj.raw();
-  Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value());
-  ASSERT(sp_id != ILLEGAL_PORT);
-
-  // Serialize message.
-  uint8_t* data = NULL;
-  MessageWriter writer(&data, &allocator);
-  writer.WriteMessage(message);
-
-  // TODO(turnidge): Throw an exception when the return value is false?
-  PortMap::PostMessage(new Message(sp_id, data, writer.BytesWritten(),
-                                   Message::kOOBPriority));
-}
-
-
-struct VmServiceNativeEntry {
-  const char* name;
-  int num_arguments;
-  Dart_NativeFunction function;
-};
-
-
-static VmServiceNativeEntry _VmServiceNativeEntries[] = {
-  {"VMService_SendServiceMessage", 2, SendServiceMessage}
-};
-
-
-static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
-                                                   int num_arguments,
-                                                   bool* auto_setup_scope) {
-  const Object& obj = Object::Handle(Api::UnwrapHandle(name));
-  if (!obj.IsString()) {
-    return NULL;
-  }
-  const char* function_name = obj.ToCString();
-  ASSERT(function_name != NULL);
-  ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = true;
-  intptr_t n =
-      sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]);
-  for (intptr_t i = 0; i < n; i++) {
-    VmServiceNativeEntry entry = _VmServiceNativeEntries[i];
-    if (!strcmp(function_name, entry.name) &&
-        (num_arguments == entry.num_arguments)) {
-      return entry.function;
-    }
-  }
-  return NULL;
-}
 
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index 0a19ebe..8ca7233 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -19,36 +19,18 @@
   // Error message if startup failed.
   static const char* GetErrorMessage();
 
-  static Dart_Port port();
-
-  static bool IsRunning();
-
-  static bool SendIsolateStartupMessage();
-  static bool SendIsolateShutdownMessage();
-
-  static void VmServiceShutdownCallback(void* callback_data);
-
  private:
   static bool _Start(intptr_t server_port);
-  static void _Stop();
   static Dart_Handle GetSource(const char* name);
   static Dart_Handle LoadScript(const char* name);
-  static Dart_Handle LoadSources(Dart_Handle library, const char** names);
   static Dart_Handle LoadSource(Dart_Handle library, const char* name);
   static Dart_Handle LoadResources(Dart_Handle library);
   static Dart_Handle LoadResource(Dart_Handle library, const char* name,
                                   const char* prefix);
-
   static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
                                        Dart_Handle url);
-
   static void ThreadMain(uword parameters);
-
-  static Dart_Isolate isolate_;
-  static Dart_Port port_;
   static const char* error_msg_;
-  static dart::Monitor* monitor_;
-
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(VmService);
 };
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 3c84c9b..75c7d47 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -302,7 +302,7 @@
  *
  * If the provided handle is an unhandled exception error, this
  * function will cause the unhandled exception to be rethrown.  This
- * will proceeed in the standard way, walking up Dart frames until an
+ * will proceed in the standard way, walking up Dart frames until an
  * appropriate 'catch' block is found, executing 'finally' blocks,
  * etc.
  *
@@ -315,7 +315,7 @@
  * In either case, when an error is propagated any current scopes
  * created by Dart_EnterScope will be exited.
  *
- * See the additonal discussion under "Propagating Errors" at the
+ * See the additional discussion under "Propagating Errors" at the
  * beginning of this file.
  *
  * \param An error handle (See Dart_IsError)
@@ -661,6 +661,34 @@
                                                    void* callback_data,
                                                    char** error);
 
+
+/**
+ * The service isolate creation and initialization callback function.
+ *
+ * This callback, provided by the embedder, is called when the vm
+ * needs to create the service isolate. The callback should create an isolate
+ * by calling Dart_CreateIsolate and prepare the isolate to be used as
+ * the service isolate.
+ *
+ * When the function returns NULL, it is the responsibility of this
+ * function to ensure that Dart_ShutdownIsolate has been called if
+ * required.
+ *
+ * When the function returns NULL, the function should set *error to
+ * a malloc-allocated buffer containing a useful error message.  The
+ * caller of this function (the vm) will make sure that the buffer is
+ * freed.
+ *
+ *
+ * \param error A structure into which the embedder can place a
+ *   C string containing an error message in the case of failures.
+ *
+ * \return The embedder returns NULL if the creation and
+ *   initialization was not successful and the isolate if successful.
+ */
+typedef Dart_Isolate (*Dart_ServiceIsolateCreateCalback)(void* callback_data,
+                                                         char** error);
+
 /**
  * An isolate interrupt callback function.
  *
@@ -769,7 +797,8 @@
     Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source);
+    Dart_EntropySource entropy_source,
+    Dart_ServiceIsolateCreateCalback service_create);
 
 /**
  * Cleanup state in the VM before process termination.
@@ -1065,6 +1094,17 @@
 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id);
 
 
+/**
+ * Posts an object to the send port.
+ *
+ * \param send_port A Dart SendPort.
+ * \param object An object from the current isolate.
+ *
+ * \return Success if no error occurs. Otherwise returns an error handle.
+ */
+DART_EXPORT Dart_Handle Dart_PostMessage(Dart_Handle send_port,
+                                         Dart_Handle object);
+
 /*
  * ======
  * Scopes
@@ -1948,7 +1988,7 @@
  * Throws an exception.
  *
  * This function causes a Dart language exception to be thrown. This
- * will proceeed in the standard way, walking up Dart frames until an
+ * will proceed in the standard way, walking up Dart frames until an
  * appropriate 'catch' block is found, executing 'finally' blocks,
  * etc.
  *
@@ -2393,4 +2433,28 @@
  */
 DART_EXPORT Dart_Handle Dart_SetPeer(Dart_Handle object, void* peer);
 
+
+/*
+ * =======
+ * Service
+ * =======
+ */
+
+/**
+ * Returns the Service isolate initialized and with the dart:vmservice library
+ * loaded and booted.
+ *
+ * This will call the embedder provided Dart_ServiceIsolateCreateCalback to
+ * create the isolate.
+ *
+ * After obtaining the service isolate the embedder specific glue code can
+ * be loaded in and the isolate can be run by the embedder.
+ *
+ * NOTE: It is not safe to call this from multiple threads concurrently.
+ *
+ * \return Returns NULL if an error occurred.
+ */
+DART_EXPORT Dart_Isolate Dart_GetServiceIsolate(void* callback_data);
+
+
 #endif  /* INCLUDE_DART_API_H_ */  /* NOLINT */
diff --git a/runtime/include/dart_native_api.h b/runtime/include/dart_native_api.h
index 0a8038e..6bfd0ce 100644
--- a/runtime/include/dart_native_api.h
+++ b/runtime/include/dart_native_api.h
@@ -152,26 +152,6 @@
 
 
 /*
- * =============
- * Heap Profiler
- * =============
- */
-
-/**
- * Generates a heap profile.
- *
- * \param callback A function pointer that will be repeatedly invoked
- *   with heap profile data.
- * \param stream A pointer that will be passed to the callback.  This
- *   is a convenient way to provide an open stream to the callback.
- *
- * \return Success if the heap profile is successful.
- */
-DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_FileWriteCallback callback,
-                                         void* stream);
-
-
-/*
  * ==================
  * Verification Tools
  * ==================
diff --git a/runtime/lib/array.cc b/runtime/lib/array.cc
index c81aef2..532eee2 100644
--- a/runtime/lib/array.cc
+++ b/runtime/lib/array.cc
@@ -110,4 +110,23 @@
   return Object::null();
 }
 
+
+// Private factory, expects correct arguments.
+DEFINE_NATIVE_ENTRY(ImmutableList_from, 4) {
+  // Ignore first argument of a thsi factory (type argument).
+  const Array& from_array = Array::CheckedHandle(arguments->NativeArgAt(1));
+  const Smi& smi_offset = Smi::CheckedHandle(arguments->NativeArgAt(2));
+  const Smi& smi_length = Smi::CheckedHandle(arguments->NativeArgAt(3));
+  const intptr_t length = smi_length.Value();
+  const intptr_t offset = smi_offset.Value();
+  const Array& result = Array::Handle(Array::New(length));
+  Object& temp = Object::Handle();
+  for (intptr_t i = 0; i < length; i++) {
+    temp = from_array.At(i + offset);
+    result.SetAt(i, temp);
+  }
+  result.MakeImmutable();
+  return result.raw();
+}
+
 }  // namespace dart
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 2369b4c..7b9e0d9 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -291,6 +291,9 @@
         "ImmutableArray can only be allocated by the VM");
   }
 
+  factory _ImmutableList._from(List from, int offset, int length)
+      native "ImmutableList_from";
+
   E operator [](int index) native "List_getIndexed";
 
   void operator []=(int index, E value) {
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 6bb2572..31de11d 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -216,7 +216,7 @@
     var args_message = args_mismatch ? " with matching arguments" : "";
     var msg;
     var memberName =
-        (_memberName == null) ? "" :_collection_dev.Symbol.getName(_memberName);
+        (_memberName == null) ? "" : internal.Symbol.getName(_memberName);
     switch (level) {
       case _InvocationMirror._DYNAMIC: {
         if (_receiver == null) {
@@ -276,7 +276,7 @@
         if (i > 0) {
           actual_buf.write(", ");
         }
-        actual_buf.write(_collection_dev.Symbol.getName(key));
+        actual_buf.write(internal.Symbol.getName(key));
         actual_buf.write(": ");
         actual_buf.write(Error.safeToString(value));
         i++;
@@ -293,7 +293,7 @@
       receiver_str = Error.safeToString(_receiver);
     }
     var memberName =
-        (_memberName == null) ? "" :_collection_dev.Symbol.getName(_memberName);
+        (_memberName == null) ? "" : internal.Symbol.getName(_memberName);
     if (!args_mismatch) {
       msg_buf.write(
           "NoSuchMethodError : method not found: '$memberName'\n"
diff --git a/runtime/lib/function_patch.dart b/runtime/lib/function_patch.dart
index 969836d..c94c78b 100644
--- a/runtime/lib/function_patch.dart
+++ b/runtime/lib/function_patch.dart
@@ -22,7 +22,7 @@
     if (numNamedArguments > 0) {
       namedArguments.forEach((name, value) {
         arguments[argumentIndex++] = value;
-        names[nameIndex++] = _collection_dev.Symbol.getName(name);
+        names[nameIndex++] = internal.Symbol.getName(name);
       });
     }
     return _apply(arguments, names);
diff --git a/runtime/lib/collection_dev_patch.dart b/runtime/lib/internal_patch.dart
similarity index 100%
rename from runtime/lib/collection_dev_patch.dart
rename to runtime/lib/internal_patch.dart
diff --git a/runtime/lib/collection_dev_sources.gypi b/runtime/lib/internal_sources.gypi
similarity index 79%
rename from runtime/lib/collection_dev_sources.gypi
rename to runtime/lib/internal_sources.gypi
index 63c909f..66fdf9d 100644
--- a/runtime/lib/collection_dev_sources.gypi
+++ b/runtime/lib/internal_sources.gypi
@@ -2,11 +2,11 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# Sources that patch the library "dart:_collection-dev".
+# Sources that patch the library "dart:_internal".
 
 {
   'sources': [
-    'collection_dev_patch.dart',
+    'internal_patch.dart',
     # The above file needs to be first as it imports required libraries.
     'print_patch.dart',
     'symbol_patch.dart',
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index 3f76e4e..5b86660 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -40,15 +40,15 @@
     if (_functionName.startsWith("get:")) {
       _type = _GETTER;
       _memberName =
-          new _collection_dev.Symbol.unvalidated(_functionName.substring(4));
+          new internal.Symbol.unvalidated(_functionName.substring(4));
     } else if (_functionName.startsWith("set:")) {
       _type = _SETTER;
       _memberName =
-          new _collection_dev.Symbol.unvalidated(
+          new internal.Symbol.unvalidated(
               _functionName.substring(4) + "=");
     } else {
       _type = _isSuperInvocation ? (_SUPER << _CALL_SHIFT) | _METHOD : _METHOD;
-      _memberName = new _collection_dev.Symbol.unvalidated(_functionName);
+      _memberName = new internal.Symbol.unvalidated(_functionName);
     }
   }
 
@@ -67,7 +67,8 @@
         return _positionalArguments = const [];
       }
       // Exclude receiver.
-      _positionalArguments = _arguments.sublist(1, numPositionalArguments);
+      _positionalArguments =
+          new _ImmutableList._from(_arguments, 1, numPositionalArguments - 1);
     }
     return _positionalArguments;
   }
@@ -84,7 +85,7 @@
       for (int i = 0; i < numNamedArguments; i++) {
         String arg_name = _argumentsDescriptor[2 + 2*i];
         var arg_value = _arguments[_argumentsDescriptor[3 + 2*i]];
-        _namedArguments[new _collection_dev.Symbol.unvalidated(arg_name)] =
+        _namedArguments[new internal.Symbol.unvalidated(arg_name)] =
             arg_value;
       }
     }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 4e78b26..ddd28c5 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -43,7 +43,7 @@
 
 
 // TODO(turnidge): Move to DartLibraryCalls.
-static RawObject* ReceivePortCreate(intptr_t port_id) {
+static RawObject* ReceivePortCreate(Dart_Port port_id) {
   Isolate* isolate = Isolate::Current();
   Function& func =
       Function::Handle(isolate,
@@ -78,7 +78,7 @@
 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) {
   ASSERT(AbstractTypeArguments::CheckedHandle(
       arguments->NativeArgAt(0)).IsNull());
-  intptr_t port_id =
+  Dart_Port port_id =
       PortMap::CreatePort(arguments->isolate()->message_handler());
   const Object& port = Object::Handle(ReceivePortCreate(port_id));
   if (port.IsError()) {
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index ca7c7e6..801c8c6 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -123,8 +123,23 @@
   const TypedData& array = TypedData::Handle(GetRandomStateArray(receiver));
   ASSERT(!seed_int.IsNull());
   ASSERT(!array.IsNull());
-  // TODO(srdjan): Reduce Bigint to 64 bit value.
-  int64_t seed = seed_int.IsBigint() ? 0 : seed_int.AsInt64Value();
+  int64_t seed = 0;
+  if (seed_int.IsBigint()) {
+    const Bigint& mask64 = Bigint::Handle(
+        BigintOperations::NewFromUint64(0xffffffffffffffffLL));
+    Bigint& big_seed = Bigint::Handle();
+    big_seed ^= seed_int.raw();
+    Bigint& low64 = Bigint::Handle();
+    while (!big_seed.IsZero()) {
+      low64 = BigintOperations::BitAnd(big_seed, mask64);
+      ASSERT(BigintOperations::FitsIntoUint64(low64));
+      seed ^= BigintOperations::ToUint64(low64);
+      big_seed = BigintOperations::ShiftRight(big_seed, 64);
+    }
+  } else {
+    seed = seed_int.AsInt64Value();
+  }
+
   do {
     seed = seed + 0x5A17;
   } while (seed == 0);
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 3d228cd..3b7391c 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -317,10 +317,15 @@
                                       const AbstractType& type,
                                       const Bool& is_declaration,
                                       const Instance& owner_mirror) {
+  if (type.IsTypeRef()) {
+    AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
+    ASSERT(!ref_type.IsTypeRef());
+    ASSERT(ref_type.IsCanonical());
+    return CreateClassMirror(cls, ref_type, is_declaration, owner_mirror);
+  }
   ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass());
   ASSERT(!type.IsNull());
   ASSERT(type.IsFinalized());
-  ASSERT(!type.IsTypeRef());
 
   if (cls.IsSignatureClass()) {
     if (cls.IsCanonicalSignatureClass()) {
@@ -332,10 +337,16 @@
     }
   }
 
+  const Error& error = Error::Handle(cls.EnsureIsFinalized(Isolate::Current()));
+  if (!error.IsNull()) {
+    ThrowInvokeError(error);
+    UNREACHABLE();
+  }
+
   const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0);
   const Bool& is_mixin_app_alias = Bool::Get(cls.is_mixin_app_alias());
 
-  const Array& args = Array::Handle(Array::New(7));
+  const Array& args = Array::Handle(Array::New(8));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
   args.SetAt(1, type);
   // We do not set the names of anonymous mixin applications because the mirrors
@@ -345,9 +356,10 @@
     args.SetAt(2, String::Handle(cls.Name()));
   }
   args.SetAt(3, owner_mirror);
-  args.SetAt(4, is_generic);
-  args.SetAt(5, is_mixin_app_alias);
-  args.SetAt(6, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
+  args.SetAt(4, Bool::Get(cls.is_abstract()));
+  args.SetAt(5, is_generic);
+  args.SetAt(6, is_mixin_app_alias);
+  args.SetAt(7, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
   return CreateMirror(Symbols::_LocalClassMirror(), args);
 }
 
@@ -365,9 +377,14 @@
 
 
 static RawInstance* CreateTypeMirror(const AbstractType& type) {
+  if (type.IsTypeRef()) {
+    AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
+    ASSERT(!ref_type.IsTypeRef());
+    ASSERT(ref_type.IsCanonical());
+    return CreateTypeMirror(ref_type);
+  }
   ASSERT(type.IsFinalized());
   ASSERT(!type.IsMalformed());
-  ASSERT(!type.IsTypeRef());
   if (type.HasResolvedTypeClass()) {
     const Class& cls = Class::Handle(type.type_class());
     // Handle void and dynamic types.
@@ -1260,7 +1277,6 @@
   const intptr_t num_inherited_args = args.Length() - num_params;
   for (intptr_t i = 0; i < num_params; i++) {
     arg_type ^= args.TypeAt(i + num_inherited_args);
-    arg_type = arg_type.Canonicalize();  // Necessary for recursive types.
     type_mirror = CreateTypeMirror(arg_type);
     result.SetAt(i, type_mirror);
   }
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 5f0983a..cd8182f 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -199,8 +199,8 @@
   }
 
   List<InstanceMirror> get metadata => emptyList;
-
   String get source => null;
+  SourceLocation get location => throw new UnimplementedError();
 }
 
 class _SyntheticSetterParameter implements ParameterMirror {
@@ -222,6 +222,8 @@
   bool get isPrivate => false;
   bool get hasDefaultValue => false;
   InstanceMirror get defaultValue => null;
+  List<InstanceMirror> get metadata => emptyList;
+  SourceLocation get location => throw new UnimplementedError();
 }
 
 abstract class _LocalObjectMirror extends _LocalMirror implements ObjectMirror {
@@ -437,6 +439,7 @@
   final Type _reflectedType;
   Symbol _simpleName;
   DeclarationMirror _owner;
+  final bool isAbstract;
   final bool _isGeneric;
   final bool _isMixinAlias;
   final bool _isGenericDeclaration;
@@ -446,6 +449,7 @@
                     reflectedType,
                     String simpleName,
                     this._owner,
+                    this.isAbstract,
                     this._isGeneric,
                     this._isMixinAlias,
                     this._isGenericDeclaration)
@@ -564,8 +568,7 @@
     if (_cachedStaticMembers == null) {
       var result = new Map<Symbol, MethodMirror>();
       declarations.values.forEach((decl) {
-        if (decl is MethodMirror && decl.isStatic &&
-            !decl.isConstructor && !decl.isAbstract) {
+        if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
           result[decl.simpleName] = decl;
         }
         if (decl is VariableMirror && decl.isStatic) {
@@ -579,7 +582,8 @@
           }
         }
       });
-      _cachedStaticMembers = result;
+      _cachedStaticMembers =
+          new _UnmodifiableMapView<Symbol, MethodMirror>(result);
     }
     return _cachedStaticMembers;
   }
@@ -607,7 +611,8 @@
           }
         }
       });
-      _cachedInstanceMembers = result;
+      _cachedInstanceMembers =
+          new _UnmodifiableMapView<Symbol, MethodMirror>(result);
     }
     return _cachedInstanceMembers;
   }
@@ -804,7 +809,7 @@
 class _LocalFunctionTypeMirror extends _LocalClassMirror
     implements FunctionTypeMirror {
   _LocalFunctionTypeMirror(reflectee, reflectedType)
-      : super(reflectee, reflectedType, null, null, false, false, false);
+      : super(reflectee, reflectedType, null, null, false, false, false, false);
 
   bool get _isAnonymousMixinApplication => false;
 
@@ -1078,28 +1083,27 @@
 
   var _cachedTopLevelMembers;
   Map<Symbol, MethodMirror> get topLevelMembers {
-    if (_cachedTopLevelMembers != null) return _cachedTopLevelMembers;
-    var result = new Map<Symbol, MethodMirror>();
-    declarations.values.forEach((decl) {
-      if (decl is MethodMirror && !decl.isAbstract) {
-        result[decl.simpleName] = decl;
-      }
-      if (decl is VariableMirror) {
-        var getterName = decl.simpleName;
-        result[getterName] =
-            new _SyntheticAccessor(this, getterName, true, true, true, decl);
-        if (!decl.isFinal) {
-          var setterName = _asSetter(decl.simpleName, this);
-          result[setterName] = new _SyntheticAccessor(
-              this, setterName, false, true, true, decl);
+    if (_cachedTopLevelMembers == null) {
+      var result = new Map<Symbol, MethodMirror>();
+      declarations.values.forEach((decl) {
+        if (decl is MethodMirror) {
+          result[decl.simpleName] = decl;
         }
-      }
-      // if (decl is TypeMirror) {
-      //  var getterName = decl.simpleName;
-      //  result[getterName] = new _SyntheticTypeGetter(this, getterName, decl);
-      // }
-    });
-    return _cachedTopLevelMembers = result;
+        if (decl is VariableMirror) {
+          var getterName = decl.simpleName;
+          result[getterName] =
+              new _SyntheticAccessor(this, getterName, true, true, true, decl);
+          if (!decl.isFinal) {
+            var setterName = _asSetter(decl.simpleName, this);
+            result[setterName] = new _SyntheticAccessor(
+                this, setterName, false, true, true, decl);
+          }
+        }
+      });
+      _cachedTopLevelMembers =
+          new _UnmodifiableMapView<Symbol, MethodMirror>(result);
+    }
+    return _cachedTopLevelMembers;
   }
 
 
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
index 6f3c436..12cbd56 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/runtime/lib/mirrors_patch.dart
@@ -2,8 +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.
 
-// TODO(ahe): Move _symbol_dev.Symbol to its own "private" library?
-import "dart:_collection-dev" as _symbol_dev;
+import "dart:_internal" as _symbol_dev;
 
 /**
  * Returns a [MirrorSystem] for the current isolate.
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index 96688cc..fa8e10e 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -4,7 +4,7 @@
 
 patch class Object {
 
-  // The VM has it's own implemention of equals.
+  // The VM has its own implementation of equals.
   bool operator ==(other) native "Object_equals";
 
   // Helpers used to implement hashCode. If a hashCode is used, we remember it
@@ -43,7 +43,7 @@
 
   /* patch */ noSuchMethod(Invocation invocation) {
     return _noSuchMethod(invocation.isMethod,
-                         _collection_dev.Symbol.getName(invocation.memberName),
+                         internal.Symbol.getName(invocation.memberName),
                          invocation._type,
                          invocation.positionalArguments,
                          _symbolMapToStringMap(invocation.namedArguments));
@@ -66,7 +66,7 @@
   static _symbolMapToStringMap(Map<Symbol, dynamic> map) {
     var result = new Map<String, dynamic>();
     map.forEach((Symbol key, value) {
-      result[_collection_dev.Symbol.getName(key)] = value;
+      result[internal.Symbol.getName(key)] = value;
     });
     return result;
   }
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index e08a75fb..406786e 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -187,7 +187,11 @@
 }                                                                              \
 
 
-#define TYPED_DATA_SETTER(setter, object, get_object_value, access_size)       \
+#define TYPED_DATA_SETTER(setter,                                              \
+                          object,                                              \
+                          get_object_value,                                    \
+                          access_size,                                         \
+                          access_type)                                         \
 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) {                                   \
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); \
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, arguments->NativeArgAt(1)); \
@@ -196,12 +200,14 @@
     const TypedData& array = TypedData::Cast(instance);                        \
     RangeCheck(offsetInBytes.Value(), access_size,                             \
                array.LengthInBytes(), access_size);                            \
-    array.setter(offsetInBytes.Value(), value.get_object_value());             \
+    array.setter(offsetInBytes.Value(),                                        \
+                 static_cast<access_type>(value.get_object_value()));          \
   } else if (instance.IsExternalTypedData()) {                                 \
     const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
     RangeCheck(offsetInBytes.Value(), access_size,                             \
                array.LengthInBytes(), access_size);                            \
-    array.setter(offsetInBytes.Value(), value.get_object_value());             \
+    array.setter(offsetInBytes.Value(),                                        \
+                 static_cast<access_type>(value.get_object_value()));          \
   } else {                                                                     \
     const String& error = String::Handle(String::NewFormatted(                 \
         "Expected a TypedData object but found %s", instance.ToCString()));    \
@@ -270,9 +276,10 @@
                            setter,                                             \
                            object,                                             \
                            get_object_value,                                   \
-                           access_size)                                        \
+                           access_size,                                        \
+                           access_type)                                        \
   TYPED_DATA_GETTER(getter, object, access_size)                               \
-  TYPED_DATA_SETTER(setter, object, get_object_value, access_size)             \
+  TYPED_DATA_SETTER(setter, object, get_object_value, access_size, access_type)\
 
 
 #define TYPED_DATA_UINT64_NATIVES(getter, setter, object)                      \
@@ -280,18 +287,19 @@
   TYPED_DATA_UINT64_SETTER(setter, object)                                     \
 
 
-TYPED_DATA_NATIVES(GetInt8, SetInt8, Smi, Value, 1)
-TYPED_DATA_NATIVES(GetUint8, SetUint8, Smi, Value, 1)
-TYPED_DATA_NATIVES(GetInt16, SetInt16, Smi, Value, 2)
-TYPED_DATA_NATIVES(GetUint16, SetUint16, Smi, Value, 2)
-TYPED_DATA_NATIVES(GetInt32, SetInt32, Integer, AsInt64Value, 4)
-TYPED_DATA_NATIVES(GetUint32, SetUint32, Integer, AsInt64Value, 4)
-TYPED_DATA_NATIVES(GetInt64, SetInt64, Integer, AsInt64Value, 8)
+TYPED_DATA_NATIVES(GetInt8, SetInt8, Smi, Value, 1, int8_t)
+TYPED_DATA_NATIVES(GetUint8, SetUint8, Smi, Value, 1, uint8_t)
+TYPED_DATA_NATIVES(GetInt16, SetInt16, Smi, Value, 2, int16_t)
+TYPED_DATA_NATIVES(GetUint16, SetUint16, Smi, Value, 2, uint16_t)
+TYPED_DATA_NATIVES(GetInt32, SetInt32, Integer, AsInt64Value, 4, int32_t)
+TYPED_DATA_NATIVES(GetUint32, SetUint32, Integer, AsInt64Value, 4, uint32_t)
+TYPED_DATA_NATIVES(GetInt64, SetInt64, Integer, AsInt64Value, 8, int64_t)
 TYPED_DATA_UINT64_NATIVES(GetUint64, SetUint64, Integer)
-TYPED_DATA_NATIVES(GetFloat32, SetFloat32, Double, value, 4)
-TYPED_DATA_NATIVES(GetFloat64, SetFloat64, Double, value, 8)
-TYPED_DATA_NATIVES(GetFloat32x4, SetFloat32x4, Float32x4, value, 16)
-TYPED_DATA_NATIVES(GetInt32x4, SetInt32x4, Int32x4, value, 16)
+TYPED_DATA_NATIVES(GetFloat32, SetFloat32, Double, value, 4, float)
+TYPED_DATA_NATIVES(GetFloat64, SetFloat64, Double, value, 8, double)
+TYPED_DATA_NATIVES(
+    GetFloat32x4, SetFloat32x4, Float32x4, value, 16, simd128_value_t)
+TYPED_DATA_NATIVES(GetInt32x4, SetInt32x4, Int32x4, value, 16, simd128_value_t)
 
 
 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt16, 2) {
@@ -321,8 +329,9 @@
 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt32, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
-  ASSERT(host_value.AsInt64Value() <= kMaxInt32);
-  int32_t value = host_value.AsInt64Value();
+  ASSERT((host_value.AsInt64Value() >= kMinInt32) ||
+         (host_value.AsInt64Value() <= kMaxInt32));
+  int32_t value = static_cast<int32_t>(host_value.AsInt64Value());
   if (little_endian.value()) {
     value = Utils::HostToLittleEndian32(value);
   } else {
@@ -336,7 +345,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
   ASSERT(host_value.AsInt64Value() <= kMaxUint32);
-  uint32_t value = host_value.AsInt64Value();
+  uint32_t value = static_cast<uint32_t>(host_value.AsInt64Value());
   if (little_endian.value()) {
     value = Utils::HostToLittleEndian32(value);
   } else {
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 376acb3..7ea3c78 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -4,6 +4,9 @@
 
 // patch classes for Int8List ..... Float64List and ByteData implementations.
 
+import "dart:_internal";
+import 'dart:math' show Random;
+
 patch class Int8List {
   /* patch */ factory Int8List(int length) {
     return new _Int8Array(length);
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 5fc7f00..9e27506 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -255,11 +255,6 @@
 typedef intptr_t word;
 typedef uintptr_t uword;
 
-#if defined(TARGET_OS_WINDOWS) || defined(TARGET_OS_MACOS)
-// off64_t is not defined on Windows or Mac OS.
-typedef int64_t off64_t;
-#endif
-
 // Byte sizes.
 const int kWordSize = sizeof(word);
 const int kDoubleSize = sizeof(double);  // NOLINT
@@ -469,12 +464,12 @@
 #if !defined(TEMP_FAILURE_RETRY)
 // TEMP_FAILURE_RETRY is defined in unistd.h on some platforms. The
 // definition below is copied from Linux and adapted to avoid lint
-// errors (type long int changed to int64_t and do/while split on
+// errors (type long int changed to intptr_t and do/while split on
 // separate lines with body in {}s).
 #define TEMP_FAILURE_RETRY(expression)                                         \
-    ({ int64_t __result;                                                       \
+    ({ intptr_t __result;                                                      \
        do {                                                                    \
-         __result = static_cast<int64_t>(expression);                          \
+         __result = (expression);                                              \
        } while (__result == -1L && errno == EINTR);                            \
        __result; })
 #endif  // !defined(TEMP_FAILURE_RETRY)
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 59e66b6..4359a4b 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -45,34 +45,34 @@
   }
 
   template<typename T>
-  static inline bool IsAligned(T x, int n) {
+  static inline bool IsAligned(T x, intptr_t n) {
     ASSERT(IsPowerOfTwo(n));
     return (x & (n - 1)) == 0;
   }
 
   template<typename T>
-  static inline bool IsAligned(T* x, int n) {
+  static inline bool IsAligned(T* x, intptr_t n) {
     return IsAligned(reinterpret_cast<uword>(x), n);
   }
 
   template<typename T>
-  static inline T RoundDown(T x, int n) {
+  static inline T RoundDown(T x, intptr_t n) {
     ASSERT(IsPowerOfTwo(n));
     return (x & -n);
   }
 
   template<typename T>
-  static inline T* RoundDown(T* x, int n) {
+  static inline T* RoundDown(T* x, intptr_t n) {
     return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uword>(x), n));
   }
 
   template<typename T>
-  static inline T RoundUp(T x, int n) {
+  static inline T RoundUp(T x, intptr_t n) {
     return RoundDown(x + n - 1, n);
   }
 
   template<typename T>
-  static inline T* RoundUp(T* x, int n) {
+  static inline T* RoundUp(T* x, intptr_t n) {
     return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n));
   }
 
diff --git a/runtime/tools/create_resources.py b/runtime/tools/create_resources.py
index 4468559..ab8371d 100644
--- a/runtime/tools/create_resources.py
+++ b/runtime/tools/create_resources.py
@@ -13,7 +13,7 @@
 import re
 from datetime import date
 
-def makeResources(root_dir, input_files):
+def makeResources(root_dir, input_files, table_name):
   result = ''
   resources = []
 
@@ -44,28 +44,39 @@
         (resource_url, resource_name, os.stat(resource_file).st_size) );
 
   # Write the resource table.
-  result += 'Resources::resource_map_entry Resources::builtin_resources_[] = '
+  result += 'ResourcesEntry __%s_resources_[] = ' % table_name
   result += '{\n'
   for res in resources:
     result += '   { "%s", %s, %d },\n' % res
+  result += '   { 0, 0, 0 },\n'
   result += '};\n\n'
-  result += 'const intptr_t Resources::builtin_resources_count_ '
-  result += '= %d;\n' % len(resources)
   return result
 
 
-def makeFile(output_file, root_dir, input_files):
+def makeFile(output_file, root_dir, input_files, outer_namespace,
+             inner_namespace, table_name):
   cc_text = '''
 // Copyright (c) %d, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 ''' % date.today().year
-  cc_text += '#include "bin/resources.h"\n\n'
-  cc_text += 'namespace dart {\n'
-  cc_text += 'namespace bin {\n'
-  cc_text += makeResources(root_dir, input_files)
-  cc_text += '}  // namespace bin\n} // namespace dart\n'
+  cc_text += 'namespace %s {\n' % outer_namespace
+  if inner_namespace != None:
+    cc_text += 'namespace %s {\n' % inner_namespace
+  cc_text += '''
+struct ResourcesEntry {
+  const char* path_;
+  const char* resource_;
+  int length_;
+};
+
+'''
+  cc_text += makeResources(root_dir, input_files, table_name)
+  cc_text += '\n'
+  if inner_namespace != None:
+    cc_text += '}  // namespace %s\n' % inner_namespace
+  cc_text += '} // namespace %s\n' % outer_namespace
   open(output_file, 'w').write(cc_text)
   return True
 
@@ -80,10 +91,23 @@
     parser.add_option("--root_prefix",
                       action="store", type="string",
                       help="root directory for resources")
+    parser.add_option("--outer_namespace",
+                      action="store", type="string",
+                      help="outer C++ namespace",
+                      default="dart")
+    parser.add_option("--inner_namespace",
+                      action="store", type="string",
+                      help="inner C++ namespace")
+    parser.add_option("--table_name",
+                      action="store", type="string",
+                      help="name of table")
     (options, args) = parser.parse_args()
     if not options.output:
       sys.stderr.write('--output not specified\n')
       return -1
+    if not options.table_name:
+      sys.stderr.write('--table_name not specified\n')
+      return -1
     if len(args) == 0:
       sys.stderr.write('No input files specified\n')
       return -1
@@ -92,7 +116,9 @@
     for arg in args:
       files.append(arg)
 
-    if not makeFile(options.output, options.root_prefix, files):
+    if not makeFile(options.output, options.root_prefix, files,
+                    options.outer_namespace, options.inner_namespace,
+                    options.table_name):
       return -1
 
     return 0
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 2a07e64..62c04de 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -414,7 +414,7 @@
       "import 'dart:async';\n"
       "import 'dart:core';\n"
       "import 'dart:collection';\n"
-      "import 'dart:_collection-dev';\n"
+      "import 'dart:_internal';\n"
       "import 'dart:math';\n"
       "import 'dart:isolate';\n"
       "import 'dart:mirrors';\n"
@@ -440,7 +440,7 @@
       "import 'dart:async';\n"
       "import 'dart:core';\n"
       "import 'dart:collection';\n"
-      "import 'dart:_collection-dev';\n"
+      "import 'dart:_internal';\n"
       "import 'dart:convert';\n"
       "import 'dart:math';\n"
       "import 'dart:isolate';\n"
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index d036fde..b42e94a 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -704,6 +704,9 @@
 
 
 bool BigintOperations::AbsFitsIntoUint64(const Bigint& bigint) {
+  if (bigint.IsZero()) {
+    return true;
+  }
   intptr_t b_length = bigint.Length();
   intptr_t num_bits = CountBits(bigint.GetChunkAt(b_length - 1));
   num_bits += (kDigitBitSize * (b_length - 1));
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index b04165a..fd4ce60 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -46,10 +46,10 @@
                collection,
                Bootstrap::collection_source_paths_,
                Bootstrap::collection_patch_paths_),
-  INIT_LIBRARY(ObjectStore::kCollectionDev,
-               _collection-dev,
-               Bootstrap::collection_dev_source_paths_,
-               Bootstrap::collection_dev_patch_paths_),
+  INIT_LIBRARY(ObjectStore::kInternal,
+               _internal,
+               Bootstrap::internal_source_paths_,
+               Bootstrap::internal_patch_paths_),
   INIT_LIBRARY(ObjectStore::kIsolate,
                isolate,
                Bootstrap::isolate_source_paths_,
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 6ebc812..5d3e53b 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -23,8 +23,8 @@
   static const char* async_source_paths_[];
   static const char* corelib_source_paths_[];
   static const char* collection_source_paths_[];
-  static const char* collection_dev_source_paths_[];
   static const char* convert_source_paths_[];
+  static const char* internal_source_paths_[];
   static const char* isolate_source_paths_[];
   static const char* json_source_paths_[];
   static const char* math_source_paths_[];
@@ -36,8 +36,8 @@
   static const char* async_patch_paths_[];
   static const char* corelib_patch_paths_[];
   static const char* collection_patch_paths_[];
-  static const char* collection_dev_patch_paths_[];
   static const char* convert_patch_paths_[];
+  static const char* internal_patch_paths_[];
   static const char* isolate_patch_paths_[];
   static const char* math_patch_paths_[];
   static const char* mirrors_patch_paths_[];
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 0a054bc..efc972a 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -89,6 +89,7 @@
   V(List_setIndexed, 3)                                                        \
   V(List_getLength, 1)                                                         \
   V(List_copyFromObjectArray, 5)                                               \
+  V(ImmutableList_from, 4)                                                     \
   V(StringBase_createFromCodePoints, 1)                                        \
   V(StringBase_substringUnchecked, 3)                                          \
   V(StringBuffer_createStringFromUint16Array, 3)                               \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 1ac53e7..d943215 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -577,7 +577,8 @@
               cls, super_type_arg, kFinalize, pending_types);
           super_type_args.SetTypeAt(i, super_type_arg);
         }
-        if (!super_type_arg.IsInstantiated()) {
+        if (!super_type_arg.IsBeingFinalized() &&
+            !super_type_arg.IsInstantiated()) {
           Error& error = Error::Handle();
           super_type_arg = super_type_arg.InstantiateFrom(arguments, &error);
           if (!error.IsNull()) {
@@ -637,6 +638,15 @@
       continue;
     }
     ASSERT(type_arg.IsFinalized());
+    if (type_arg.IsMalbounded()) {
+      // The type argument itself is already malbounded, independently of the
+      // declared bound, which may be Object.
+      // Propagate the bound error from the type argument to the type.
+      if (bound_error->IsNull()) {
+        *bound_error = type_arg.error();
+        ASSERT(!bound_error->IsNull());
+      }
+    }
     cls_type_param = cls_type_params.TypeAt(i);
     const TypeParameter& type_param = TypeParameter::Cast(cls_type_param);
     ASSERT(type_param.IsFinalized());
@@ -745,7 +755,6 @@
     }
     return type.raw();
   }
-  ASSERT(type.IsResolved());
   ASSERT(finalization >= kFinalize);
 
   if (type.IsTypeRef()) {
@@ -763,6 +772,7 @@
     return TypeRef::New(type);
   }
 
+  ASSERT(type.IsResolved());
   if (FLAG_trace_type_finalization) {
     OS::Print("Finalizing type '%s' for class '%s'\n",
               String::Handle(type.Name()).ToCString(),
@@ -864,11 +874,7 @@
       // argument vector.
       const intptr_t offset = num_type_arguments - num_type_parameters;
       AbstractType& type_arg = AbstractType::Handle(Type::DynamicType());
-      // TODO(regis): Leave the temporary type argument values as null.
-      for (intptr_t i = 0; i < offset; i++) {
-        // Temporarily set the type arguments of the super classes to dynamic.
-        full_arguments.SetTypeAt(i, type_arg);
-      }
+      // Leave the temporary type arguments at indices [0..offset[ as null.
       for (intptr_t i = 0; i < num_type_parameters; i++) {
         // If no type parameters were provided, a raw type is desired, so we
         // create a vector of dynamic.
@@ -1393,61 +1399,52 @@
 // 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(
+  Isolate* isolate = Isolate::Current();
+  const AbstractType& super_type = AbstractType::Handle(isolate,
       mixin_app_class.super_type());
   ASSERT(super_type.IsResolved());
-  const Class& super_class = Class::Handle(super_type.type_class());
+  const Class& super_class = Class::Handle(isolate, super_type.type_class());
   const intptr_t num_super_type_params = super_class.NumTypeParameters();
-  const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
-  const Class& mixin_class = Class::Handle(mixin_type.type_class());
+  const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
+  const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
   const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters();
   // The mixin class cannot be Object and this was checked earlier.
   ASSERT(!mixin_class.IsObjectClass());
 
   // Add the mixin type to the interfaces that the mixin application
   // class implements. This is necessary so that type tests work.
-  const Array& interfaces = Array::Handle(Array::New(1));
-  const Type& interface = Type::Handle(Type::New(
-      mixin_class,
-      Object::null_abstract_type_arguments(),  // Set again below if generic.
-      mixin_app_class.token_pos()));
-  ASSERT(!interface.IsFinalized());
-  interfaces.SetAt(0, interface);
+  const Array& interfaces = Array::Handle(isolate, Array::New(1));
+  interfaces.SetAt(0, mixin_type);
   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
   // application class is non generic as well and we can skip type parameter
   // cloning.
+  bool has_uninstantiated_bounds = false;
   if ((num_super_type_params + num_mixin_type_params) > 0) {
     // First, clone the super class type parameters. Rename them so that
     // there can be no name conflict between the parameters of the super
     // class and the mixin class.
-    const TypeArguments& cloned_type_params = TypeArguments::Handle(
+    const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate,
         TypeArguments::New(num_super_type_params + num_mixin_type_params));
-    TypeParameter& param = TypeParameter::Handle();
-    TypeParameter& cloned_param = TypeParameter::Handle();
-    String& param_name = String::Handle();
-    AbstractType& param_bound = AbstractType::Handle();
+    TypeParameter& param = TypeParameter::Handle(isolate);
+    TypeParameter& cloned_param = TypeParameter::Handle(isolate);
+    String& param_name = String::Handle(isolate);
+    AbstractType& param_bound = AbstractType::Handle(isolate);
     intptr_t cloned_index = 0;
     if (num_super_type_params > 0) {
       const TypeArguments& super_type_params =
-          TypeArguments::Handle(super_class.type_parameters());
-      const TypeArguments& super_type_args =
-          TypeArguments::Handle(TypeArguments::New(num_super_type_params));
+          TypeArguments::Handle(isolate, super_class.type_parameters());
+      const TypeArguments& super_type_args = TypeArguments::Handle(isolate,
+          TypeArguments::New(num_super_type_params));
+      // The cloned super class type parameters do not need to repeat their
+      // bounds, since the bound checks will be performed at the super class
+      // level.
+      param_bound = isolate->object_store()->object_type();
       for (intptr_t i = 0; i < num_super_type_params; i++) {
         param ^= super_type_params.TypeAt(i);
         param_name = param.name();
-        param_bound = param.bound();
-        // TODO(14453): handle type bounds.
-        if (!param_bound.IsObjectType()) {
-          const Script& script = Script::Handle(mixin_app_class.script());
-          ReportError(Error::Handle(),  // No previous error.
-                      script, param.token_pos(),
-                      "type parameter '%s': type bounds not yet"
-                      " implemented for mixins\n",
-                      param_name.ToCString());
-        }
         param_name = String::Concat(param_name, Symbols::Backtick());
         param_name = Symbols::New(param_name);
         cloned_param = TypeParameter::New(mixin_app_class,
@@ -1461,8 +1458,8 @@
         super_type_args.SetTypeAt(cloned_index, cloned_param);
         cloned_index++;
       }
-      // TODO(14453): May need to handle BoundedType here.
-      ASSERT(super_type.IsType());
+      // The super type may have a BoundedType as type argument, but cannot be
+      // a BoundedType itself.
       Type::Cast(super_type).set_arguments(super_type_args);
       ASSERT(!super_type.IsFinalized());
     }
@@ -1474,25 +1471,15 @@
     // with that name.
     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::Handle(isolate, mixin_class.type_parameters());
+      const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate,
           TypeArguments::New(num_mixin_type_params));
       for (intptr_t i = 0; i < num_mixin_type_params; i++) {
         param ^= mixin_params.TypeAt(i);
         param_name = param.name();
-        param_bound = param.bound();
-
-        // TODO(14453): handle type bounds.
-        if (!param_bound.IsObjectType()) {
-          const Script& script = Script::Handle(mixin_app_class.script());
-          ReportError(Error::Handle(),  // No previous error.
-                      script, param.token_pos(),
-                      "type parameter '%s': type bounds not yet"
-                      " implemented for mixins\n",
-                      param_name.ToCString());
+        param_bound = param.bound();  // The bound will be adjusted below.
+        if (!param_bound.IsInstantiated()) {
+          has_uninstantiated_bounds = true;
         }
         cloned_param = TypeParameter::New(mixin_app_class,
                                           cloned_index,
@@ -1500,17 +1487,42 @@
                                           param_bound,
                                           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 mixin type and of the single
-      // interface type.
+      // Third, replace the type parameters appearing in the bounds of the mixin
+      // type parameters, if any, by the cloned type parameters. This can be
+      // done by instantiating each bound using the mixin_type_args as
+      // instantiator. Since the mixin class must extend Object, its first type
+      // parameter has index 0, therefore, the instantiator does not require
+      // shifting. There is however an exception where the mixin class is an
+      // alias, in which case shifting is required and performed later in
+      // ApplyMixinAppAlias.
+      // Unfinalized type parameters replace finalized type parameters, which
+      // is not a problem since they will get finalized shortly as the mixin
+      // application class gets finalized.
+      if (has_uninstantiated_bounds && !mixin_class.is_mixin_app_alias()) {
+        Error& bound_error = Error::Handle(isolate);
+        for (intptr_t i = 0; i < num_mixin_type_params; i++) {
+          param ^= mixin_type_args.TypeAt(i);
+          param_bound = param.bound();
+          if (!param_bound.IsInstantiated()) {
+            param_bound = param_bound.InstantiateFrom(mixin_type_args,
+                                                      &bound_error);
+            // The instantiator contains only TypeParameter objects and no
+            // BoundedType objects, so no bound error may occur.
+            ASSERT(bound_error.IsNull());
+            ASSERT(!param_bound.IsInstantiated());
+            param.set_bound(param_bound);
+          }
+        }
+      }
+
+      // Lastly, set the type arguments of the mixin type, which is also the
+      // single interface type.
       ASSERT(!mixin_type.IsFinalized());
       mixin_type.set_arguments(mixin_type_args);
-      ASSERT(!interface.IsFinalized());
-      interface.set_arguments(interface_type_args);
     }
     mixin_app_class.set_type_parameters(cloned_type_params);
   }
@@ -1519,7 +1531,7 @@
   // application class. The new class will have the aliased mixin as actual
   // mixin.
   if (mixin_class.is_mixin_app_alias()) {
-    ApplyMixinAppAlias(mixin_app_class);
+    ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds);
   }
 }
 
@@ -1575,34 +1587,48 @@
 Object&M<Map<U, V>> of A and, therefore, U and V refer to A. An instantiation
 step with a properly crafted instantiator vector takes care of the required type
 parameter substitution.
-
 The instantiator vector must end with the type parameters U and V of S&A.
 The offset of the first type parameter U of S&A must be at the finalized index
 of type parameter U of A.
+
+The same instantiator vector is used to adjust the type parameter bounds on U
+and V, if any. This step was postponed from CloneMixinAppTypeParameters above.
+
+Also, a possible bound on type parameter T of M (not shown in the example above)
+must be applied to type parameter T of S&A`. If the bound is uninstantiated,
+i.e. if it refers to T or other type parameters of M, an instantiation step is
+required to substitute these type parameters of M with type parameters of S&A`.
+The instantiator vector consists of the cloned type parameters of M without
+offset, since class M must extend Object. This is done in the recursive call to
+CloneMixinAppTypeParameters and does not require specific code in
+ApplyMixinAppAlias.
 */
-void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class) {
+void ClassFinalizer::ApplyMixinAppAlias(const Class& mixin_app_class,
+                                        bool has_uninstantiated_bounds) {
   // If this mixin alias is aliasing another mixin alias, 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());
+  Isolate* isolate = Isolate::Current();
+  AbstractType& super_type = AbstractType::Handle(isolate,
+                                                  mixin_app_class.super_type());
+  const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin());
+  const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class());
   ASSERT(mixin_class.is_mixin_app_alias());
-  const Class& aliased_mixin_app_class = Class::Handle(
+  const Class& aliased_mixin_app_class = Class::Handle(isolate,
       mixin_class.SuperClass());
-  const Type& aliased_mixin_type = Type::Handle(
+  const Type& aliased_mixin_type = Type::Handle(isolate,
       aliased_mixin_app_class.mixin());
   // The name of the inserted mixin application class is the name of mixin
   // class name with a backtick added.
-  String& inserted_class_name = String::Handle(mixin_app_class.Name());
+  String& inserted_class_name = String::Handle(isolate, mixin_app_class.Name());
   inserted_class_name = String::Concat(inserted_class_name,
                                        Symbols::Backtick());
-  const Library& library = Library::Handle(mixin_app_class.library());
-  Class& inserted_class = Class::Handle(
+  const Library& library = Library::Handle(isolate, mixin_app_class.library());
+  Class& inserted_class = Class::Handle(isolate,
       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());
+    const Script& script = Script::Handle(isolate, mixin_app_class.script());
     inserted_class = Class::New(
         inserted_class_name, script, mixin_app_class.token_pos());
     inserted_class.set_is_synthesized_class();
@@ -1626,8 +1652,8 @@
     // 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()),
+    const Type& generic_mixin_type = Type::Handle(isolate,
+        Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()),
                   Object::null_abstract_type_arguments(),
                   aliased_mixin_type.token_pos()));
     inserted_class.set_mixin(generic_mixin_type);
@@ -1649,7 +1675,7 @@
   // It is important that the type parameters of the mixin application class
   // are not finalized yet, because new type parameters may have been added
   // to the super class.
-  Class& super_class = Class::Handle(super_type.type_class());
+  Class& super_class = Class::Handle(isolate, super_type.type_class());
   ASSERT(mixin_app_class.SuperClass() == super_class.raw());
   while (super_class.IsMixinApplication()) {
     super_class = super_class.SuperClass();
@@ -1659,16 +1685,16 @@
   intptr_t offset =
       mixin_class.NumTypeArguments() - mixin_class.NumTypeParameters();
   const TypeArguments& type_params =
-      TypeArguments::Handle(mixin_app_class.type_parameters());
-  TypeArguments& instantiator = TypeArguments::Handle(
+      TypeArguments::Handle(isolate, mixin_app_class.type_parameters());
+  TypeArguments& instantiator = TypeArguments::Handle(isolate,
       TypeArguments::New(offset + num_mixin_type_params));
-  AbstractType& type = AbstractType::Handle();
+  AbstractType& type = AbstractType::Handle(isolate);
   for (intptr_t i = 0; i < num_mixin_type_params; i++) {
     type = type_params.TypeAt(num_super_type_params + i);
     instantiator.SetTypeAt(offset + i, type);
   }
   ASSERT(aliased_mixin_type.IsFinalized());
-  const Class& aliased_mixin_type_class = Class::Handle(
+  const Class& aliased_mixin_type_class = Class::Handle(isolate,
       aliased_mixin_type.type_class());
   const intptr_t num_aliased_mixin_type_params =
       aliased_mixin_type_class.NumTypeParameters();
@@ -1679,9 +1705,9 @@
          (num_super_type_params + num_aliased_mixin_type_params));
   // The aliased_mixin_type may be raw.
   const AbstractTypeArguments& mixin_class_super_type_args =
-      AbstractTypeArguments::Handle(
-          AbstractType::Handle(mixin_class.super_type()).arguments());
-  TypeArguments& new_mixin_type_args = TypeArguments::Handle();
+      AbstractTypeArguments::Handle(isolate,
+          AbstractType::Handle(isolate, mixin_class.super_type()).arguments());
+  TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate);
   if ((num_aliased_mixin_type_params > 0) &&
       !mixin_class_super_type_args.IsNull()) {
     new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
@@ -1692,13 +1718,14 @@
   }
   if (!new_mixin_type_args.IsNull() &&
       !new_mixin_type_args.IsInstantiated()) {
-    Error& bound_error = Error::Handle();
+    Error& bound_error = Error::Handle(isolate);
     new_mixin_type_args ^=
         new_mixin_type_args.InstantiateFrom(instantiator, &bound_error);
-    // TODO(14453): Handle bound error.
+    // The instantiator contains only TypeParameter objects and no BoundedType
+    // objects, so no bound error may occur.
     ASSERT(bound_error.IsNull());
   }
-  TypeArguments& new_super_type_args = TypeArguments::Handle();
+  TypeArguments& new_super_type_args = TypeArguments::Handle(isolate);
   if ((num_super_type_params + num_aliased_mixin_type_params) > 0) {
     new_super_type_args = TypeArguments::New(num_super_type_params +
                                              num_aliased_mixin_type_params);
@@ -1719,6 +1746,26 @@
                          new_super_type_args,
                          mixin_app_class.token_pos());
   mixin_app_class.set_super_type(super_type);
+
+  // Perform the bound adjustment posponed from CloneMixinAppTypeParameters.
+  if (has_uninstantiated_bounds) {
+    TypeParameter& param = TypeParameter::Handle(isolate);
+    AbstractType& param_bound = AbstractType::Handle(isolate);
+    Error& bound_error = Error::Handle(isolate);
+    for (intptr_t i = 0; i < num_mixin_type_params; i++) {
+      param ^= type_params.TypeAt(num_super_type_params + i);
+      param_bound = param.bound();
+      if (!param_bound.IsInstantiated()) {
+        param_bound = param_bound.InstantiateFrom(instantiator, &bound_error);
+        // The instantiator contains only TypeParameter objects and no
+        // BoundedType objects, so no bound error may occur.
+        ASSERT(bound_error.IsNull());
+        ASSERT(!param_bound.IsInstantiated());
+        param.set_bound(param_bound);
+      }
+    }
+  }
+
   // Mark this mixin application class as being an alias.
   mixin_app_class.set_is_mixin_app_alias();
   ASSERT(!mixin_app_class.is_type_finalized());
@@ -1728,7 +1775,7 @@
               "with super type '%s'\n",
               inserted_class.ToCString(),
               mixin_app_class.ToCString(),
-              String::Handle(super_type.Name()).ToCString());
+              String::Handle(isolate, super_type.Name()).ToCString());
   }
 }
 
@@ -1806,7 +1853,10 @@
   ASSERT(!mixin_type.IsBeingFinalized());
   mixin_type ^=
       FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types);
-  // TODO(14453): Check for a malbounded mixin_type.
+  // The mixin type cannot be malbounded, since it merely substitutes the
+  // type parameters of the mixin class with those of the mixin application
+  // class, but it does not instantiate them.
+  ASSERT(!mixin_type.IsMalbounded());
   mixin_app_class.set_mixin(mixin_type);
 }
 
@@ -1876,7 +1926,8 @@
   ASSERT(!mixin_type.IsNull());
   ASSERT(mixin_type.HasResolvedTypeClass());
   const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
-  mixin_cls.EnsureIsFinalized(isolate);
+  const Error& error = Error::Handle(mixin_cls.EnsureIsFinalized(isolate));
+  ASSERT(error.IsNull());
   // If the mixin is a mixin application alias class, there are no members to
   // apply here. A new synthesized class representing the aliased mixin
   // application class was inserted in the super chain of this mixin application
@@ -1982,7 +2033,8 @@
   AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (!super_type.IsNull()) {
     // In case of a bound error in the super type in production mode, the
-    // finalized super type will be a BoundedType with a malformed bound.
+    // finalized super type will have a BoundedType as type argument for the
+    // out of bound type argument.
     // It should not be a problem if the class is written to a snapshot and
     // later executed in checked mode. Note that the finalized type argument
     // vector of any type of the base class will contain a BoundedType for the
@@ -2315,9 +2367,9 @@
   AbstractType& mixin_super_type =
       AbstractType::Handle(mixin_app_type.super_type());
   ResolveType(cls, mixin_super_type);
-  ASSERT(mixin_super_type.HasResolvedTypeClass());
-  // TODO(14453): May need to handle BoundedType here.
-  ASSERT(mixin_super_type.IsType());
+  ASSERT(mixin_super_type.HasResolvedTypeClass());  // Even if malformed.
+  // The super type may have a BoundedType as type argument, but cannot be
+  // a BoundedType itself.
   CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
   AbstractType& mixin_type = AbstractType::Handle();
   Type& generic_mixin_type = Type::Handle();
@@ -2330,7 +2382,7 @@
     mixin_type = mixin_app_type.MixinTypeAt(i);
     ASSERT(!mixin_type.IsNull());
     ResolveType(cls, mixin_type);
-    ASSERT(mixin_type.HasResolvedTypeClass());
+    ASSERT(mixin_type.HasResolvedTypeClass());  // Even if malformed.
     ASSERT(mixin_type.IsType());
     CollectTypeArguments(cls, Type::Cast(mixin_type), type_args);
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index a4f148e..a62a3ed 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -125,7 +125,8 @@
       const Function& factory,
       const GrowableObjectArray& visited_factories);
   static void CloneMixinAppTypeParameters(const Class& mixin_app_class);
-  static void ApplyMixinAppAlias(const Class& mixin_app_class);
+  static void ApplyMixinAppAlias(const Class& mixin_app_class,
+                                 bool has_uninstantiated_bounds);
   static void ApplyMixinMembers(const Class& cls);
   static void CreateForwardingConstructors(
       const Class& mixin_app,
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index d838eff..8ba0237 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -227,6 +227,11 @@
         Symbols::Empty(), bound_error_message);
     UNREACHABLE();
   }
+  if (type.IsTypeRef()) {
+    type = TypeRef::Cast(type).type();
+    ASSERT(!type.IsTypeRef());
+    ASSERT(type.IsCanonical());
+  }
   ASSERT(!type.IsNull() && type.IsInstantiated());
   arguments.SetReturn(type);
 }
@@ -611,22 +616,41 @@
     // Throw a dynamic type error.
     const intptr_t location = GetCallerLocation();
     const AbstractType& src_type = AbstractType::Handle(src_instance.GetType());
-    const String& src_type_name = String::Handle(src_type.UserVisibleName());
+    String& src_type_name = String::Handle(src_type.UserVisibleName());
     String& dst_type_name = String::Handle();
+    Library& dst_type_lib = Library::Handle();
     if (!dst_type.IsInstantiated()) {
       // Instantiate dst_type before reporting the error.
       const AbstractType& instantiated_dst_type = AbstractType::Handle(
           dst_type.InstantiateFrom(instantiator_type_arguments, NULL));
       // Note that instantiated_dst_type may be malbounded.
       dst_type_name = instantiated_dst_type.UserVisibleName();
+      dst_type_lib =
+          Class::Handle(instantiated_dst_type.type_class()).library();
     } else {
       dst_type_name = dst_type.UserVisibleName();
+      dst_type_lib = Class::Handle(dst_type.type_class()).library();
     }
     String& bound_error_message =  String::Handle();
     if (!bound_error.IsNull()) {
       ASSERT(FLAG_enable_type_checks);
       bound_error_message = String::New(bound_error.ToErrorCString());
     }
+    if (src_type_name.Equals(dst_type_name)) {
+      // Qualify the names with their libraries.
+      String& lib_name = String::Handle();
+      lib_name = Library::Handle(
+          Class::Handle(src_type.type_class()).library()).name();
+      if (lib_name.Length() != 0) {
+        lib_name = String::Concat(lib_name, Symbols::Dot());
+        src_type_name = String::Concat(lib_name, src_type_name);
+      }
+      lib_name = dst_type_lib.name();
+      if (lib_name.Length() != 0) {
+        lib_name = String::Concat(lib_name, Symbols::Dot());
+        dst_type_name = String::Concat(lib_name, dst_type_name);
+      }
+    }
     Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name,
                                         dst_name, bound_error_message);
     UNREACHABLE();
@@ -816,14 +840,6 @@
 }
 
 
-// Gets called from debug stub when code reaches a breakpoint at a return
-// in Dart code.
-DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) {
-  ASSERT(isolate->debugger() != NULL);
-  isolate->debugger()->SignalBpReached();
-}
-
-
 // Gets called from debug stub when code reaches a breakpoint.
 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) {
   ASSERT(isolate->debugger() != NULL);
@@ -1412,6 +1428,9 @@
   ASSERT(function.HasCode());
 
   if (CanOptimizeFunction(function, isolate)) {
+    // Reset usage counter for reoptimization before calling optimizer to
+    // prevent recursive triggering of function optimization.
+    function.set_usage_counter(0);
     const Error& error =
         Error::Handle(Compiler::CompileOptimizedFunction(function));
     if (!error.IsNull()) {
@@ -1419,8 +1438,6 @@
     }
     const Code& optimized_code = Code::Handle(function.CurrentCode());
     ASSERT(!optimized_code.IsNull());
-    // Reset usage counter for reoptimization.
-    function.set_usage_counter(0);
   }
   arguments.SetReturn(Code::Handle(function.CurrentCode()));
 }
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 47e9444..a01bc6b 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -24,7 +24,6 @@
 DECLARE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck);
 DECLARE_RUNTIME_ENTRY(BreakpointRuntimeHandler);
 DECLARE_RUNTIME_ENTRY(BreakpointStaticHandler);
-DECLARE_RUNTIME_ENTRY(BreakpointReturnHandler);
 DECLARE_RUNTIME_ENTRY(BreakpointDynamicHandler);
 DECLARE_RUNTIME_ENTRY(SingleStepHandler);
 DECLARE_RUNTIME_ENTRY(CloneContext);
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 248d413..5cbfefa 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -17,6 +17,7 @@
 #include "vm/object_id_ring.h"
 #include "vm/port.h"
 #include "vm/profiler.h"
+#include "vm/service.h"
 #include "vm/simulator.h"
 #include "vm/snapshot.h"
 #include "vm/stub_code.h"
@@ -28,8 +29,6 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool, heap_profile_initialize, false,
-            "Writes a heap profile on isolate initialization.");
 DECLARE_FLAG(bool, print_class_table);
 DECLARE_FLAG(bool, trace_isolates);
 
@@ -84,7 +83,8 @@
                            Dart_FileReadCallback file_read,
                            Dart_FileWriteCallback file_write,
                            Dart_FileCloseCallback file_close,
-                           Dart_EntropySource entropy_source) {
+                           Dart_EntropySource entropy_source,
+                           Dart_ServiceIsolateCreateCalback service_create) {
   // TODO(iposva): Fix race condition here.
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
     return "VM already initialized.";
@@ -141,6 +141,7 @@
 
   Isolate::SetCurrent(NULL);  // Unregister the VM isolate from this thread.
   Isolate::SetCreateCallback(create);
+  Isolate::SetServiceCreateCallback(service_create);
   Isolate::SetInterruptCallback(interrupt);
   Isolate::SetUnhandledExceptionCallback(unhandled);
   Isolate::SetShutdownCallback(shutdown);
@@ -224,10 +225,6 @@
     }
   }
 
-  if (FLAG_heap_profile_initialize) {
-    isolate->heap()->ProfileToFile("initialize");
-  }
-
   Object::VerifyBuiltinVtables();
 
   StubCode::Init(isolate);
@@ -244,6 +241,7 @@
   if (FLAG_print_class_table) {
     isolate->class_table()->Print();
   }
+  Service::SendIsolateStartupMessage();
   return Error::null();
 }
 
@@ -252,6 +250,7 @@
   Isolate* isolate = Isolate::Current();
   void* callback_data = isolate->init_callback_data();
   Dart_IsolateShutdownCallback callback = Isolate::ShutdownCallback();
+  Service::SendIsolateShutdownMessage();
   if (callback != NULL) {
     (callback)(callback_data);
   }
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 135c6b0..e7d9098 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -28,7 +28,8 @@
       Dart_FileReadCallback file_read,
       Dart_FileWriteCallback file_write,
       Dart_FileCloseCallback file_close,
-      Dart_EntropySource entropy_source);
+      Dart_EntropySource entropy_source,
+      Dart_ServiceIsolateCreateCalback service_create);
   static const char* Cleanup();
 
   static Isolate* CreateIsolate(const char* name_prefix);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 02cf512..3683d21 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -27,6 +27,7 @@
 #include "vm/port.h"
 #include "vm/resolver.h"
 #include "vm/reusable_handles.h"
+#include "vm/service.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 #include "vm/timer.h"
@@ -793,10 +794,12 @@
     Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source) {
+    Dart_EntropySource entropy_source,
+    Dart_ServiceIsolateCreateCalback service_create) {
   const char* err_msg = Dart::InitOnce(create, interrupt, unhandled, shutdown,
                                        file_open, file_read, file_write,
-                                       file_close, entropy_source);
+                                       file_close, entropy_source,
+                                       service_create);
   if (err_msg != NULL) {
     OS::PrintErr("Dart_Initialize: %s\n", err_msg);
     return false;
@@ -1169,6 +1172,34 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_PostMessage(Dart_Handle send_port,
+                                         Dart_Handle object) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  Instance& port_instance = Instance::Handle();
+  port_instance ^= Api::UnwrapHandle(send_port);
+  if (!DartLibraryCalls::IsSendPort(port_instance)) {
+    return Api::NewError("send_port is not a SendPort.");
+  }
+  const Object& idObj = Object::Handle(
+      DartLibraryCalls::PortGetId(port_instance));
+  ASSERT(!idObj.IsError());
+  Integer& id = Integer::Handle();
+  id ^= idObj.raw();
+  Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value());
+  uint8_t* data = NULL;
+  MessageWriter writer(&data, &allocator);
+  Object& msg_object = Object::Handle(Api::UnwrapHandle(object));
+  writer.WriteMessage(msg_object);
+  intptr_t len = writer.BytesWritten();
+  bool r = PortMap::PostMessage(
+      new Message(port, data, len, Message::kNormalPriority));
+  if (r) {
+    return Api::Success();
+  }
+  return Api::NewError("Dart_PostMessage failed.");
+}
+
 // --- Scopes ----
 
 DART_EXPORT void Dart_EnterScope() {
@@ -4495,4 +4526,11 @@
   return Api::Success();
 }
 
+
+// --- Service support ---
+
+DART_EXPORT Dart_Isolate Dart_GetServiceIsolate(void* callback_data) {
+  return Api::CastIsolate(Service::GetServiceIsolate(callback_data));
+}
+
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index f048340..30b3ad5 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -4616,7 +4616,7 @@
 
 TEST_CASE(InvokeNoSuchMethod) {
   const char* kScriptChars =
-      "import 'dart:_collection-dev' as _collection_dev;\n"
+      "import 'dart:_internal' as _internal;\n"
       "class Expect {\n"
       "  static equals(a, b) {\n"
       "    if (a != b) {\n"
@@ -4627,7 +4627,7 @@
       "class TestClass {\n"
       "  static int fld1 = 0;\n"
       "  void noSuchMethod(Invocation invocation) {\n"
-      "    var name = _collection_dev.Symbol.getName(invocation.memberName);\n"
+      "    var name = _internal.Symbol.getName(invocation.memberName);\n"
       "    if (name == 'fld') {\n"
       "      Expect.equals(true, invocation.isGetter);\n"
       "      Expect.equals(false, invocation.isMethod);\n"
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index f8d7794..70d5720 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -395,16 +395,17 @@
 
 
 Dart_CObject* ApiMessageReader::ReadObjectRef() {
-  int64_t value = Read<int64_t>();
-  if ((value & kSmiTagMask) == 0) {
-    int64_t untagged_value = value >> kSmiTagShift;
-    if (kMinInt32 <= untagged_value && untagged_value <= kMaxInt32) {
-      return AllocateDartCObjectInt32(untagged_value);
+  int64_t value64 = Read<int64_t>();
+  if ((value64 & kSmiTagMask) == 0) {
+    int64_t untagged_value = value64 >> kSmiTagShift;
+    if ((kMinInt32 <= untagged_value) && (untagged_value <= kMaxInt32)) {
+      return AllocateDartCObjectInt32(static_cast<int32_t>(untagged_value));
     } else {
       return AllocateDartCObjectInt64(untagged_value);
     }
   }
-  ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
+  ASSERT((value64 <= kIntptrMax) && (value64 >= kIntptrMin));
+  intptr_t value = static_cast<intptr_t>(value64);
   if (IsVMIsolateObject(value)) {
     return ReadVMIsolateObject(value);
   }
@@ -512,12 +513,12 @@
       return value;
     }
     case kMintCid: {
-      int64_t value = Read<int64_t>();
+      int64_t value64 = Read<int64_t>();
       Dart_CObject* object;
-      if (kMinInt32 <= value && value <= kMaxInt32) {
-        object = AllocateDartCObjectInt32(value);
+      if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) {
+        object = AllocateDartCObjectInt32(static_cast<int32_t>(value64));
       } else {
-        object = AllocateDartCObjectInt64(value);
+        object = AllocateDartCObjectInt64(value64);
       }
       AddBackRef(object_id, object, kIsDeserialized);
       return object;
@@ -718,16 +719,17 @@
 
 
 Dart_CObject* ApiMessageReader::ReadObjectImpl() {
-  int64_t value = Read<int64_t>();
-  if ((value & kSmiTagMask) == 0) {
-    int64_t untagged_value = value >> kSmiTagShift;
-    if (kMinInt32 <= untagged_value && untagged_value <= kMaxInt32) {
-      return AllocateDartCObjectInt32(untagged_value);
+  int64_t value64 = Read<int64_t>();
+  if ((value64 & kSmiTagMask) == 0) {
+    int64_t untagged_value = value64 >> kSmiTagShift;
+    if ((kMinInt32 <= untagged_value) && (untagged_value <= kMaxInt32)) {
+      return AllocateDartCObjectInt32(static_cast<int32_t>(untagged_value));
     } else {
       return AllocateDartCObjectInt64(untagged_value);
     }
   }
-  ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
+  ASSERT((value64 <= kIntptrMax) && (value64 >= kIntptrMin));
+  intptr_t value = static_cast<intptr_t>(value64);
   if (IsVMIsolateObject(value)) {
     return ReadVMIsolateObject(value);
   }
@@ -847,7 +849,7 @@
 
 void ApiMessageWriter::WriteSmi(int64_t value) {
   ASSERT(Smi::IsValid64(value));
-  Write<RawObject*>(Smi::New(value));
+  Write<RawObject*>(Smi::New(static_cast<intptr_t>(value)));
 }
 
 
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 97dd924..33c97c6 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -437,7 +437,7 @@
 }
 
 
-RawObject* DartLibraryCalls::NewSendPort(intptr_t port_id) {
+RawObject* DartLibraryCalls::NewSendPort(Dart_Port port_id) {
   Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
   ASSERT(!isolate_lib.IsNull());
   const String& class_name =
@@ -493,4 +493,16 @@
 }
 
 
+bool DartLibraryCalls::IsSendPort(const Instance& send_port) {
+  // Get instance class.
+  const Class& cls = Class::Handle(send_port.clazz());
+  // Get send port class from isolate library.
+  const Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
+  const Class& send_port_cls = Class::Handle(
+      isolate_lib.LookupClassAllowPrivate(Symbols::_SendPortImpl()));
+  // Check for the same class id.
+  ASSERT(!send_port_cls.IsNull());
+  return cls.id() == send_port_cls.id();
+}
+
 }  // namespace dart
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 7420e8b..760b26f 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -170,7 +170,7 @@
                                   const Instance& dart_message);
 
   // On success returns new SendPort, on failure returns a RawError.
-  static RawObject* NewSendPort(intptr_t port_id);
+  static RawObject* NewSendPort(Dart_Port port_id);
 
   // map[key] = value;
   //
@@ -183,6 +183,8 @@
   //
   // Returns the value of _id on success, a RawError on failure.
   static RawObject* PortGetId(const Instance& port);
+
+  static bool IsSendPort(const Instance& send_port);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 3b76466..43e7977 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -158,7 +158,7 @@
   }
 
   uint8_t* buffer() const { return *buffer_; }
-  int bytes_written() const { return current_ - *buffer_; }
+  intptr_t bytes_written() const { return current_ - *buffer_; }
 
   void set_current(uint8_t* value) { current_ = value; }
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 20cb409..bcecb46 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1741,21 +1741,27 @@
   DictionaryIterator it(lib);
   Object& entry = Object::Handle(isolate_);
   Field& field = Field::Handle(isolate_);
-  Class& cls = Class::Handle(isolate_);
   String& field_name = String::Handle(isolate_);
   Object& field_value = Object::Handle(isolate_);
   while (it.HasNext()) {
     entry = it.GetNext();
     if (entry.IsField()) {
       field ^= entry.raw();
-      cls = field.owner();
       ASSERT(field.is_static());
       field_name = field.name();
       if ((field_name.CharAt(0) == '_') && !include_private_fields) {
         // Skip library-private field.
         continue;
       }
-      field_value = GetStaticField(cls, field_name);
+      // If the field is not initialized yet, report the value to be
+      // "<not initialized>". We don't want to execute the implicit getter
+      // since it may have side effects.
+      if ((field.value() == Object::sentinel().raw()) ||
+          (field.value() == Object::transition_sentinel().raw())) {
+        field_value = Symbols::NotInitialized().raw();
+      } else {
+        field_value = field.value();
+      }
       if (!prefix.IsNull()) {
         field_name = String::Concat(prefix, field_name);
       }
@@ -1886,6 +1892,11 @@
   if (frame->TokenPos() == Scanner::kDummyTokenIndex) {
     return;
   }
+  // Don't pause for a single step if there is a breakpoint set
+  // at this location.
+  if (HasActiveBreakpoint(frame->pc())) {
+    return;
+  }
 
   if (FLAG_verbose_debug) {
     OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
@@ -2095,6 +2106,14 @@
 }
 
 
+// TODO(hausner): Could potentially make this faster by checking
+// whether the call target at pc is a debugger stub.
+bool Debugger::HasActiveBreakpoint(uword pc) {
+  CodeBreakpoint* bpt = GetCodeBreakpoint(pc);
+  return (bpt != NULL) && (bpt->IsEnabled());
+}
+
+
 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) {
   CodeBreakpoint* bpt = code_breakpoints_;
   while (bpt != NULL) {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 573ea50..1f81084 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -322,6 +322,10 @@
   // Checks for both user-defined and internal temporary breakpoints.
   bool HasBreakpoint(const Function& func);
 
+  // Returns true if the call at address pc is patched to point to
+  // a debugger stub.
+  bool HasActiveBreakpoint(uword pc);
+
   // Returns a stack trace with frames corresponding to invisible functions
   // omitted. CurrentStackTrace always returns a new trace on the current stack.
   // The trace returned by StackTrace may have been cached; it is suitable for
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 087010f..1d49949 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -31,8 +31,6 @@
 
 DEFINE_FLAG(bool, print_stacktrace_at_throw, false,
             "Prints a stack trace everytime a throw occurs.");
-DEFINE_FLAG(bool, heap_profile_out_of_memory, false,
-            "Writes a heap profile on unhandled out-of-memory exceptions.");
 DEFINE_FLAG(bool, verbose_stacktrace, false,
     "Stack traces will include methods marked invisible.");
 
@@ -448,11 +446,6 @@
                            exception,
                            stacktrace);
   } else {
-    if (FLAG_heap_profile_out_of_memory) {
-      if (exception.raw() == isolate->object_store()->out_of_memory()) {
-        isolate->heap()->ProfileToFile("out-of-memory");
-      }
-    }
     // No dart exception handler found in this invocation sequence,
     // so we create an unhandled exception object and return to the
     // invocation stub so that it returns this unhandled exception
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 5f03f47..7e6084e 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -6,9 +6,10 @@
 
 #include "vm/bit_vector.h"
 #include "vm/flow_graph_builder.h"
+#include "vm/growable_array.h"
 #include "vm/intermediate_language.h"
 #include "vm/longjump.h"
-#include "vm/growable_array.h"
+#include "vm/stack_frame.h"
 
 namespace dart {
 
@@ -77,6 +78,8 @@
 
 
 ConstantInstr* FlowGraph::GetConstant(const Object& object) {
+  // Not all objects can be embedded in code.
+  ASSERT(object.IsSmi() || object.InVMHeap() || object.IsOld());
   // Check if the constant is already in the pool.
   GrowableArray<Definition*>* pool = graph_entry_->initial_definitions();
   for (intptr_t i = 0; i < pool->length(); ++i) {
@@ -695,6 +698,47 @@
 }
 
 
+void FlowGraph::InitializeOsrLocalRange(GrowableArray<Definition*>* env,
+                                        RawObject** base,
+                                        intptr_t count) {
+  for (intptr_t i = 0; i < count; ++i) {
+    // Variables go from high to low addresses as they go from left to
+    // right.
+    const Object& value = Object::ZoneHandle(base[-i]);
+    Definition* definition = NULL;
+    if (value.IsSmi() || value.InVMHeap() || value.IsOld()) {
+      definition = GetConstant(value);
+    } else {
+      definition = new ParameterInstr(env->length(), graph_entry());
+      definition->set_ssa_temp_index(alloc_ssa_temp_index());
+      AddToInitialDefinitions(definition);
+    }
+    env->Add(definition);
+  }
+}
+
+
+void FlowGraph::InitializeOsrLocals(GrowableArray<Definition*>* env) {
+  DartFrameIterator iterator;
+  StackFrame* frame = iterator.NextFrame();
+  const Code& code = Code::Handle(frame->LookupDartCode());
+  ASSERT(!code.is_optimized());
+  ASSERT(frame->LookupDartFunction() == parsed_function().function().raw());
+
+  // Initialize parameters and locals in the order they appear in the
+  // environment (left-to-right, parameters first).
+  intptr_t count = num_non_copied_params();
+  RawObject** base = reinterpret_cast<RawObject**>(frame->fp())
+      + kParamEndSlotFromFp  // One past the last parameter.
+      + count;
+  InitializeOsrLocalRange(env, base, count);
+
+  count = num_copied_params() + num_stack_locals();
+  base = reinterpret_cast<RawObject**>(frame->fp()) + kFirstLocalSlotFromFp;
+  InitializeOsrLocalRange(env, base, count);
+}
+
+
 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
                        VariableLivenessAnalysis* variable_liveness,
                        ZoneGrowableArray<Definition*>* inlining_parameters) {
@@ -712,7 +756,7 @@
 
   // Add parameters to the initial definitions and renaming environment.
   if (inlining_parameters != NULL) {
-    // Use known parameters.
+    // When inlining, use the known parameter definitions.
     ASSERT(parameter_count() == inlining_parameters->length());
     for (intptr_t i = 0; i < parameter_count(); ++i) {
       Definition* defn = (*inlining_parameters)[i];
@@ -720,11 +764,13 @@
       AddToInitialDefinitions(defn);
       env.Add(defn);
     }
+  } else if (IsCompiledForOsr()) {
+    // For functions compiled for OSR, use the constants found in the
+    // unoptimized frame.
+    InitializeOsrLocals(&env);
   } else {
-    // Create new parameters.  For functions compiled for OSR, the locals
-    // are unknown and so treated like parameters.
-    intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count();
-    for (intptr_t i = 0; i < count; ++i) {
+    // Create fresh (unknown) parameters.
+    for (intptr_t i = 0; i < parameter_count(); ++i) {
       ParameterInstr* param = new ParameterInstr(i, entry);
       param->set_ssa_temp_index(alloc_ssa_temp_index());  // New SSA temp.
       AddToInitialDefinitions(param);
@@ -740,12 +786,6 @@
     }
   }
 
-  if (entry->SuccessorCount() > 1) {
-    // Functions with try-catch have a fixed area of stack slots reserved
-    // so that all local variables are stored at a known location when
-    // on entry to the catch.
-    entry->set_fixed_slot_count(num_stack_locals() + num_copied_params());
-  }
   RenameRecursive(entry, &env, live_phis, variable_liveness);
 }
 
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 4b31a11..aec6ddf 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -223,6 +223,11 @@
       GrowableArray<intptr_t>* parent,
       GrowableArray<intptr_t>* label);
 
+  void InitializeOsrLocals(GrowableArray<Definition*>* env);
+  void InitializeOsrLocalRange(GrowableArray<Definition*>* env,
+                               RawObject** base,
+                               intptr_t count);
+
   void Rename(GrowableArray<PhiInstr*>* live_phis,
               VariableLivenessAnalysis* variable_liveness,
               ZoneGrowableArray<Definition*>* inlining_parameters);
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index b59a05b..5b9c3cb 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -580,15 +580,19 @@
   }
   ConvertAllUses(range);
   if (defn->IsParameter() && (range->spill_slot().stack_index() >= 0)) {
-    // Parameters above the frame pointer consume spill slots and are marked
-    // in stack maps.
-    spill_slots_.Add(range_end);
-    quad_spill_slots_.Add(false);
+    // Parameters above the frame pointer occupy (allocatable) spill slots
+    // and are marked in stack maps.  There are multiple non-interfering
+    // live ranges occupying the same spill slot (e.g., those for different
+    // catch blocks).  Block the spill slot until the latest such live range
+    // endpoint.
+    intptr_t index = range->spill_slot().stack_index();
+    while (index > (spill_slots_.length() - 1)) {
+      spill_slots_.Add(-1);
+      quad_spill_slots_.Add(false);
+    }
+    spill_slots_[index] = Utils::Maximum(spill_slots_[index], range_end);
+    ASSERT(!quad_spill_slots_[index]);
     MarkAsObjectAtSafepoints(range);
-  } else if (defn->IsConstant() && block->IsCatchBlockEntry()) {
-    // Constants at catch block entries consume spill slots.
-    spill_slots_.Add(range_end);
-    quad_spill_slots_.Add(false);
   }
 }
 
@@ -1607,11 +1611,7 @@
   // Search for a free spill slot among allocated: the value in it should be
   // dead and its type should match (e.g. it should not be a part of the quad if
   // we are allocating normal double slot).
-  // For CPU registers we need to take reserved slots for try-catch into
-  // account.
-  intptr_t idx = register_kind_ == Location::kRegister
-      ? flow_graph_.graph_entry()->fixed_slot_count()
-      : 0;
+  intptr_t idx = 0;
   for (; idx < spill_slots_.length(); idx++) {
     if ((need_quad == quad_spill_slots_[idx]) &&
         (spill_slots_[idx] <= start)) {
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 082c46c..ea8313d 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1012,7 +1012,6 @@
     intptr_t extra_slots = StackSize()
         - flow_graph().num_stack_locals()
         - flow_graph().num_copied_params();
-    ASSERT(extra_slots >= 0);
     __ EnterOsrFrame(extra_slots * kWordSize);
   } else {
     ASSERT(StackSize() >= 0);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index cfbdaed..c95dacf 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -743,10 +743,18 @@
 
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) return;
+  if (is_optimizing()) {
+    return;
+  }
   Definition* defn = instr->AsDefinition();
   if ((defn != NULL) && defn->is_used()) {
-    __ pushl(defn->locs()->out().reg());
+    Location value = defn->locs()->out();
+    if (value.IsRegister()) {
+      __ pushl(value.reg());
+    } else {
+      ASSERT(value.IsStackSlot());
+      __ pushl(value.ToStackSlotAddress());
+    }
   }
 }
 
@@ -1025,7 +1033,6 @@
     intptr_t extra_slots = StackSize()
         - flow_graph().num_stack_locals()
         - flow_graph().num_copied_params();
-    ASSERT(extra_slots >= 0);
     __ EnterOsrFrame(extra_slots * kWordSize);
   } else {
     ASSERT(StackSize() >= 0);
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 49e259d..7a4a8ba 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1051,7 +1051,6 @@
     intptr_t extra_slots = StackSize()
         - flow_graph().num_stack_locals()
         - flow_graph().num_copied_params();
-    ASSERT(extra_slots >= 0);
     __ EnterOsrFrame(extra_slots * kWordSize);
   } else {
     ASSERT(StackSize() >= 0);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 293ae4f..e59f707 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -723,10 +723,18 @@
 
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  if (is_optimizing()) return;
+  if (is_optimizing()) {
+    return;
+  }
   Definition* defn = instr->AsDefinition();
   if ((defn != NULL) && defn->is_used()) {
-    __ pushq(defn->locs()->out().reg());
+    Location value = defn->locs()->out();
+    if (value.IsRegister()) {
+      __ pushq(value.reg());
+    } else {
+      ASSERT(value.IsStackSlot());
+      __ pushq(value.ToStackSlotAddress());
+    }
   }
 }
 
@@ -1057,7 +1065,6 @@
     intptr_t extra_slots = StackSize()
         - flow_graph().num_stack_locals()
         - flow_graph().num_copied_params();
-    ASSERT(extra_slots >= 0);
     __ EnterOsrFrame(extra_slots * kWordSize, new_pp, new_pc);
   } else {
     ASSERT(StackSize() >= 0);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index d488c48..39b6168 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -178,7 +178,7 @@
 }
 
 
-static const ICData& SpecializeICData(const ICData& ic_data, intptr_t cid) {
+static const ICData& TrySpecializeICData(const ICData& ic_data, intptr_t cid) {
   ASSERT(ic_data.num_args_tested() == 1);
 
   if ((ic_data.NumberOfChecks() == 1) &&
@@ -186,21 +186,23 @@
     return ic_data;  // Nothing to do
   }
 
-  const ICData& new_ic_data = ICData::ZoneHandle(ICData::New(
-      Function::Handle(ic_data.function()),
-      String::Handle(ic_data.target_name()),
-      Object::empty_array(),  // Dummy argument descriptor.
-      ic_data.deopt_id(),
-      ic_data.num_args_tested()));
-  new_ic_data.set_deopt_reason(ic_data.deopt_reason());
-
   const Function& function =
       Function::Handle(ic_data.GetTargetForReceiverClassId(cid));
+  // TODO(fschneider): Try looking up the function on the class if it is
+  // not found in the ICData.
   if (!function.IsNull()) {
+    const ICData& new_ic_data = ICData::ZoneHandle(ICData::New(
+        Function::Handle(ic_data.function()),
+        String::Handle(ic_data.target_name()),
+        Object::empty_array(),  // Dummy argument descriptor.
+        ic_data.deopt_id(),
+        ic_data.num_args_tested()));
+    new_ic_data.set_deopt_reason(ic_data.deopt_reason());
     new_ic_data.AddReceiverCheck(cid, function);
+    return new_ic_data;
   }
 
-  return new_ic_data;
+  return ic_data;
 }
 
 
@@ -216,7 +218,11 @@
     return;  // No information about receiver was infered.
   }
 
-  const ICData& ic_data = SpecializeICData(call->ic_data(), receiver_cid);
+  const ICData& ic_data = TrySpecializeICData(call->ic_data(), receiver_cid);
+  if (ic_data.raw() == call->ic_data().raw()) {
+    // No specialization.
+    return;
+  }
 
   const bool with_checks = false;
   PolymorphicInstanceCallInstr* specialized =
@@ -369,6 +375,10 @@
         curr_instr->ReplaceWith(div_mod, current_iterator());
         other_binop->ReplaceUsesWith(div_mod);
         other_binop->RemoveFromGraph();
+        // Only one merge possible. Because canonicalization happens later,
+        // more candidates are possible.
+        // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod.
+        break;
       }
     }
   }
@@ -415,14 +425,18 @@
         ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(1);
         args->Add(new Value(curr_instr->value()->definition()));
 
-        // Replace with TruncDivMod.
-        MergedMathInstr* div_mod = new MergedMathInstr(
+        // Replace with SinCos.
+        MergedMathInstr* sin_cos = new MergedMathInstr(
             args,
             curr_instr->DeoptimizationTarget(),
             MergedMathInstr::kSinCos);
-        curr_instr->ReplaceWith(div_mod, current_iterator());
-        other_op->ReplaceUsesWith(div_mod);
+        curr_instr->ReplaceWith(sin_cos, current_iterator());
+        other_op->ReplaceUsesWith(sin_cos);
         other_op->RemoveFromGraph();
+        // Only one merge possible. Because canonicalization happens later,
+        // more candidates are possible.
+        // TODO(srdjan): Allow merging of sin/cos into sincos.
+        break;
       }
     }
   }
@@ -4575,12 +4589,9 @@
           }
           if (inputs_loop_invariant &&
               !current->IsAssertAssignable() &&
-              !current->IsAssertBoolean() &&
-              !current->IsGuardField()) {
+              !current->IsAssertBoolean()) {
             // TODO(fschneider): Enable hoisting of Assert-instructions
             // if it safe to do.
-            // TODO(15652): Hoisting guard-field instructions causes the
-            // optimizing compiler to crash.
             Hoist(&it, pre_header, current);
           } else if (current->IsCheckSmi() &&
                      current->InputAt(0)->definition()->IsPhi()) {
@@ -8190,7 +8201,9 @@
     MaterializeObjectInstr* mat = materializations_[i];
     for (intptr_t j = 0; j < mat->InputCount(); j++) {
       Definition* defn = mat->InputAt(j)->definition();
-      if (defn->IsBoxDouble()) {
+      if (defn->IsBoxDouble() ||
+          defn->IsBoxFloat32x4() ||
+          defn->IsBoxInt32x4()) {
         mat->InputAt(j)->BindTo(defn->InputAt(0)->definition());
       }
     }
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index b3d604a..bd78beb 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -8,7 +8,6 @@
 #include "platform/utils.h"
 #include "vm/flags.h"
 #include "vm/heap_histogram.h"
-#include "vm/heap_profiler.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
 #include "vm/object_set.h"
@@ -321,45 +320,6 @@
 }
 
 
-void Heap::Profile(Dart_FileWriteCallback callback, void* stream) const {
-  HeapProfiler profiler(callback, stream);
-
-  // Dump the root set.
-  HeapProfilerRootVisitor root_visitor(&profiler);
-  Isolate* isolate = Isolate::Current();
-  Isolate* vm_isolate = Dart::vm_isolate();
-  isolate->VisitObjectPointers(&root_visitor, false,
-                               StackFrameIterator::kDontValidateFrames);
-  HeapProfilerWeakRootVisitor weak_root_visitor(&root_visitor);
-  isolate->VisitWeakPersistentHandles(&weak_root_visitor, true);
-
-  // Dump the current and VM isolate heaps.
-  HeapProfilerObjectVisitor object_visitor(isolate, &profiler);
-  isolate->heap()->IterateObjects(&object_visitor);
-  vm_isolate->heap()->IterateObjects(&object_visitor);
-}
-
-
-void Heap::ProfileToFile(const char* reason) const {
-  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
-  ASSERT(file_open != NULL);
-  Dart_FileWriteCallback file_write = Isolate::file_write_callback();
-  ASSERT(file_write != NULL);
-  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
-  ASSERT(file_close != NULL);
-  Isolate* isolate = Isolate::Current();
-  const char* format = "%s-%s.hprof";
-  intptr_t len = OS::SNPrint(NULL, 0, format, isolate->name(), reason);
-  char* filename = isolate->current_zone()->Alloc<char>(len + 1);
-  OS::SNPrint(filename, len + 1, format, isolate->name(), reason);
-  void* file = (*file_open)(filename, true);
-  if (file != NULL) {
-    Profile(file_write, file);
-    (*file_close)(file);
-  }
-}
-
-
 const char* Heap::GCReasonToString(GCReason gc_reason) {
   switch (gc_reason) {
     case kNewSpace:
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 2c39e2b..703c265 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -171,10 +171,6 @@
 
   ObjectSet* CreateAllocatedObjectSet() const;
 
-  // Generates a profile of the current and VM isolate heaps.
-  void Profile(Dart_FileWriteCallback callback, void* stream) const;
-  void ProfileToFile(const char* reason) const;
-
   static const char* GCReasonToString(GCReason gc_reason);
 
   // Associate a peer with an object.  A non-existent peer is equal to NULL.
diff --git a/runtime/vm/heap_profiler.cc b/runtime/vm/heap_profiler.cc
deleted file mode 100644
index bdfdd83..0000000
--- a/runtime/vm/heap_profiler.cc
+++ /dev/null
@@ -1,807 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/heap_profiler.h"
-
-#include "vm/dart_api_state.h"
-#include "vm/object.h"
-#include "vm/raw_object.h"
-#include "vm/stack_frame.h"
-#include "vm/unicode.h"
-
-namespace dart {
-
-HeapProfiler::Buffer::~Buffer() {
-  delete[] data_;
-}
-
-
-void HeapProfiler::Buffer::Write(const uint8_t* data, intptr_t size) {
-  EnsureCapacity(size);
-  memmove(&data_[size_], data, size);
-  size_ += size;
-}
-
-
-void HeapProfiler::Buffer::EnsureCapacity(intptr_t size) {
-  if ((size + size_) > capacity_) {
-    intptr_t new_capacity = Utils::RoundUpToPowerOfTwo(capacity_ + size);
-    uint8_t* new_data = new uint8_t[new_capacity];
-    memmove(new_data, data_, size_);
-    capacity_ = new_capacity;
-    delete[] data_;
-    data_ = new_data;
-  }
-}
-
-
-void HeapProfiler::Record::Write(const uint8_t* value, intptr_t size) {
-  body_.Write(value, size);
-}
-
-
-void HeapProfiler::Record::Write8(uint8_t value) {
-  body_.Write(&value, sizeof(value));
-}
-
-
-void HeapProfiler::Record::Write16(uint16_t value) {
-  value = htons(value);
-  body_.Write(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-}
-
-
-void HeapProfiler::Record::Write32(uint32_t value) {
-  value = htonl(value);
-  body_.Write(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-}
-
-
-void HeapProfiler::Record::Write64(uint64_t value) {
-  uint16_t x = 0xFF;
-  if (*reinterpret_cast<uint8_t*>(&x) == 0xFF) {
-    uint64_t hi = static_cast<uint64_t>(htonl(value & 0xFFFFFFFF)) << 32;
-    uint64_t lo = htonl(value >> 32);
-    value = hi | lo;
-  }
-  body_.Write(reinterpret_cast<uint8_t*>(&value), sizeof(value));
-}
-
-
-void HeapProfiler::Record::WriteObjectId(const void* value) {
-  Write64(reinterpret_cast<uint64_t>(value));
-}
-
-
-HeapProfiler::SubRecord::SubRecord(uint8_t sub_tag, HeapProfiler* profiler)
-    : record_(profiler->heap_dump_record_) {
-  record_->Write8(sub_tag);
-}
-
-
-HeapProfiler::SubRecord::~SubRecord() {
-}
-
-
-void HeapProfiler::SubRecord::Write(const uint8_t* value, intptr_t size) {
-  record_->Write(value, size);
-}
-
-
-void HeapProfiler::SubRecord::Write8(uint8_t value) {
-  record_->Write8(value);
-}
-
-
-void HeapProfiler::SubRecord::Write16(uint16_t value) {
-  record_->Write16(value);
-}
-
-
-void HeapProfiler::SubRecord::Write32(uint32_t value) {
-  record_->Write32(value);
-}
-
-
-void HeapProfiler::SubRecord::Write64(uint64_t value) {
-  record_->Write64(value);
-}
-
-
-void HeapProfiler::SubRecord::WriteObjectId(const void* value) {
-  record_->WriteObjectId(value);
-}
-
-
-HeapProfiler::HeapProfiler(Dart_FileWriteCallback callback, void* stream)
-    : write_callback_(callback),
-      output_stream_(stream),
-      heap_dump_record_(NULL) {
-  WriteHeader();
-  WriteStackTrace();
-  WriteFakeLoadClass(kJavaLangClass, "java.lang.Class");
-  WriteFakeLoadClass(kJavaLangClassLoader, "java.lang.ClassLoader");
-  WriteFakeLoadClass(kJavaLangObject, "java.lang.Object");
-  WriteFakeLoadClass(kJavaLangString, "java.lang.String");
-  WriteFakeLoadClass(kArrayObject, "Object[]");
-  WriteFakeLoadClass(kArrayBoolean, "bool[]");
-  WriteFakeLoadClass(kArrayChar, "char[]");
-  WriteFakeLoadClass(kArrayFloat, "float[]");
-  WriteFakeLoadClass(kArrayDouble, "double[]");
-  WriteFakeLoadClass(kArrayByte, "byte[]");
-  WriteFakeLoadClass(kArrayShort, "short[]");
-  WriteFakeLoadClass(kArrayInt, "int[]");
-  WriteFakeLoadClass(kArrayLong, "long[]");
-  heap_dump_record_ = new Record(kHeapDump, this);
-  WriteFakeClassDump(kJavaLangClass, static_cast<FakeClass>(0));
-  WriteFakeClassDump(kJavaLangClassLoader, kJavaLangObject);
-  WriteFakeClassDump(kJavaLangObject, static_cast<FakeClass>(0));
-  WriteFakeClassDump(kJavaLangString, kJavaLangObject);
-}
-
-
-HeapProfiler::~HeapProfiler() {
-  for (std::set<const RawSmi*>::iterator it = smi_table_.begin();
-       it != smi_table_.end();
-       ++it) {
-    WriteSmiInstanceDump(*it);
-  }
-  delete heap_dump_record_;
-}
-
-
-const RawObject* HeapProfiler::ObjectId(const RawObject* raw_obj) {
-  if (!raw_obj->IsHeapObject()) {
-    // To describe an immediate object in HPROF we record its value
-    // and write fake INSTANCE_DUMP subrecord in the HEAP_DUMP record.
-    const RawSmi* raw_smi = reinterpret_cast<const RawSmi*>(raw_obj);
-    if (smi_table_.find(raw_smi) == smi_table_.end()) {
-      smi_table_.insert(raw_smi);
-    }
-  } else if (raw_obj->GetClassId() == kNullCid) {
-    // Instances of the Null type are translated to NULL so they can
-    // be printed as "null" in HAT.
-    return NULL;
-  }
-  return raw_obj;
-}
-
-
-const RawClass* HeapProfiler::ClassId(const RawClass* raw_class) {
-  // A unique LOAD_CLASS record must be written for each class object.
-  if (class_table_.find(raw_class) == class_table_.end()) {
-    class_table_.insert(raw_class);
-    WriteLoadClass(raw_class);
-  }
-  return raw_class;
-}
-
-
-// A built-in class may have its name encoded in a C-string.  These
-// strings should only be found in class objects.  We emit a unique
-// STRING_IN_UTF8 so HAT will properly display the class name.
-const char* HeapProfiler::StringId(const char* c_string) {
-  const RawString* ptr = reinterpret_cast<const RawString*>(c_string);
-  if (string_table_.find(ptr) == string_table_.end()) {
-    string_table_.insert(ptr);
-    WriteStringInUtf8(c_string);
-  }
-  return c_string;
-}
-
-
-const RawString* HeapProfiler::StringId(const RawString* raw_string) {
-  // A unique STRING_IN_UTF8 record must be written for each string
-  // object.
-  if (string_table_.find(raw_string) == string_table_.end()) {
-    string_table_.insert(raw_string);
-    WriteStringInUtf8(raw_string);
-  }
-  return raw_string;
-}
-
-
-const RawClass* HeapProfiler::GetClass(const RawObject* raw_obj) {
-  return Isolate::Current()->class_table()->At(raw_obj->GetClassId());
-}
-
-
-const RawClass* HeapProfiler::GetSuperClass(const RawClass* raw_class) {
-  ASSERT(raw_class != Class::null());
-  const RawAbstractType* super_type = raw_class->ptr()->super_type_;
-  if (super_type == AbstractType::null()) {
-    return Class::null();
-  }
-  while (super_type->GetClassId() == kBoundedTypeCid) {
-    super_type =
-        reinterpret_cast<const RawBoundedType*>(super_type)->ptr()->type_;
-  }
-  ASSERT(super_type->GetClassId() == kTypeCid);
-  return reinterpret_cast<const RawClass*>(
-      reinterpret_cast<const RawType*>(super_type)->ptr()->type_class_);
-}
-
-
-void HeapProfiler::WriteRoot(const RawObject* raw_obj) {
-  SubRecord sub(kRootUnknown, this);
-  sub.WriteObjectId(ObjectId(raw_obj));
-}
-
-
-void HeapProfiler::WriteObject(const RawObject* raw_obj) {
-  ASSERT(raw_obj->IsHeapObject());
-  intptr_t class_id = raw_obj->GetClassId();
-  switch (class_id) {
-    case kFreeListElement: {
-      // Free space has an object-like encoding.  Heap profiles only
-      // care about live objects so we skip over these records.
-      break;
-    }
-    case kClassCid: {
-      const RawClass* raw_class = reinterpret_cast<const RawClass*>(raw_obj);
-      if (raw_class->ptr()->id_ == kFreeListElement) {
-        // Skip over the FreeListElement class.  This class exists to
-        // describe free space.
-        break;
-      }
-      WriteClassDump(raw_class);
-      break;
-    }
-    case kArrayCid:
-    case kImmutableArrayCid: {
-      WriteObjectArrayDump(reinterpret_cast<const RawArray*>(raw_obj));
-      break;
-    }
-    case kTypedDataInt8ArrayCid:
-    case kTypedDataUint8ArrayCid:
-    case kTypedDataUint8ClampedArrayCid: {
-      const RawTypedData* raw_int8_array =
-          reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int8_array, kByte);
-      break;
-    }
-    case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid: {
-      const RawTypedData* raw_int16_array =
-          reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int16_array, kShort);
-      break;
-    }
-    case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid: {
-      const RawTypedData* raw_int32_array =
-          reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int32_array, kInt);
-      break;
-    }
-    case kTypedDataInt64ArrayCid:
-    case kTypedDataUint64ArrayCid: {
-      const RawTypedData* raw_int64_array =
-          reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int64_array, kLong);
-      break;
-    }
-    case kTypedDataFloat32ArrayCid: {
-      const RawTypedData* raw_float32_array =
-          reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_float32_array, kFloat);
-      break;
-    }
-    case kTypedDataFloat64ArrayCid: {
-      const RawTypedData* raw_float64_array =
-          reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_float64_array, kDouble);
-      break;
-    }
-    case kOneByteStringCid:
-    case kTwoByteStringCid:
-    case kExternalOneByteStringCid:
-    case kExternalTwoByteStringCid: {
-      WriteInstanceDump(StringId(reinterpret_cast<const RawString*>(raw_obj)));
-      break;
-    }
-    default:
-      WriteInstanceDump(raw_obj);
-  }
-}
-
-
-void HeapProfiler::Write(const void* data, intptr_t size) {
-  (*write_callback_)(data, size, output_stream_);
-}
-
-
-// Header
-//
-// Format:
-//   [u1]* - format name
-//   u4 - size of identifiers
-//   u4 - high word of number of milliseconds since 0:00 GMT, 1/1/70
-//   u4 - low word of number of milliseconds since 0:00 GMT, 1/1/70
-void HeapProfiler::WriteHeader() {
-  const char magic[] = "JAVA PROFILE 1.0.1";
-  Write(magic, sizeof(magic));
-  uint32_t size = htonl(kObjectIdSize);
-  Write(&size, sizeof(size));
-  uint64_t milliseconds = OS::GetCurrentTimeMillis();
-  uint32_t hi = htonl(
-      static_cast<uint32_t>((milliseconds >> 32) & 0x00000000FFFFFFFF));
-  Write(&hi, sizeof(hi));
-  uint32_t lo = htonl(
-      static_cast<uint32_t>(milliseconds & 0x00000000FFFFFFFF));
-  Write(&lo, sizeof(lo));
-}
-
-
-// Record
-//
-// Format:
-//   u1 - TAG: denoting the type of the record
-//   u4 - TIME: number of microseconds since the time stamp in the header
-//   u4 - LENGTH: number of bytes that follow this u4 field and belong
-//        to this record
-//   [u1]* - BODY: as many bytes as specified in the above u4 field
-void HeapProfiler::WriteRecord(const Record& record) {
-  uint8_t tag = record.Tag();
-  Write(&tag, sizeof(tag));
-  uint32_t time = htonl(record.Time());
-  Write(&time, sizeof(time));
-  uint32_t length = htonl(record.Length());
-  Write(&length, sizeof(length));
-  Write(record.Body(), record.Length());
-}
-
-
-// STRING IN UTF8 - 0x01
-//
-// Format:
-//   ID - ID for this string
-//   [u1]* - UTF8 characters for string (NOT NULL terminated)
-void HeapProfiler::WriteStringInUtf8(const RawString* raw_string) {
-  intptr_t length = 0;
-  char* characters = NULL;
-  intptr_t class_id = raw_string->GetClassId();
-  if (class_id == kOneByteStringCid) {
-    const RawOneByteString* onestr =
-        reinterpret_cast<const RawOneByteString*>(raw_string);
-    for (intptr_t i = 0; i < Smi::Value(onestr->ptr()->length_); ++i) {
-      length += Utf8::Length(onestr->ptr()->data_[i]);
-    }
-    characters = new char[length];
-    for (intptr_t i = 0, j = 0; i < Smi::Value(onestr->ptr()->length_); ++i) {
-      int32_t ch = onestr->ptr()->data_[i];
-      j += Utf8::Encode(ch, &characters[j]);
-    }
-  } else {
-    ASSERT(class_id == kTwoByteStringCid);
-    const RawTwoByteString* twostr =
-        reinterpret_cast<const RawTwoByteString*>(raw_string);
-    for (intptr_t i = 0; i < Smi::Value(twostr->ptr()->length_); ++i) {
-      length += Utf8::Length(twostr->ptr()->data_[i]);
-    }
-    characters = new char[length];
-    for (intptr_t i = 0, j = 0; i < Smi::Value(twostr->ptr()->length_); ++i) {
-      int32_t ch = twostr->ptr()->data_[i];
-      j += Utf8::Encode(ch, &characters[j]);
-    }
-  }
-  Record record(kStringInUtf8, this);
-  record.WriteObjectId(ObjectId(raw_string));
-  for (intptr_t i = 0; i < length; ++i) {
-    record.Write8(characters[i]);
-  }
-  delete[] characters;
-}
-
-
-void HeapProfiler::WriteStringInUtf8(const char* c_string) {
-  Record record(kStringInUtf8, this);
-  record.WriteObjectId(c_string);
-  for (; *c_string != '\0'; ++c_string) {
-    record.Write8(*c_string);
-  }
-}
-
-
-// LOAD CLASS - 0x02
-//
-// Format:
-//   u4 - class serial number (always > 0)
-//   ID - class object ID
-//   u4 - stack trace serial number
-//   ID - class name string ID
-void HeapProfiler::WriteLoadClass(const RawClass* raw_class) {
-  Record record(kLoadClass, this);
-  // class serial number (always > 0)
-  record.Write32(1);
-  // class object ID
-  record.WriteObjectId(raw_class);
-  // stack trace serial number
-  record.Write32(0);
-  // class name string ID
-  if (raw_class->ptr()->name_ != String::null()) {
-    record.WriteObjectId(StringId(raw_class->ptr()->name_));
-  } else {
-    const char* format = "<an unnamed class with id %d>";
-    intptr_t len = OS::SNPrint(NULL, 0, format, raw_class->ptr()->id_);
-    char* str = new char[len + 1];
-    OS::SNPrint(str, len + 1, format, raw_class->ptr()->id_);
-    record.WriteObjectId(StringId(str));
-    delete[] str;
-  }
-}
-
-
-void HeapProfiler::WriteFakeLoadClass(FakeClass fake_class,
-                                      const char* class_name) {
-  Record record(kLoadClass, this);
-  // class serial number (always > 0)
-  record.Write32(1);
-  // class object ID
-  record.WriteObjectId(reinterpret_cast<void*>(fake_class));
-  // stack trace serial number
-  record.Write32(0);
-  // class name string ID
-  record.WriteObjectId(StringId(class_name));
-}
-
-
-// STACK TRACE - 0x05
-//
-//  u4 - stack trace serial number
-//  u4 - thread serial number
-//  u4 - number of frames
-//  [ID]* - series of stack frame ID's
-void HeapProfiler::WriteStackTrace() {
-  Record record(kStackTrace, this);
-  // stack trace serial number
-  record.Write32(0);
-  // thread serial number
-  record.Write32(0);
-  // number of frames
-  record.Write32(0);
-}
-
-
-// HEAP SUMMARY - 0x07
-//
-// Format:
-//   u4 - total live bytes
-//   u4 - total live instances
-//   u8 - total bytes allocated
-//   u8 - total instances allocated
-void HeapProfiler::WriteHeapSummary(uint32_t total_live_bytes,
-                                   uint32_t total_live_instances,
-                                   uint64_t total_bytes_allocated,
-                                   uint64_t total_instances_allocated) {
-  Record record(kHeapSummary, this);
-  record.Write32(total_live_bytes);
-  record.Write32(total_live_instances);
-  record.Write32(total_bytes_allocated);
-  record.Write32(total_instances_allocated);
-}
-
-
-// HEAP DUMP - 0x0C
-//
-// Format:
-//  []*
-void HeapProfiler::WriteHeapDump() {
-  Record record(kHeapDump, this);
-}
-
-
-// CLASS DUMP - 0x20
-//
-// Format:
-//  ID - class object ID
-//  u4 - stack trace serial number
-//  ID - super class object ID
-//  ID - class loader object ID
-//  ID - signers object ID
-//  ID - protection domain object ID
-//  ID - reserved
-//  ID - reserved
-//  u4 - instance size (in bytes)
-//  u2 - size of constant pool and number of records that follow:
-//  u2 - constant pool index
-//  u1 - type of entry: (See Basic Type)
-//  value - value of entry (u1, u2, u4, or u8 based on type of entry)
-//  u2 - Number of static fields:
-//  ID - static field name string ID
-//  u1 - type of field: (See Basic Type)
-//  value - value of entry (u1, u2, u4, or u8 based on type of field)
-//  u2 - Number of instance fields (not including super class's)
-//  ID - field name string ID
-//  u1 - type of field: (See Basic Type)
-void HeapProfiler::WriteClassDump(const RawClass* raw_class) {
-  SubRecord sub(kClassDump, this);
-  // class object ID
-  sub.WriteObjectId(ClassId(raw_class));
-  // stack trace serial number
-  sub.Write32(0);
-  // super class object ID
-  const RawClass* super_class = GetSuperClass(raw_class);
-  if (super_class == Class::null()) {
-    sub.WriteObjectId(NULL);
-  } else {
-    sub.WriteObjectId(ClassId(super_class));
-  }
-  // class loader object ID
-  sub.WriteObjectId(NULL);
-  // signers object ID
-  sub.WriteObjectId(NULL);
-  // protection domain object ID
-  sub.WriteObjectId(NULL);
-  // reserved
-  sub.WriteObjectId(NULL);
-  // reserved
-  sub.WriteObjectId(NULL);
-
-  intptr_t num_static_fields = 0;
-  intptr_t num_instance_fields = 0;
-
-  RawArray* raw_array = raw_class->ptr()->fields_;
-  if (raw_array != Array::null()) {
-    for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) {
-      RawField* raw_field =
-          reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]);
-      if (Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) {
-        ++num_static_fields;
-      } else {
-        ++num_instance_fields;
-      }
-    }
-  }
-  // instance size (in bytes)
-  intptr_t instance_size_in_words = raw_class->ptr()->instance_size_in_words_;
-  if (instance_size_in_words == 0) {
-    // TODO(iposva): Better accounting of variable sized VM classes.
-    instance_size_in_words = num_instance_fields;
-  }
-  sub.Write32(instance_size_in_words * kWordSize);
-  // size of constant pool and number of records that follow:
-  sub.Write16(0);
-  // Number of static fields
-  sub.Write16(num_static_fields);
-  // Static fields:
-  if (raw_array != Array::null()) {
-    for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) {
-      RawField* raw_field =
-          reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]);
-      if (Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) {
-        ASSERT(raw_field->ptr()->name_ != String::null());
-        // static field name string ID
-        sub.WriteObjectId(StringId(raw_field->ptr()->name_));
-        // type of static field
-        sub.Write8(kObject);
-        // value of entry
-        sub.WriteObjectId(ObjectId(raw_field->ptr()->value_));
-      }
-    }
-  }
-  // Number of instance fields (not include super class's)
-  sub.Write16(num_instance_fields);
-  // Instance fields:
-  if (raw_array != Array::null()) {
-    for (intptr_t i = 0; i < Smi::Value(raw_array->ptr()->length_); ++i) {
-      RawField* raw_field =
-          reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]);
-      if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) {
-        ASSERT(raw_field->ptr()->name_ != String::null());
-        // field name string ID
-        sub.WriteObjectId(StringId(raw_field->ptr()->name_));
-        // type of field
-        sub.Write8(kObject);
-      }
-    }
-  }
-}
-
-void HeapProfiler::WriteFakeClassDump(FakeClass fake_class,
-                                      FakeClass fake_super_class) {
-  SubRecord sub(kClassDump, this);
-  // class object ID
-  sub.WriteObjectId(reinterpret_cast<void*>(fake_class));
-  // stack trace serial number
-  sub.Write32(0);
-  // super class object ID
-  sub.WriteObjectId(reinterpret_cast<void*>(fake_super_class));
-  // class loader object ID
-  sub.WriteObjectId(NULL);
-  // signers object ID
-  sub.WriteObjectId(NULL);
-  // protection domain object ID
-  sub.WriteObjectId(NULL);
-  // reserved
-  sub.WriteObjectId(NULL);
-  // reserved
-  sub.WriteObjectId(NULL);
-  // instance size (in bytes)
-  sub.Write32(0);
-  // size of constant pool and number of records that follow:
-  sub.Write16(0);
-  // Number of static fields
-  sub.Write16(0);
-  // Number of instance fields (not include super class's)
-  sub.Write16(0);
-}
-
-
-
-// INSTANCE DUMP - 0x21
-//
-// Format:
-//  ID - object ID
-//  u4 - stack trace serial number
-//  ID - class object ID
-//  u4 - number of bytes that follow
-//  [value]* - instance field values (this class, followed by super class, etc)
-void HeapProfiler::WriteInstanceDump(const RawObject* raw_obj) {
-  ASSERT(raw_obj->IsHeapObject());
-  SubRecord sub(kInstanceDump, this);
-  // object ID
-  sub.WriteObjectId(raw_obj);
-  // stack trace serial number
-  sub.Write32(0);
-  // class object ID
-  sub.WriteObjectId(ClassId(GetClass(raw_obj)));
-  // number of bytes that follow
-  intptr_t num_instance_fields = 0;
-  for (const RawClass* cls = GetClass(raw_obj);
-       cls != Class::null();
-       cls = GetSuperClass(cls)) {
-    RawArray* raw_array = cls->ptr()->fields_;
-    if (raw_array != Array::null()) {
-      intptr_t length = Smi::Value(raw_array->ptr()->length_);
-      for (intptr_t i = 0; i < length; ++i) {
-        RawField* raw_field =
-            reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]);
-        if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) {
-          ++num_instance_fields;
-        }
-      }
-    }
-  }
-  int64_t num_instance_bytes = num_instance_fields * kObjectIdSize;
-  ASSERT(num_instance_bytes <= kMaxUint32);
-  sub.Write32(num_instance_bytes);
-  // instance field values (this class, followed by super class, etc)
-  for (const RawClass* cls = GetClass(raw_obj);
-       cls != Class::null();
-       cls = GetSuperClass(cls)) {
-    RawArray* raw_array = cls->ptr()->fields_;
-    if (raw_array != Array::null()) {
-      intptr_t length = Smi::Value(raw_array->ptr()->length_);
-      uint8_t* base = reinterpret_cast<uint8_t*>(raw_obj->ptr());
-      for (intptr_t i = 0; i < length; ++i) {
-        RawField* raw_field =
-            reinterpret_cast<RawField*>(raw_array->ptr()->data()[i]);
-        if (!Field::StaticBit::decode(raw_field->ptr()->kind_bits_)) {
-          intptr_t offset_in_words =
-              Smi::Value(reinterpret_cast<RawSmi*>(raw_field->ptr()->value_));
-          intptr_t offset = offset_in_words * kWordSize;
-          RawObject* ptr = *reinterpret_cast<RawObject**>(base + offset);
-          sub.WriteObjectId(ObjectId(ptr));
-        }
-      }
-    }
-  }
-}
-
-
-// Write a specialized instance dump for "referenced" Smi objects.
-void HeapProfiler::WriteSmiInstanceDump(const RawSmi* raw_smi) {
-  ASSERT(!raw_smi->IsHeapObject());
-  SubRecord sub(kInstanceDump, this);
-  // object ID
-  sub.WriteObjectId(raw_smi);
-  // stack trace serial number
-  sub.Write32(0);
-  // class object ID
-  sub.WriteObjectId(Isolate::Current()->class_table()->At(kSmiCid));
-  // number of bytes that follow
-  sub.Write32(0);
-}
-
-
-// OBJECT ARRAY DUMP - 0x22
-//
-// Format:
-//  ID - array object ID
-//  u4 - stack trace serial number
-//  u4 - number of elements
-//  ID - array class object ID
-//  [ID]* - elements
-void HeapProfiler::WriteObjectArrayDump(const RawArray* raw_array) {
-  SubRecord sub(kObjectArrayDump, this);
-  // array object ID
-  sub.WriteObjectId(raw_array);
-  // stack trace serial number
-  sub.Write32(0);
-  // number of elements
-  intptr_t length = Smi::Value(raw_array->ptr()->length_);
-  sub.Write32(length);
-  // array class object ID
-  sub.WriteObjectId(reinterpret_cast<void*>(kArrayObject));
-  // elements
-  for (intptr_t i = 0; i < length; ++i) {
-    sub.WriteObjectId(ObjectId(raw_array->ptr()->data()[i]));
-  }
-}
-
-
-// PRIMITIVE ARRAY DUMP - 0x23
-//
-// Format:
-//  ID - array object ID
-//  u4 - stack trace serial number
-//  u4 - number of elements
-//  u1 - element type
-//  [u1]* - elements
-void HeapProfiler::WritePrimitiveArrayDump(const RawTypedData* raw_byte_array,
-                                           uint8_t tag) {
-  SubRecord sub(kPrimitiveArrayDump, this);
-  // array object ID
-  sub.WriteObjectId(raw_byte_array);
-  // stack trace serial number
-  sub.Write32(0);
-  // number of elements
-  intptr_t length = Smi::Value(raw_byte_array->ptr()->length_);
-  const void* data = &(raw_byte_array->ptr()->data_[0]);
-  sub.Write32(length);
-  // element type
-  sub.Write8(tag);
-  // elements (packed)
-  for (intptr_t i = 0; i < length; ++i) {
-    if (tag == kByte) {
-      sub.Write8(reinterpret_cast<const int8_t*>(data)[i]);
-    } else if (tag == kShort) {
-      sub.Write16(reinterpret_cast<const int16_t*>(data)[i]);
-      break;
-    } else if (tag == kInt || tag == kFloat) {
-      sub.Write32(reinterpret_cast<const int32_t*>(data)[i]);
-    } else {
-      ASSERT(tag == kLong || tag == kDouble);
-      sub.Write64(reinterpret_cast<const int64_t*>(data)[i]);
-    }
-  }
-}
-
-
-void HeapProfilerRootVisitor::VisitPointers(RawObject** first,
-                                           RawObject** last) {
-  for (RawObject** current = first; current <= last; current++) {
-    RawObject* raw_obj = *current;
-    if (raw_obj->IsHeapObject()) {
-      // Skip visits of FreeListElements.
-      if (raw_obj->GetClassId() == kFreeListElement) {
-        // Only the class of the free list element should ever be visited.
-        ASSERT(first == last);
-        return;
-      }
-      uword obj_addr = RawObject::ToAddr(raw_obj);
-      if (!Isolate::Current()->heap()->Contains(obj_addr) &&
-          !Dart::vm_isolate()->heap()->Contains(obj_addr)) {
-        FATAL1("Invalid object pointer encountered %#" Px "\n", obj_addr);
-      }
-    }
-    profiler_->WriteRoot(raw_obj);
-  }
-}
-
-
-void HeapProfilerWeakRootVisitor::VisitHandle(uword addr) {
-  FinalizablePersistentHandle* handle =
-      reinterpret_cast<FinalizablePersistentHandle*>(addr);
-  RawObject* raw_obj = handle->raw();
-  visitor_->VisitPointer(&raw_obj);
-}
-
-
-void HeapProfilerObjectVisitor::VisitObject(RawObject* raw_obj) {
-  profiler_->WriteObject(raw_obj);
-}
-
-}  // namespace dart
diff --git a/runtime/vm/heap_profiler.h b/runtime/vm/heap_profiler.h
deleted file mode 100644
index 117b46f..0000000
--- a/runtime/vm/heap_profiler.h
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_HEAP_PROFILER_H_
-#define VM_HEAP_PROFILER_H_
-
-#include <set>
-
-#include "include/dart_api.h"
-#include "vm/globals.h"
-#include "vm/handles.h"
-#include "vm/object.h"
-#include "vm/visitor.h"
-
-namespace dart {
-
-// A HeapProfiler writes a snapshot of the heap for off-line analysis.
-// The heap is written in binary HPROF format, which is a sequence of
-// self describing records.  A description of the HPROF format can be
-// found at
-//
-// http://java.net/downloads/heap-snapshot/hprof-binary-format.html
-//
-// HPROF was not designed for Dart, but most Dart concepts can be
-// mapped directly into HPROF.  Some features, such as immediate
-// objects and variable length objects, require a translation.
-class HeapProfiler {
- public:
-  enum Tag {
-    kStringInUtf8 = 0x01,
-    kLoadClass = 0x02,
-    kUnloadClass = 0x03,
-    kStackFrame = 0x04,
-    kStackTrace = 0x05,
-    kAllocSites = 0x06,
-    kHeapSummary = 0x07,
-    kStartThread = 0x0A,
-    kEndThread = 0x0B,
-    kHeapDump = 0x0C,
-    kCpuSamples = 0x0D,
-    kControlSettings = 0x0E,
-    kHeapDumpSummary = 0x1C,
-    kHeapDumpEnd = 0x2C
-  };
-
-  // Sub-record tags describe sub-records within a heap dump.
-  enum Subtag {
-    kRootJniGlobal = 0x01,
-    kRootJniLocal = 0x01,
-    kRootJavaFrame = 0x03,
-    kRootNativeStack = 0x04,
-    kRootStickyClass = 0x05,
-    kRootThreadBlock = 0x06,
-    kRootMonitorUsed = 0x07,
-    kRootThreadObject = 0x08,
-    kClassDump = 0x20,
-    kInstanceDump = 0x21,
-    kObjectArrayDump = 0x22,
-    kPrimitiveArrayDump = 0x23,
-    kRootUnknown = 0xFF
-  };
-
-  // Tags for describing element and field types.
-  enum BasicType {
-    kObject = 2,
-    kBoolean = 4,
-    kChar = 5,
-    kFloat = 6,
-    kDouble = 7,
-    kByte = 8,
-    kShort = 9,
-    kInt = 10,
-    kLong = 11
-  };
-
-  // Object ids for fake classes.
-  //
-  // While not necessary to describe Dart programs, third party tools
-  // expect these types.  These tools also interpret id values as raw
-  // addresses so we space them by 8 to not look like compressed oops.
-  enum FakeClass {
-    kJavaLangClass = 1,
-    kJavaLangClassLoader = 9,
-    kJavaLangObject = 17,
-    kJavaLangString = 25,
-    kArrayObject = 33,
-    kArrayBoolean = 41,
-    kArrayChar = 49,
-    kArrayFloat = 57,
-    kArrayDouble = 65,
-    kArrayByte = 73,
-    kArrayShort = 81,
-    kArrayInt = 89,
-    kArrayLong = 97
-  };
-
-  static const int kObjectIdSize = sizeof(uint64_t);  // NOLINT
-
-  HeapProfiler(Dart_FileWriteCallback callback, void* stream);
-  ~HeapProfiler();
-
-  // Writes a root to the heap dump.
-  void WriteRoot(const RawObject* raw_obj);
-
-  // Writes a object to the heap dump.
-  void WriteObject(const RawObject* raw_obj);
-
- private:
-  // Record tags describe top-level records.
-  // A growable array of bytes used to build a record body.
-  class Buffer {
-   public:
-    Buffer() : data_(0), size_(0), capacity_(0) {
-    }
-    ~Buffer();
-
-    // Writes an array of bytes to the buffer, increasing the capacity
-    // as needed.
-    void Write(const uint8_t* data, intptr_t length);
-
-    // Returns the underlying element storage.
-    const uint8_t* Data() const {
-      return data_;
-    }
-
-    // Returns the number of elements written to the buffer.
-    intptr_t Size() const {
-      return size_;
-    }
-
-   private:
-    // Resizes the element storage, if needed.
-    void EnsureCapacity(intptr_t size);
-
-    uint8_t* data_;
-
-    intptr_t size_;
-
-    // Size of the element storage.
-    intptr_t capacity_;
-
-    DISALLOW_COPY_AND_ASSIGN(Buffer);
-  };
-
-  // A top-level data record.
-  class Record {
-   public:
-    Record(uint8_t tag, HeapProfiler* profiler)
-        : tag_(tag), profiler_(profiler) {
-    }
-    ~Record() {
-      profiler_->WriteRecord(*this);
-    }
-
-    // Returns the tag describing the record format.
-    uint8_t Tag() const {
-      return tag_;
-    }
-
-    // Returns a millisecond time delta, always 0.
-    uint8_t Time() const {
-      return 0;
-    }
-
-    // Returns the record length in bytes.
-    uint32_t Length() const {
-      return body_.Size();
-    }
-
-    // Returns the record body.
-    const uint8_t* Body() const {
-      return body_.Data();
-    }
-
-    // Appends an array of 8-bit values to the record body.
-    void Write(const uint8_t* value, intptr_t size);
-
-    // Appends an 8-, 16-, 32- or 64-bit value to the body in
-    // big-endian format.
-    void Write8(uint8_t value);
-    void Write16(uint16_t value);
-    void Write32(uint32_t value);
-    void Write64(uint64_t value);
-
-    // Appends an ID to the body.
-    void WriteObjectId(const void* value);
-
-   private:
-    // A tag value that describes the record format.
-    uint8_t tag_;
-
-    // The payload of the record as described by the tag.
-    Buffer body_;
-
-    // Parent object.
-    HeapProfiler* profiler_;
-
-    DISALLOW_COPY_AND_ASSIGN(Record);
-  };
-
-  // A sub-record within a heap dump record.  Write calls are
-  // forwarded to the profilers heap dump record instance.
-  class SubRecord {
-   public:
-    // Starts a new sub-record within the heap dump record.
-    SubRecord(uint8_t sub_tag, HeapProfiler* profiler);
-    ~SubRecord();
-
-    // Appends an array of 8-bit values to the heap dump record.
-    void Write(const uint8_t* value, intptr_t size);
-
-    // Appends an 8-, 16-, 32- or 64-bit value to the heap dump
-    // record.
-    void Write8(uint8_t value);
-    void Write16(uint16_t value);
-    void Write32(uint32_t value);
-    void Write64(uint64_t value);
-
-    // Appends an ID to the current heap dump record.
-    void WriteObjectId(const void* value);
-
-   private:
-    // The record instance that receives forwarded write calls.
-    Record* record_;
-  };
-
-  // Id canonizers.
-  const RawClass* ClassId(const RawClass* raw_class);
-  const RawObject* ObjectId(const RawObject* raw_obj);
-  const char* StringId(const char* c_string);
-  const RawString* StringId(const RawString* raw_string);
-
-  // Invokes the write callback.
-  void Write(const void* data, intptr_t size);
-
-  // Writes the binary hprof header to the output stream.
-  void WriteHeader();
-
-  // Writes a record to the output stream.
-  void WriteRecord(const Record& record);
-
-  // Writes a string in utf-8 record to the output stream.
-  void WriteStringInUtf8(const char* c_string);
-  void WriteStringInUtf8(const RawString* raw_string);
-
-  // Writes a load class record to the output stream.
-  void WriteLoadClass(const RawClass* raw_class);
-  void WriteFakeLoadClass(FakeClass fake_class, const char* class_name);
-
-  // Writes an empty stack trace to the output stream.
-  void WriteStackTrace();
-
-  // Writes a heap summary record to the output stream.
-  void WriteHeapSummary(uint32_t total_live_bytes,
-                        uint32_t total_live_instances,
-                        uint64_t total_bytes_allocated,
-                        uint64_t total_instances_allocated);
-
-  // Writes a heap dump record to the output stream.
-  void WriteHeapDump();
-
-  // Writes a sub-record to the heap dump record.
-  void WriteClassDump(const RawClass* raw_class);
-  void WriteFakeClassDump(FakeClass fake_class, FakeClass fake_super_class);
-  void WriteInstanceDump(const RawObject* raw_obj);
-  void WriteSmiInstanceDump(const RawSmi* raw_smi);
-  void WriteObjectArrayDump(const RawArray* raw_array);
-  void WritePrimitiveArrayDump(const RawTypedData* raw_byte_array, uint8_t tag);
-
-  static const RawClass* GetClass(const RawObject* raw_obj);
-  static const RawClass* GetSuperClass(const RawClass* raw_class);
-
-  Dart_FileWriteCallback write_callback_;
-
-  void* output_stream_;
-
-  Record* heap_dump_record_;
-
-  std::set<const RawSmi*> smi_table_;
-  std::set<const RawClass*> class_table_;
-  std::set<const RawString*> string_table_;
-
-  DISALLOW_COPY_AND_ASSIGN(HeapProfiler);
-};
-
-
-// Writes a root sub-record to the heap dump for every strong handle.
-class HeapProfilerRootVisitor : public ObjectPointerVisitor {
- public:
-  explicit HeapProfilerRootVisitor(HeapProfiler* profiler)
-      : ObjectPointerVisitor(Isolate::Current()),
-        profiler_(profiler) {
-  }
-
-  virtual void VisitPointers(RawObject** first, RawObject** last);
-
- private:
-  HeapProfiler* profiler_;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(HeapProfilerRootVisitor);
-};
-
-
-// Writes a root sub-record to the heap dump for every weak handle.
-class HeapProfilerWeakRootVisitor : public HandleVisitor {
- public:
-  explicit HeapProfilerWeakRootVisitor(HeapProfilerRootVisitor* visitor)
-      : visitor_(visitor) {
-  }
-
-  virtual void VisitHandle(uword addr);
-
- private:
-  HeapProfilerRootVisitor* visitor_;
-  DISALLOW_COPY_AND_ASSIGN(HeapProfilerWeakRootVisitor);
-};
-
-
-// Writes a sub-record to the heap dump for every object in the heap.
-class HeapProfilerObjectVisitor : public ObjectVisitor {
- public:
-  HeapProfilerObjectVisitor(Isolate* isolate, HeapProfiler* profiler)
-      : ObjectVisitor(isolate), profiler_(profiler) {
-  }
-
-  virtual void VisitObject(RawObject* obj);
-
- private:
-  HeapProfiler* profiler_;
-  DISALLOW_COPY_AND_ASSIGN(HeapProfilerObjectVisitor);
-};
-
-}  // namespace dart
-
-#endif  // VM_HEAP_PROFILER_H_
diff --git a/runtime/vm/heap_profiler_test.cc b/runtime/vm/heap_profiler_test.cc
deleted file mode 100644
index c7cf66e..0000000
--- a/runtime/vm/heap_profiler_test.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/assert.h"
-#include "vm/heap_profiler.h"
-#include "vm/growable_array.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-static void WriteCallback(const void* data, intptr_t length, void* stream) {
-  GrowableArray<uint8_t>* array =
-      reinterpret_cast<GrowableArray<uint8_t>*>(stream);
-  for (intptr_t i = 0; i < length; ++i) {
-    array->Add(reinterpret_cast<const uint8_t*>(data)[i]);
-  }
-}
-
-
-static uint8_t Read8(GrowableArray<uint8_t>* array, intptr_t* i) {
-  EXPECT(array != NULL);
-  EXPECT(i != NULL);
-  EXPECT_LE(*i + 1, array->length());
-  return (*array)[(*i)++];
-}
-
-
-static uint32_t Read32(GrowableArray<uint8_t>* array, intptr_t* i) {
-  EXPECT(array != NULL);
-  EXPECT(i != NULL);
-  EXPECT_LE(*i + 4, array->length());
-  uint32_t result = 0;
-  result |= ((*array)[(*i)++] <<  0);
-  result |= ((*array)[(*i)++] <<  8);
-  result |= ((*array)[(*i)++] << 16);
-  result |= ((*array)[(*i)++] << 24);
-  return ntohl(result);
-}
-
-
-static bool IsTagValid(uint8_t tag) {
-  switch (static_cast<HeapProfiler::Tag>(tag)) {
-    case HeapProfiler::kStringInUtf8:
-    case HeapProfiler::kLoadClass:
-    case HeapProfiler::kUnloadClass:
-    case HeapProfiler::kStackFrame:
-    case HeapProfiler::kStackTrace:
-    case HeapProfiler::kAllocSites:
-    case HeapProfiler::kHeapSummary:
-    case HeapProfiler::kStartThread:
-    case HeapProfiler::kEndThread:
-    case HeapProfiler::kHeapDump:
-    case HeapProfiler::kCpuSamples:
-    case HeapProfiler::kControlSettings:
-    case HeapProfiler::kHeapDumpSummary:
-    case HeapProfiler::kHeapDumpEnd:
-      return true;
-    default:
-      return false;
-  }
-}
-
-
-// Write an empty profile.  Validate the presence of a header and a
-// minimal set of records.
-TEST_CASE(HeapProfileEmpty) {
-  uint64_t before = OS::GetCurrentTimeMillis();
-  GrowableArray<uint8_t> array;
-  {
-    HeapProfiler(WriteCallback, &array);
-  }
-  uint64_t after = OS::GetCurrentTimeMillis();
-  intptr_t i = 0;
-  EXPECT_LE(i + 19, array.length());
-  EXPECT_EQ('J', array[i++]);
-  EXPECT_EQ('A', array[i++]);
-  EXPECT_EQ('V', array[i++]);
-  EXPECT_EQ('A', array[i++]);
-  EXPECT_EQ(' ', array[i++]);
-  EXPECT_EQ('P', array[i++]);
-  EXPECT_EQ('R', array[i++]);
-  EXPECT_EQ('O', array[i++]);
-  EXPECT_EQ('F', array[i++]);
-  EXPECT_EQ('I', array[i++]);
-  EXPECT_EQ('L', array[i++]);
-  EXPECT_EQ('E', array[i++]);
-  EXPECT_EQ(' ', array[i++]);
-  EXPECT_EQ('1', array[i++]);
-  EXPECT_EQ('.', array[i++]);
-  EXPECT_EQ('0', array[i++]);
-  EXPECT_EQ('.', array[i++]);
-  EXPECT_EQ('1', array[i++]);
-  EXPECT_EQ('\0', array[i++]);
-  uint32_t size = Read32(&array, &i);
-  EXPECT_EQ(8u, size);
-  uint64_t hi = Read32(&array, &i);
-  uint64_t lo = Read32(&array, &i);
-  uint64_t time = (hi << 32) | lo;
-  EXPECT_LE(before, time);
-  EXPECT_GE(after, time);
-  while (i != array.length()) {
-    // Check tag
-    uint8_t tag = Read8(&array, &i);
-    EXPECT(IsTagValid(tag));
-    // Check time diff
-    uint32_t time_diff = Read32(&array, &i);
-    EXPECT_LE(before, time + time_diff);
-    EXPECT_GE(after, time + time_diff);
-    // Check length diff
-    uint32_t length = Read32(&array, &i);
-    EXPECT_LE((intptr_t)length + i , array.length());
-    // skip body
-    i += length;
-  }
-}
-
-}  // namespace dart
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 1121281..68d8201 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -298,8 +298,7 @@
       initial_definitions_(),
       osr_id_(osr_id),
       entry_count_(0),
-      spill_slot_count_(0),
-      fixed_slot_count_(0) {
+      spill_slot_count_(0) {
 }
 
 
@@ -379,7 +378,7 @@
   return (library.raw() == Library::CoreLibrary())
       || (library.raw() == Library::MathLibrary())
       || (library.raw() == Library::TypedDataLibrary())
-      || (library.raw() == Library::CollectionDevLibrary());
+      || (library.raw() == Library::InternalLibrary());
 }
 
 
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 2c7bcb4..c445a79 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -177,7 +177,7 @@
   V(_TypedList, get:length, TypedDataLength, 26646119)                         \
   V(_GrowableList, get:length, GrowableArrayLength, 1654255033)                \
   V(_StringBase, get:length, StringBaseLength, 1483549854)                     \
-  V(ListIterator, moveNext, ListIteratorMoveNext, 881367324)                   \
+  V(ListIterator, moveNext, ListIteratorMoveNext, 2062984847)                  \
   V(_GrowableList, get:iterator, GrowableArrayIterator, 1155241039)            \
   V(_GrowableList, forEach, GrowableArrayForEach, 195359970)                   \
 
@@ -1416,14 +1416,6 @@
     spill_slot_count_ = count;
   }
 
-  // Number of stack slots reserved for compiling try-catch. For functions
-  // without try-catch, this is 0. Otherwise, it is the number of local
-  // variables.
-  intptr_t fixed_slot_count() const { return fixed_slot_count_; }
-  void set_fixed_slot_count(intptr_t count) {
-    ASSERT(count >= 0);
-    fixed_slot_count_ = count;
-  }
   TargetEntryInstr* normal_entry() const { return normal_entry_; }
 
   const ParsedFunction& parsed_function() const {
@@ -1447,7 +1439,6 @@
   const intptr_t osr_id_;
   intptr_t entry_count_;
   intptr_t spill_slot_count_;
-  intptr_t fixed_slot_count_;  // For try-catch in optimized code.
 
   DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
 };
@@ -4035,6 +4026,16 @@
     return (*values_)[i];
   }
 
+  // SelectRepresentations pass is run once more while MaterializeObject
+  // instructions are still in the graph. To avoid any redundant boxing
+  // operations inserted by that pass we should indicate that this
+  // instruction can cope with any representation as it is essentially
+  // an environment use.
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(0 <= idx && idx < InputCount());
+    return kNoRepresentation;
+  }
+
   virtual bool CanDeoptimize() const { return false; }
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index fe0c840..56338e1 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -103,15 +103,18 @@
 
 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 0;
+  const intptr_t stack_index = (local().index() < 0)
+      ? kFirstLocalSlotFromFp - local().index()
+      : kParamEndSlotFromFp - local().index();
   return LocationSummary::Make(kNumInputs,
-                               Location::RequiresRegister(),
+                               Location::StackSlot(stack_index),
                                LocationSummary::kNoCall);
 }
 
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register result = locs()->out().reg();
-  __ movl(result, Address(EBP, local().index() * kWordSize));
+  ASSERT(!compiler->is_optimizing());
+  // Nothing to do.
 }
 
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index d2030e6..89cc028 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -186,15 +186,18 @@
 
 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
   const intptr_t kNumInputs = 0;
+  const intptr_t stack_index = (local().index() < 0)
+      ? kFirstLocalSlotFromFp - local().index()
+      : kParamEndSlotFromFp - local().index();
   return LocationSummary::Make(kNumInputs,
-                               Location::RequiresRegister(),
+                               Location::StackSlot(stack_index),
                                LocationSummary::kNoCall);
 }
 
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register result = locs()->out().reg();
-  __ movq(result, Address(RBP, local().index() * kWordSize));
+  ASSERT(!compiler->is_optimizing());
+  // Nothing to do.
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 56e8cd7..535398e 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -143,7 +143,7 @@
 
   bool success = true;
   if (message->IsOOB()) {
-    Service::HandleServiceMessage(isolate_, msg);
+    Service::HandleIsolateMessage(isolate_, msg);
   } else {
     const Object& result = Object::Handle(
         DartLibraryCalls::HandleMessage(receive_port, msg));
@@ -731,6 +731,7 @@
     // Finalize any weak persistent handles with a non-null referent.
     FinalizeWeakPersistentHandlesVisitor visitor;
     api_state()->weak_persistent_handles().VisitHandles(&visitor);
+    api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor);
 
     CompilerStats::Print();
     if (FLAG_trace_isolates) {
@@ -760,7 +761,7 @@
 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL;
 Dart_EntropySource Isolate::entropy_source_callback_ = NULL;
 Dart_IsolateInterruptCallback Isolate::vmstats_callback_ = NULL;
-
+Dart_ServiceIsolateCreateCalback Isolate::service_create_callback_ = NULL;
 
 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                   bool visit_prologue_weak_handles,
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 05faacf..08dd50b 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -299,6 +299,13 @@
     return create_callback_;
   }
 
+  static void SetServiceCreateCallback(Dart_ServiceIsolateCreateCalback cb) {
+    service_create_callback_ = cb;
+  }
+  static Dart_ServiceIsolateCreateCalback ServiceCreateCallback() {
+    return service_create_callback_;
+  }
+
   static void SetInterruptCallback(Dart_IsolateInterruptCallback cb) {
     interrupt_callback_ = cb;
   }
@@ -479,6 +486,7 @@
   static Dart_FileCloseCallback file_close_callback_;
   static Dart_EntropySource entropy_source_callback_;
   static Dart_IsolateInterruptCallback vmstats_callback_;
+  static Dart_ServiceIsolateCreateCalback service_create_callback_;
 
   friend class ReusableHandleScope;
   friend class ReusableObjectHandleScope;
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index ee39fb0..2bb21c7 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -40,7 +40,7 @@
   // Setup the internal library's 'internalPrint' function.
   // Necessary because asynchronous errors use "print" to print their
   // stack trace.
-  Dart_Handle url = NewString("dart:_collection-dev");
+  Dart_Handle url = NewString("dart:_internal");
   DART_CHECK_VALID(url);
   Dart_Handle internal_lib = Dart_LookupLibrary(url);
   DART_CHECK_VALID(internal_lib);
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 2116a4d..8dd4a01 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -10,13 +10,15 @@
 
 namespace dart {
 
-JSONStream::JSONStream(intptr_t buf_size) : buffer_(buf_size) {
-  open_objects_ = 0;
-  arguments_ = NULL;
-  num_arguments_ = 0;
-  option_keys_ = NULL;
-  option_values_ = NULL;
-  num_options_ = 0;
+JSONStream::JSONStream(intptr_t buf_size)
+    : open_objects_(0),
+      buffer_(buf_size),
+      reply_port_(ILLEGAL_PORT),
+      arguments_(NULL),
+      num_arguments_(0),
+      option_keys_(NULL),
+      option_values_(NULL),
+      num_options_(0) {
 }
 
 
@@ -181,6 +183,11 @@
 }
 
 
+void JSONStream::set_reply_port(Dart_Port port) {
+  reply_port_ = port;
+}
+
+
 void JSONStream::SetArguments(const char** arguments, intptr_t num_arguments) {
   arguments_ = arguments;
   num_arguments_ = num_arguments;
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 9546498..8966b04 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -5,6 +5,7 @@
 #ifndef VM_JSON_STREAM_H_
 #define VM_JSON_STREAM_H_
 
+#include "include/dart_api.h"  // for Dart_Port
 #include "platform/json.h"
 #include "vm/allocation.h"
 
@@ -25,10 +26,13 @@
   TextBuffer* buffer() { return &buffer_; }
   const char* ToCString() { return buffer_.buf(); }
 
+  void set_reply_port(Dart_Port port);
   void SetArguments(const char** arguments, intptr_t num_arguments);
   void SetOptions(const char** option_keys, const char** option_values,
                   intptr_t num_options);
 
+  Dart_Port reply_port() const { return reply_port_; }
+
   intptr_t num_arguments() const { return num_arguments_; }
   const char* GetArgument(intptr_t i) const {
     return arguments_[i];
@@ -77,6 +81,7 @@
 
   intptr_t open_objects_;
   TextBuffer buffer_;
+  Dart_Port reply_port_;
   const char** arguments_;
   intptr_t num_arguments_;
   const char** option_keys_;
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 9ff6f7f..7dd91bf 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -80,20 +80,6 @@
 }
 
 
-// --- Heap Profiler ---
-
-DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_FileWriteCallback callback,
-                                         void* stream) {
-  Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  if (callback == NULL) {
-    RETURN_NULL_ERROR(callback);
-  }
-  isolate->heap()->Profile(callback, stream);
-  return Api::Success();
-}
-
-
 // --- Verification tools ---
 
 static void CompileAll(Isolate* isolate, Dart_Handle* result) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 98e442d..7111409 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2160,8 +2160,6 @@
 void Class::set_super_type(const AbstractType& value) const {
   ASSERT(value.IsNull() ||
          (value.IsType() && !value.IsDynamicType()) ||
-         value.IsTypeRef() ||
-         value.IsBoundedType() ||
          value.IsMixinAppType());
   StorePointer(&raw_ptr()->super_type_, value.raw());
 }
@@ -3595,7 +3593,7 @@
 }
 
 
-bool AbstractTypeArguments::IsInstantiated() const {
+bool AbstractTypeArguments::IsInstantiated(GrowableObjectArray* trail) const {
   // AbstractTypeArguments is an abstract class.
   UNREACHABLE();
   return false;
@@ -3673,7 +3671,8 @@
 }
 
 
-bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const {
+bool AbstractTypeArguments::IsEquivalent(const AbstractTypeArguments& other,
+                                         GrowableObjectArray* trail) const {
   if (this->raw() == other.raw()) {
     return true;
   }
@@ -3689,7 +3688,7 @@
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
     other_type = other.TypeAt(i);
-    if (!type.Equals(other_type)) {
+    if (!type.IsEquivalent(other_type, trail)) {
       return false;
     }
   }
@@ -3699,7 +3698,8 @@
 
 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
   // AbstractTypeArguments is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -3808,13 +3808,12 @@
 }
 
 
-bool TypeArguments::IsInstantiated() const {
+bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const {
   AbstractType& type = AbstractType::Handle();
   const intptr_t num_types = Length();
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
-    ASSERT(!type.IsNull());
-    if (!type.IsInstantiated()) {
+    if (!type.IsBeingFinalized() && !type.IsInstantiated(trail)) {
       return false;
     }
   }
@@ -3964,7 +3963,8 @@
 
 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
   ASSERT(!IsInstantiated());
   if (!instantiator_type_arguments.IsNull() &&
       IsUninstantiatedIdentity() &&
@@ -3977,8 +3977,10 @@
   AbstractType& type = AbstractType::Handle();
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
-    if (!type.IsInstantiated()) {
-      type = type.InstantiateFrom(instantiator_type_arguments, bound_error);
+    if (!type.IsBeingFinalized() && !type.IsInstantiated()) {
+      type = type.InstantiateFrom(instantiator_type_arguments,
+                                  bound_error,
+                                  trail);
     }
     instantiated_array.SetTypeAt(i, type);
   }
@@ -4109,7 +4111,8 @@
 }
 
 
-RawAbstractTypeArguments* TypeArguments::Canonicalize() const {
+RawAbstractTypeArguments* TypeArguments::Canonicalize(
+    GrowableObjectArray* trail) const {
   if (IsNull() || IsCanonical()) {
     ASSERT(IsOld());
     return this->raw();
@@ -4131,7 +4134,7 @@
     AbstractType& type = AbstractType::Handle(isolate);
     for (intptr_t i = 0; i < num_types; i++) {
       type = TypeAt(i);
-      type = type.Canonicalize();
+      type = type.Canonicalize(trail);
       SetTypeAt(i, type);
     }
     // Make sure we have an old space object and add it to the table.
@@ -4205,7 +4208,8 @@
 }
 
 
-RawAbstractTypeArguments* InstantiatedTypeArguments::Canonicalize() const {
+RawAbstractTypeArguments* InstantiatedTypeArguments::Canonicalize(
+    GrowableObjectArray* trail) const {
   const intptr_t num_types = Length();
   const TypeArguments& type_args = TypeArguments::Handle(
       TypeArguments::New(num_types, Heap::kOld));
@@ -4214,7 +4218,7 @@
     type = TypeAt(i);
     type_args.SetTypeAt(i, type);
   }
-  return type_args.Canonicalize();
+  return type_args.Canonicalize(trail);
 }
 
 
@@ -8395,8 +8399,8 @@
 }
 
 
-RawLibrary* Library::CollectionDevLibrary() {
-  return Isolate::Current()->object_store()->collection_dev_library();
+RawLibrary* Library::InternalLibrary() {
+  return Isolate::Current()->object_store()->internal_library();
 }
 
 
@@ -11823,7 +11827,7 @@
 }
 
 
-bool AbstractType::IsInstantiated() const {
+bool AbstractType::IsInstantiated(GrowableObjectArray* trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return false;
@@ -11878,7 +11882,8 @@
 }
 
 
-bool AbstractType::Equals(const Instance& other) const {
+bool AbstractType::IsEquivalent(const Instance& other,
+                                GrowableObjectArray* trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return false;
@@ -11887,7 +11892,8 @@
 
 RawAbstractType* AbstractType::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -11901,7 +11907,7 @@
 }
 
 
-RawAbstractType* AbstractType::Canonicalize() const {
+RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -11917,7 +11923,7 @@
     }
     String& type_name = String::Handle(type.BuildName(kInternalName));
     type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace());
-    // Building the bound name may lead into cycles.
+    // Build the bound name without causing divergence.
     const AbstractType& bound = AbstractType::Handle(
         BoundedType::Cast(*this).bound());
     String& bound_name = String::Handle();
@@ -11978,11 +11984,11 @@
     }
     if (cls.IsSignatureClass()) {
       // We may be reporting an error about a malformed function type. In that
-      // case, avoid instantiating the signature, since it may lead to cycles.
+      // case, avoid instantiating the signature, since it may cause divergence.
       if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
         return class_name.raw();
       }
-      // In order to avoid cycles, print the name of a typedef (non-canonical
+      // To avoid divergence, print the name of a typedef (non-canonical
       // signature class) as a regular, possibly parameterized, class.
       if (cls.IsCanonicalSignatureClass()) {
         const Function& signature_function = Function::Handle(
@@ -12387,7 +12393,7 @@
 }
 
 
-bool Type::IsInstantiated() const {
+bool Type::IsInstantiated(GrowableObjectArray* trail) const {
   if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
     return true;
   }
@@ -12396,13 +12402,14 @@
   }
   const AbstractTypeArguments& args =
       AbstractTypeArguments::Handle(arguments());
-  return args.IsNull() || args.IsInstantiated();
+  return args.IsNull() || args.IsInstantiated(trail);
 }
 
 
 RawAbstractType* Type::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
   ASSERT(IsFinalized() || IsBeingFinalized());
   ASSERT(!IsInstantiated());
   // Return the uninstantiated type unchanged if malformed. No copy needed.
@@ -12412,7 +12419,8 @@
   AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::Handle(arguments());
   type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
-                                                  bound_error);
+                                                  bound_error,
+                                                  trail);
   // Note that the type class has to be resolved at this time, but not
   // necessarily finalized yet. We may be checking bounds at compile time.
   const Class& cls = Class::Handle(type_class());
@@ -12427,14 +12435,18 @@
 }
 
 
-bool Type::Equals(const Instance& other) const {
+bool Type::IsEquivalent(const Instance& other,
+                        GrowableObjectArray* trail) const {
   ASSERT(!IsNull());
   if (raw() == other.raw()) {
     return true;
   }
   if (other.IsTypeRef()) {
-    // TODO(regis): Use trail. For now, we "unfold" the right hand type.
-    return Equals(AbstractType::Handle(TypeRef::Cast(other).type()));
+    // Unfold right hand type. Divergence is controlled by left hand type.
+    const AbstractType& other_ref_type = AbstractType::Handle(
+        TypeRef::Cast(other).type());
+    ASSERT(!other_ref_type.IsTypeRef());
+    return IsEquivalent(other_ref_type, trail);
   }
   if (!other.IsType()) {
     return false;
@@ -12478,7 +12490,7 @@
   for (intptr_t i = 0; i < num_type_params; i++) {
     type_arg = type_args.TypeAt(from_index + i);
     other_type_arg = other_type_args.TypeAt(from_index + i);
-    if (!type_arg.Equals(other_type_arg)) {
+    if (!type_arg.IsEquivalent(other_type_arg, trail)) {
       return false;
     }
   }
@@ -12500,7 +12512,7 @@
 }
 
 
-RawAbstractType* Type::Canonicalize() const {
+RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
   ASSERT(IsFinalized());
   if (IsCanonical() || IsMalformed()) {
     ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld());
@@ -12551,7 +12563,7 @@
   AbstractTypeArguments& type_args =
       AbstractTypeArguments::Handle(isolate, arguments());
   ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments()));
-  type_args = type_args.Canonicalize();
+  type_args = type_args.Canonicalize(trail);
   set_arguments(type_args);
   // The type needs to be added to the list. Grow the list if it is full.
   if (index == canonical_types_len) {
@@ -12690,53 +12702,44 @@
 }
 
 
-bool TypeRef::IsInstantiated() const {
-  if (is_being_checked()) {
+bool TypeRef::IsInstantiated(GrowableObjectArray* trail) const {
+  if (TestAndAddToTrail(&trail)) {
     return true;
   }
-  set_is_being_checked(true);
-  const bool result = AbstractType::Handle(type()).IsInstantiated();
-  set_is_being_checked(false);
-  return result;
+  return AbstractType::Handle(type()).IsInstantiated(trail);
 }
 
 
-bool TypeRef::Equals(const Instance& other) const {
-  // TODO(regis): Use trail instead of mark bit.
+bool TypeRef::IsEquivalent(const Instance& other,
+                           GrowableObjectArray* trail) const {
   if (raw() == other.raw()) {
     return true;
   }
-  if (is_being_checked()) {
+  if (TestAndAddBuddyToTrail(&trail, other)) {
     return true;
   }
-  set_is_being_checked(true);
-  const bool result = AbstractType::Handle(type()).Equals(other);
-  set_is_being_checked(false);
-  return result;
+  return AbstractType::Handle(type()).IsEquivalent(other, trail);
 }
 
 
 RawAbstractType* TypeRef::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
-  const AbstractType& ref_type = AbstractType::Handle(type());
-  // TODO(regis): Use trail instead of mark bit plus temporary redirection,
-  // because it could be marked for another reason.
-  if (is_being_checked()) {
-    ASSERT(ref_type.IsTypeRef());
-    return ref_type.raw();
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
+  TypeRef& instantiated_type_ref = TypeRef::Handle();
+  instantiated_type_ref ^= OnlyBuddyInTrail(trail);
+  if (!instantiated_type_ref.IsNull()) {
+    return instantiated_type_ref.raw();
   }
-  set_is_being_checked(true);
+  instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType()));
+  AddOnlyBuddyToTrail(&trail, instantiated_type_ref);
+  const AbstractType& ref_type = AbstractType::Handle(type());
   ASSERT(!ref_type.IsTypeRef());
-  const TypeRef& instantiated_type_ref = TypeRef::Handle(
-      TypeRef::New(ref_type));
-  // TODO(regis): instantiated_type_ref should be stored in the trail instead.
-  set_type(instantiated_type_ref);
   const AbstractType& instantiated_ref_type = AbstractType::Handle(
-      ref_type.InstantiateFrom(instantiator_type_arguments, bound_error));
+      ref_type.InstantiateFrom(instantiator_type_arguments,
+                               bound_error,
+                               trail));
   instantiated_type_ref.set_type(instantiated_ref_type);
-  set_type(ref_type);
-  set_is_being_checked(false);
   return instantiated_type_ref.raw();
 }
 
@@ -12747,43 +12750,92 @@
 }
 
 
-void TypeRef::set_is_being_checked(bool value) const {
-  raw_ptr()->is_being_checked_ = value;
-}
-
-
-// This function only canonicalizes the referenced type, but not the TypeRef
-// itself, since it cannot be canonical by definition.
+// A TypeRef cannot be canonical by definition. Only its referenced type can be.
 // Consider the type Derived, where class Derived extends Base<Derived>.
 // The first type argument of its flattened type argument vector is Derived,
 // i.e. itself, but pointer equality is not possible.
-RawAbstractType* TypeRef::Canonicalize() const {
-  // TODO(regis): Use trail, not mark bit.
-  if (is_being_checked()) {
+RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const {
+  if (TestAndAddToTrail(&trail)) {
     return raw();
   }
-  set_is_being_checked(true);
   AbstractType& ref_type = AbstractType::Handle(type());
-  ASSERT(!ref_type.IsTypeRef());
-  ref_type = ref_type.Canonicalize();
+  ref_type = ref_type.Canonicalize(trail);
   set_type(ref_type);
-  // No need to call SetCanonical(), since a TypeRef cannot be canonical by
-  // definition.
-  set_is_being_checked(false);
-  // We return the referenced type instead of the TypeRef in order to provide
-  // pointer equality in simple cases, e.g. in language/f_bounded_equality_test.
-  return ref_type.raw();
+  return raw();
 }
 
 
 intptr_t TypeRef::Hash() const {
-  // TODO(regis): Use trail and hash of referenced type.
-  // Do not calculate the hash of the referenced type to avoid cycles.
+  // Do not calculate the hash of the referenced type to avoid divergence.
   uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id();
   return FinalizeHash(result);
 }
 
 
+bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const {
+  if (*trail == NULL) {
+    *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
+  } else {
+    const intptr_t len = (*trail)->Length();
+    for (intptr_t i = 0; i < len; i++) {
+      if ((*trail)->At(i) == this->raw()) {
+        return true;
+      }
+    }
+  }
+  (*trail)->Add(*this);
+  return false;
+}
+
+
+bool TypeRef::TestAndAddBuddyToTrail(GrowableObjectArray** trail,
+                                     const Object& buddy) const {
+  if (*trail == NULL) {
+    *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
+  } else {
+    const intptr_t len = (*trail)->Length();
+    ASSERT((len % 2) == 0);
+    for (intptr_t i = 0; i < len; i += 2) {
+      if (((*trail)->At(i) == this->raw()) &&
+          ((*trail)->At(i + 1) == buddy.raw())) {
+        return true;
+      }
+    }
+  }
+  (*trail)->Add(*this);
+  (*trail)->Add(buddy);
+  return false;
+}
+
+
+RawObject* TypeRef::OnlyBuddyInTrail(GrowableObjectArray* trail) const {
+  if (trail == NULL) {
+    return Object::null();
+  }
+  const intptr_t len = trail->Length();
+  ASSERT((len % 2) == 0);
+  for (intptr_t i = 0; i < len; i += 2) {
+    if (trail->At(i) == this->raw()) {
+      ASSERT(trail->At(i + 1) != Object::null());
+      return trail->At(i + 1);
+    }
+  }
+  return Object::null();
+}
+
+
+void TypeRef::AddOnlyBuddyToTrail(GrowableObjectArray** trail,
+                              const Object& buddy) const {
+  if (*trail == NULL) {
+    *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
+  } else {
+    ASSERT(OnlyBuddyInTrail(*trail) == Object::null());
+  }
+  (*trail)->Add(*this);
+  (*trail)->Add(buddy);
+}
+
+
 RawTypeRef* TypeRef::New() {
   ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null());
   RawObject* raw = Object::Allocate(TypeRef::kClassId,
@@ -12796,7 +12848,6 @@
 RawTypeRef* TypeRef::New(const AbstractType& type) {
   const TypeRef& result = TypeRef::Handle(TypeRef::New());
   result.set_type(type);
-  result.set_is_being_checked(false);
   return result.raw();
 }
 
@@ -12825,13 +12876,17 @@
 }
 
 
-bool TypeParameter::Equals(const Instance& other) const {
+bool TypeParameter::IsEquivalent(const Instance& other,
+                                 GrowableObjectArray* trail) const {
   if (raw() == other.raw()) {
     return true;
   }
   if (other.IsTypeRef()) {
-    // TODO(regis): Use trail. For now, we "unfold" the right hand type.
-    return Equals(AbstractType::Handle(TypeRef::Cast(other).type()));
+    // Unfold right hand type. Divergence is controlled by left hand type.
+    const AbstractType& other_ref_type = AbstractType::Handle(
+        TypeRef::Cast(other).type());
+    ASSERT(!other_ref_type.IsTypeRef());
+    return IsEquivalent(other_ref_type, trail);
   }
   if (!other.IsTypeParameter()) {
     return false;
@@ -12872,7 +12927,8 @@
 
 RawAbstractType* TypeParameter::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
   ASSERT(IsFinalized());
   if (instantiator_type_arguments.IsNull()) {
     return Type::DynamicType();
@@ -12883,17 +12939,6 @@
   // type arguments are canonicalized at type finalization time. It would be too
   // early to canonicalize the returned type argument here, since instantiation
   // not only happens at run time, but also during type finalization.
-  // However, if the type argument is a reference to a canonical type, we
-  // return the referenced canonical type instead of the type reference to
-  // provide pointer equality in some simple cases, e.g. in
-  // language/f_bounded_equality_test.
-  if (type_arg.IsTypeRef()) {
-    const AbstractType& ref_type = AbstractType::Handle(
-        TypeRef::Cast(type_arg).type());
-    if (ref_type.IsCanonical()) {
-      return ref_type.raw();
-    }
-  }
   return type_arg.raw();
 }
 
@@ -12960,7 +13005,8 @@
 intptr_t TypeParameter::Hash() const {
   ASSERT(IsFinalized());
   uword result = Class::Handle(parameterized_class()).id();
-  // Do not include the hash of the bound, which could lead to cycles.
+  // No need to include the hash of the bound, since the type parameter is fully
+  // identified by its class and index.
   result <<= index();
   return FinalizeHash(result);
 }
@@ -13007,14 +13053,18 @@
 
 
 const char* TypeParameter::ToCString() const {
-  const char* format = "TypeParameter: name %s; index: %d; class: %s";
+  const char* format =
+      "TypeParameter: name %s; index: %d; class: %s; bound: %s";
   const char* name_cstr = String::Handle(Name()).ToCString();
   const Class& cls = Class::Handle(parameterized_class());
   const char* cls_cstr =
       cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString();
-  intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr) + 1;
+  const AbstractType& upper_bound = AbstractType::Handle(bound());
+  const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString();
+  intptr_t len = OS::SNPrint(
+      NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + 1;
   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
-  OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr);
+  OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr, bound_cstr);
   return chars;
 }
 
@@ -13044,35 +13094,37 @@
 }
 
 
-bool BoundedType::Equals(const Instance& other) const {
+bool BoundedType::IsEquivalent(const Instance& other,
+                               GrowableObjectArray* trail) const {
   // BoundedType are not canonicalized, because their bound may get finalized
   // after the BoundedType is created and initialized.
   if (raw() == other.raw()) {
     return true;
   }
   if (other.IsTypeRef()) {
-    // TODO(regis): Use trail. For now, we "unfold" the right hand type.
-    return Equals(AbstractType::Handle(TypeRef::Cast(other).type()));
+    // Unfold right hand type. Divergence is controlled by left hand type.
+    const AbstractType& other_ref_type = AbstractType::Handle(
+        TypeRef::Cast(other).type());
+    ASSERT(!other_ref_type.IsTypeRef());
+    return IsEquivalent(other_ref_type, trail);
   }
   if (!other.IsBoundedType()) {
     return false;
   }
   const BoundedType& other_bounded = BoundedType::Cast(other);
   if (type_parameter() != other_bounded.type_parameter()) {
-    // Not a structural compare.
-    // Note that a deep comparison of bounds could lead to cycles.
     return false;
   }
   const AbstractType& this_type = AbstractType::Handle(type());
   const AbstractType& other_type = AbstractType::Handle(other_bounded.type());
-  if (!this_type.Equals(other_type)) {
+  if (!this_type.IsEquivalent(other_type, trail)) {
     return false;
   }
   const AbstractType& this_bound = AbstractType::Handle(bound());
   const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound());
   return this_bound.IsFinalized() &&
          other_bound.IsFinalized() &&
-         this_bound.Equals(other_bound);
+         this_bound.Equals(other_bound);  // Different graph, do not pass trail.
 }
 
 
@@ -13098,31 +13150,25 @@
 }
 
 
-void BoundedType::set_is_being_checked(bool value) const {
-  raw_ptr()->is_being_checked_ = value;
-}
-
-
 RawAbstractType* BoundedType::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* bound_error) const {
+    Error* bound_error,
+    GrowableObjectArray* trail) const {
   ASSERT(IsFinalized());
   AbstractType& bounded_type = AbstractType::Handle(type());
   if (!bounded_type.IsInstantiated()) {
     bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments,
-                                                bound_error);
+                                                bound_error,
+                                                trail);
   }
-  if (FLAG_enable_type_checks &&
-      bound_error->IsNull() &&
-      !is_being_checked()) {
-    // Avoid endless recursion while checking and instantiating bound.
-    set_is_being_checked(true);
+  if (FLAG_enable_type_checks && bound_error->IsNull()) {
     AbstractType& upper_bound = AbstractType::Handle(bound());
     ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
     const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
     if (!upper_bound.IsInstantiated()) {
       upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
-                                                bound_error);
+                                                bound_error,
+                                                trail);
     }
     if (bound_error->IsNull()) {
       if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
@@ -13135,7 +13181,6 @@
         bounded_type = BoundedType::New(bounded_type, upper_bound, type_param);
       }
     }
-    set_is_being_checked(false);
   }
   return bounded_type.raw();
 }
@@ -13158,7 +13203,8 @@
 
 intptr_t BoundedType::Hash() const {
   uword result = AbstractType::Handle(type()).Hash();
-  // Do not include the hash of the bound, which could lead to cycles.
+  // No need to include the hash of the bound, since the bound is defined by the
+  // type parameter (modulo instantiation state).
   result += TypeParameter::Handle(type_parameter()).Hash();
 return FinalizeHash(result);
 }
@@ -13181,7 +13227,6 @@
   result.set_type(type);
   result.set_bound(bound);
   result.set_type_parameter(type_parameter);
-  result.set_is_being_checked(false);
   return result.raw();
 }
 
@@ -16423,7 +16468,6 @@
 
 FinalizablePersistentHandle* ExternalTypedData::AddFinalizer(
     void* peer, Dart_WeakPersistentHandleFinalizer callback) const {
-  SetPeer(peer);
   return dart::AddFinalizer(*this, peer, callback);
 }
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 56d7bbd..a413793 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1213,7 +1213,8 @@
   // If bound_error is not NULL, it may be set to reflect a bound error.
   virtual RawAbstractTypeArguments* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* bound_error) const;
+      Error* bound_error,
+      GrowableObjectArray* trail = NULL) const;
 
   // Do not clone InstantiatedTypeArguments or null vectors, since they are
   // considered finalized.
@@ -1222,7 +1223,10 @@
   }
 
   // Null vectors are canonical.
-  virtual RawAbstractTypeArguments* Canonicalize() const { return this->raw(); }
+  virtual RawAbstractTypeArguments* Canonicalize(
+      GrowableObjectArray* trail = NULL) const {
+    return this->raw();
+  }
 
   // The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>".
   virtual RawString* Name() const {
@@ -1268,14 +1272,19 @@
   }
 
   // Check if the vectors are equal.
-  bool Equals(const AbstractTypeArguments& other) const;
+  bool Equals(const AbstractTypeArguments& other) const {
+    return IsEquivalent(other);
+  }
+
+  bool IsEquivalent(const AbstractTypeArguments& other,
+                    GrowableObjectArray* trail = NULL) const;
 
   // UNREACHABLEs as AbstractTypeArguments is an abstract class.
   virtual intptr_t Length() const;
   virtual RawAbstractType* TypeAt(intptr_t index) const;
   virtual void SetTypeAt(intptr_t index, const AbstractType& value) const;
   virtual bool IsResolved() const;
-  virtual bool IsInstantiated() const;
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const;
   virtual bool IsUninstantiatedIdentity() const;
   virtual bool CanShareInstantiatorTypeArguments(
       const Class& instantiator_class) const;
@@ -1323,7 +1332,7 @@
   }
   virtual void SetTypeAt(intptr_t index, const AbstractType& value) const;
   virtual bool IsResolved() const;
-  virtual bool IsInstantiated() const;
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const;
   virtual bool IsUninstantiatedIdentity() const;
   virtual bool CanShareInstantiatorTypeArguments(
       const Class& instantiator_class) const;
@@ -1331,11 +1340,13 @@
   virtual bool IsBounded() const;
   virtual RawAbstractTypeArguments* CloneUnfinalized() const;
   // Canonicalize only if instantiated, otherwise returns 'this'.
-  virtual RawAbstractTypeArguments* Canonicalize() const;
+  virtual RawAbstractTypeArguments* Canonicalize(
+      GrowableObjectArray* trail = NULL) const;
 
   virtual RawAbstractTypeArguments* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* bound_error) const;
+      Error* bound_error,
+      GrowableObjectArray* trail = NULL) const;
 
   static const intptr_t kBytesPerElement = kWordSize;
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
@@ -1384,7 +1395,9 @@
   virtual RawAbstractType* TypeAt(intptr_t index) const;
   virtual void SetTypeAt(intptr_t index, const AbstractType& value) const;
   virtual bool IsResolved() const { return true; }
-  virtual bool IsInstantiated() const { return true; }
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const {
+    return true;
+  }
   virtual bool IsUninstantiatedIdentity() const {
     UNREACHABLE();
     return false;
@@ -1395,7 +1408,8 @@
     return false;
   }
   virtual bool IsBounded() const { return false; }  // Bounds were checked.
-  virtual RawAbstractTypeArguments* Canonicalize() const;
+  virtual RawAbstractTypeArguments* Canonicalize(
+      GrowableObjectArray* trail = NULL) const;
 
   RawAbstractTypeArguments* uninstantiated_type_arguments() const {
     return raw_ptr()->uninstantiated_type_arguments_;
@@ -2650,7 +2664,7 @@
   static RawLibrary* AsyncLibrary();
   static RawLibrary* CoreLibrary();
   static RawLibrary* CollectionLibrary();
-  static RawLibrary* CollectionDevLibrary();
+  static RawLibrary* InternalLibrary();
   static RawLibrary* IsolateLibrary();
   static RawLibrary* MathLibrary();
   static RawLibrary* MirrorsLibrary();
@@ -4086,15 +4100,20 @@
   virtual RawUnresolvedClass* unresolved_class() const;
   virtual RawAbstractTypeArguments* arguments() const;
   virtual intptr_t token_pos() const;
-  virtual bool IsInstantiated() const;
-  virtual bool Equals(const Instance& other) const;
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const;
+  virtual bool Equals(const Instance& other) const {
+    return IsEquivalent(other);
+  }
+  virtual bool IsEquivalent(const Instance& other,
+                            GrowableObjectArray* trail = NULL) const;
 
   // Instantiate this type using the given type argument vector.
   // Return a new type, or return 'this' if it is already instantiated.
   // If bound_error is not NULL, it may be set to reflect a bound error.
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* bound_error) const;
+      Error* bound_error,
+      GrowableObjectArray* trail = NULL) const;
 
   // Return a clone of this unfinalized type or the type itself if it is
   // already finalized. Apply recursively to type arguments, i.e. finalized
@@ -4106,7 +4125,8 @@
   }
 
   // Return the canonical version of this type.
-  virtual RawAbstractType* Canonicalize() const;
+  virtual RawAbstractType* Canonicalize(
+      GrowableObjectArray* trail = NULL) const;
 
   // The name of this type, including the names of its type arguments, if any.
   virtual RawString* Name() const {
@@ -4232,13 +4252,16 @@
   virtual RawAbstractTypeArguments* arguments() const;
   void set_arguments(const AbstractTypeArguments& value) const;
   virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
-  virtual bool IsInstantiated() const;
-  virtual bool Equals(const Instance& other) const;
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const;
+  virtual bool IsEquivalent(const Instance& other,
+                            GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* malformed_error) const;
+      Error* malformed_error,
+      GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* CloneUnfinalized() const;
-  virtual RawAbstractType* Canonicalize() const;
+  virtual RawAbstractType* Canonicalize(
+      GrowableObjectArray* trail = NULL) const;
 
   virtual intptr_t Hash() const;
 
@@ -4343,15 +4366,39 @@
   virtual intptr_t token_pos() const {
     return AbstractType::Handle(type()).token_pos();
   }
-  virtual bool IsInstantiated() const;
-  virtual bool Equals(const Instance& other) const;
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const;
+  virtual bool IsEquivalent(const Instance& other,
+                            GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* bound_error) const;
-  virtual RawAbstractType* Canonicalize() const;
+      Error* bound_error,
+      GrowableObjectArray* trail = NULL) const;
+  virtual RawAbstractType* Canonicalize(
+      GrowableObjectArray* trail = NULL) const;
 
   virtual intptr_t Hash() const;
 
+  // Return true if the receiver is contained in the trail.
+  // Otherwise, if the trail is null, allocate a trail, then add the receiver to
+  // the trail and return false.
+  bool TestAndAddToTrail(GrowableObjectArray** trail) const;
+
+  // Return true if the pair <receiver, buddy> is contained in the trail.
+  // Otherwise, if the trail is null, allocate a trail, add the pair <receiver,
+  // buddy> to the trail and return false.
+  // The receiver may be added several times, each time with a different buddy.
+  bool TestAndAddBuddyToTrail(GrowableObjectArray** trail,
+                              const Object& buddy) const;
+
+  // Return the object associated with the receiver in the trail or
+  // Object::null() if the receiver is not contained in the trail.
+  RawObject* OnlyBuddyInTrail(GrowableObjectArray* trail) const;
+
+  // If the trail is null, allocate a trail, add the pair <receiver, buddy> to
+  // the trail. The receiver may only be added once with its only buddy.
+  void AddOnlyBuddyToTrail(GrowableObjectArray** trail,
+                           const Object& buddy) const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawTypeRef));
   }
@@ -4359,11 +4406,6 @@
   static RawTypeRef* New(const AbstractType& type);
 
  private:
-  bool is_being_checked() const {
-    return raw_ptr()->is_being_checked_;
-  }
-  void set_is_being_checked(bool value) const;
-
   static RawTypeRef* New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeRef, AbstractType);
@@ -4410,13 +4452,20 @@
                   const AbstractType& upper_bound,
                   Error* bound_error) const;
   virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
-  virtual bool IsInstantiated() const { return false; }
-  virtual bool Equals(const Instance& other) const;
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const {
+    return false;
+  }
+  virtual bool IsEquivalent(const Instance& other,
+                            GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* bound_error) const;
+      Error* bound_error,
+      GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* CloneUnfinalized() const;
-  virtual RawAbstractType* Canonicalize() const { return raw(); }
+  virtual RawAbstractType* Canonicalize(
+      GrowableObjectArray* trail = NULL) const {
+    return raw();
+  }
 
   virtual intptr_t Hash() const;
 
@@ -4482,19 +4531,24 @@
   virtual intptr_t token_pos() const {
     return AbstractType::Handle(type()).token_pos();
   }
-  virtual bool IsInstantiated() const {
+  virtual bool IsInstantiated(GrowableObjectArray* trail = NULL) const {
     // It is not possible to encounter an instantiated bounded type with an
     // uninstantiated upper bound. Therefore, we do not need to check if the
     // bound is instantiated. Moreover, doing so could lead into cycles, as in
     // class C<T extends C<C>> { }.
     return AbstractType::Handle(type()).IsInstantiated();
   }
-  virtual bool Equals(const Instance& other) const;
+  virtual bool IsEquivalent(const Instance& other,
+                            GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* bound_error) const;
+      Error* bound_error,
+      GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* CloneUnfinalized() const;
-  virtual RawAbstractType* Canonicalize() const { return raw(); }
+  virtual RawAbstractType* Canonicalize(
+      GrowableObjectArray* trail = NULL) const {
+    return raw();
+  }
 
   virtual intptr_t Hash() const;
 
@@ -4511,11 +4565,6 @@
   void set_bound(const AbstractType& value) const;
   void set_type_parameter(const TypeParameter& value) const;
 
-  bool is_being_checked() const {
-    return raw_ptr()->is_being_checked_;
-  }
-  void set_is_being_checked(bool value) const;
-
   static RawBoundedType* New();
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(BoundedType, AbstractType);
@@ -4532,9 +4581,9 @@
 class MixinAppType : public AbstractType {
  public:
   // A MixinAppType object is unfinalized by definition, since it is replaced at
-  // class finalization time with a finalized Type or BoundedType object.
+  // class finalization time with a finalized (and possibly malformed or
+  // malbounded) Type object.
   virtual bool IsFinalized() const { return false; }
-  // TODO(regis): Handle malformed and malbounded MixinAppType.
   virtual bool IsMalformed() const { return false; }
   virtual bool IsMalbounded() const { return false; }
   virtual bool IsMalformedOrMalbounded() const { return false; }
@@ -6038,10 +6087,6 @@
     return (ElementSizeInBytes(cid) * Length());
   }
 
-  void* GetPeer() const {
-    return raw_ptr()->peer_;
-  }
-
   void* DataAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset == 0) ||
            ((byte_offset > 0) && (byte_offset < LengthInBytes())));
@@ -6121,10 +6166,6 @@
     raw_ptr()->data_ = data;
   }
 
-  void SetPeer(void* peer) const {
-    raw_ptr()->peer_ = peer;
-  }
-
  private:
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalTypedData, Instance);
   friend class Class;
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 866f62c..710572f 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -24,8 +24,8 @@
     kAsync,
     kCore,
     kCollection,
-    kCollectionDev,
     kConvert,
+    kInternal,
     kIsolate,
     kMath,
     kMirrors,
@@ -273,10 +273,8 @@
   RawLibrary* builtin_library() const { return builtin_library_; }
   RawLibrary* core_library() const { return core_library_; }
   RawLibrary* collection_library() const { return collection_library_; }
-  RawLibrary* collection_dev_library() const {
-    return collection_dev_library_;
-  }
   RawLibrary* convert_library() const { return convert_library_; }
+  RawLibrary* internal_library() const { return internal_library_; }
   RawLibrary* isolate_library() const { return isolate_library_; }
   RawLibrary* math_library() const { return math_library_; }
   RawLibrary* mirrors_library() const { return mirrors_library_; }
@@ -292,12 +290,12 @@
       case kCollection:
         collection_library_ = value.raw();
         break;
-      case kCollectionDev:
-        collection_dev_library_ = value.raw();
-        break;
       case kConvert:
         convert_library_ = value.raw();
         break;
+      case kInternal:
+        internal_library_ = value.raw();
+        break;
       case kIsolate:
         isolate_library_ = value.raw();
         break;
@@ -465,8 +463,8 @@
   RawLibrary* builtin_library_;
   RawLibrary* core_library_;
   RawLibrary* collection_library_;
-  RawLibrary* collection_dev_library_;
   RawLibrary* convert_library_;
+  RawLibrary* internal_library_;
   RawLibrary* isolate_library_;
   RawLibrary* math_library_;
   RawLibrary* mirrors_library_;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index b53e2dc..492474f 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2945,7 +2945,7 @@
 
 
 void Parser::AddEqualityNullCheck() {
-  const intptr_t token_pos = Scanner::kDummyTokenIndex;
+  const intptr_t token_pos = TokenPos();
   AstNode* argument =
       new LoadLocalNode(token_pos,
                         current_block_->scope->parent()->VariableAt(1));
@@ -4495,7 +4495,6 @@
 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
   TRACE_PARSER("ParseMixins");
   ASSERT(CurrentToken() == Token::kWITH);
-  ASSERT(super_type.IsType());  // TODO(regis): Could be a BoundedType.
   const GrowableObjectArray& mixin_types =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
   AbstractType& mixin_type = AbstractType::Handle();
@@ -9806,9 +9805,9 @@
   } else {
     ErrorMsg("illegal symbol literal");
   }
-  // Lookup class Symbol from collection_dev library and call the
+  // Lookup class Symbol from internal library and call the
   // constructor to create a symbol instance.
-  const Library& lib = Library::Handle(Library::CollectionDevLibrary());
+  const Library& lib = Library::Handle(Library::InternalLibrary());
   const Class& symbol_class = Class::Handle(lib.LookupClass(Symbols::Symbol()));
   ASSERT(!symbol_class.IsNull());
   ArgumentListNode* constr_args = new ArgumentListNode(symbol_pos);
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index ad701cb..b967123 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -32,7 +32,7 @@
     defined(TARGET_OS_MACOS) || defined(TARGET_OS_ANDROID)
   DEFINE_FLAG(bool, profile, false, "Enable Sampling Profiler");
 #else
-  DEFINE_FLAG(bool, profile, false, "Enable Sampling Profiler");
+  DEFINE_FLAG(bool, profile, true, "Enable Sampling Profiler");
 #endif
 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
 DEFINE_FLAG(charp, profile_dir, NULL,
@@ -112,7 +112,6 @@
       return;
     }
     isolate->set_profiler_data(NULL);
-    profiler_data->set_sample_buffer(NULL);
     delete profiler_data;
     if (FLAG_trace_profiled_isolates) {
       OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name());
@@ -133,13 +132,6 @@
   if (profiler_data == NULL) {
     return;
   }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  if (sample_buffer == NULL) {
-    return;
-  }
-  Sample* sample = sample_buffer->ReserveSample();
-  sample->Init(Sample::kIsolateStart, isolate, OS::GetCurrentTimeMicros(),
-               Thread::GetCurrentThreadId());
   ThreadInterrupter::Register(RecordSampleInterruptCallback, isolate);
 }
 
@@ -153,17 +145,6 @@
   }
   ASSERT(initialized_);
   ThreadInterrupter::Unregister();
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
-  }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  if (sample_buffer == NULL) {
-    return;
-  }
-  Sample* sample = sample_buffer->ReserveSample();
-  sample->Init(Sample::kIsolateStop, isolate, OS::GetCurrentTimeMicros(),
-               Thread::GetCurrentThreadId());
 }
 
 
@@ -649,6 +630,7 @@
 
 IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer,
                                          bool own_sample_buffer) {
+  ASSERT(sample_buffer != NULL);
   sample_buffer_ = sample_buffer;
   own_sample_buffer_ = own_sample_buffer;
 }
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 4712792..706e64a 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -26,7 +26,7 @@
   static void Shutdown();
 
   static void InitProfilingForIsolate(Isolate* isolate,
-                                      bool shared_buffer = false);
+                                      bool shared_buffer = true);
   static void ShutdownProfilingForIsolate(Isolate* isolate);
 
   static void BeginExecution(Isolate* isolate);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 0b251ba..f8dbad4 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -442,8 +442,6 @@
   friend class GCMarker;
   friend class ExternalTypedData;
   friend class Heap;
-  friend class HeapProfiler;
-  friend class HeapProfilerRootVisitor;
   friend class MarkingVisitor;
   friend class Object;
   friend class ObjectHistogram;
@@ -513,8 +511,6 @@
   friend class Object;
   friend class RawInstance;
   friend class RawInstructions;
-  friend class RawType;  // TODO(regis): To temporarily print unfinalized types.
-  friend class RawTypeParameter;  // To temporarily print unfinalized types.
   friend class SnapshotReader;
 };
 
@@ -531,8 +527,6 @@
     return reinterpret_cast<RawObject**>(&ptr()->ident_);
   }
   intptr_t token_pos_;
-
-  friend class RawType;  // TODO(regis): To temporarily print unfinalized types.
 };
 
 
@@ -1191,7 +1185,6 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->type_);
   }
-  bool is_being_checked_;  // Transient field, not snapshotted.
 };
 
 
@@ -1225,7 +1218,6 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->type_parameter_);
   }
-  bool is_being_checked_;  // Transient field, not snapshotted.
 };
 
 
@@ -1492,7 +1484,6 @@
   RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->length_); }
 
   uint8_t* data_;
-  void* peer_;
 
   friend class TokenStream;
   friend class RawTokenStream;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 9c73a1c..a34039c 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -11,9 +11,6 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, error_on_bad_type);
-
-
 #define NEW_OBJECT(type)                                                       \
   ((kind == Snapshot::kFull) ? reader->New##type() : type::New())
 
@@ -241,52 +238,14 @@
 }
 
 
-static const char* RawOneByteStringToCString(RawOneByteString* str) {
-  const char* start = reinterpret_cast<char*>(str) - kHeapObjectTag +
-      OneByteString::data_offset();
-  const int len = Smi::Value(*reinterpret_cast<RawSmi**>(
-      reinterpret_cast<uword>(str) - kHeapObjectTag + String::length_offset()));
-  char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
-  memmove(chars, start, len);
-  chars[len] = '\0';
-  return chars;
-}
-
-
 void RawType::WriteTo(SnapshotWriter* writer,
                       intptr_t object_id,
                       Snapshot::Kind kind) {
   ASSERT(writer != NULL);
 
   // Only resolved and finalized types should be written to a snapshot.
-  // TODO(regis): Replace the test below by an ASSERT() or remove the flag test.
-  if (FLAG_error_on_bad_type &&
-      (ptr()->type_state_ != RawType::kFinalizedInstantiated) &&
-      (ptr()->type_state_ != RawType::kFinalizedUninstantiated)) {
-    // Print the name of the class of the unfinalized type, as well as the
-    // token location from where it is referred to, making sure not
-    // to allocate any handles. Unfortunately, we cannot print the script name.
-    const intptr_t cid = ClassIdTag::decode(*reinterpret_cast<uword*>(
-        reinterpret_cast<uword>(ptr()->type_class_) - kHeapObjectTag +
-            Object::tags_offset()));
-    if (cid == kUnresolvedClassCid) {
-      OS::Print("Snapshotting unresolved type '%s' at token pos %" Pd "\n",
-                RawOneByteStringToCString(
-                    reinterpret_cast<RawOneByteString*>(
-                        reinterpret_cast<RawUnresolvedClass*>(
-                            ptr()->type_class_)->ptr()->ident_)),
-                ptr()->token_pos_);
-    } else {
-      // Assume cid == kClassId, but it can also be kIllegalCid.
-      OS::Print("Snapshotting unfinalized type '%s' at token pos %" Pd "\n",
-                RawOneByteStringToCString(
-                    reinterpret_cast<RawOneByteString*>(
-                        reinterpret_cast<RawClass*>(
-                            ptr()->type_class_)->ptr()->name_)),
-                ptr()->token_pos_);
-    }
-    UNREACHABLE();
-  }
+  ASSERT((ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
+         (ptr()->type_state_ == RawType::kFinalizedUninstantiated));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -331,8 +290,6 @@
                           reader->ObjectHandle()->raw());
   }
 
-  type_ref.set_is_being_checked(false);
-
   return type_ref.raw();
 }
 
@@ -395,24 +352,7 @@
   ASSERT(writer != NULL);
 
   // Only finalized type parameters should be written to a snapshot.
-  // TODO(regis): Replace the test below by an ASSERT() or remove the flag test.
-  if (FLAG_error_on_bad_type &&
-      (ptr()->type_state_ != RawTypeParameter::kFinalizedUninstantiated)) {
-    // Print the name of the unfinalized type parameter, the name of the class
-    // it parameterizes, as well as the token location from where it is referred
-    // to, making sure not to allocate any handles. Unfortunately, we cannot
-    // print the script name.
-    OS::Print("Snapshotting unfinalized type parameter '%s' of class '%s' at "
-              "token pos %" Pd "\n",
-              RawOneByteStringToCString(
-                  reinterpret_cast<RawOneByteString*>(ptr()->name_)),
-              RawOneByteStringToCString(
-                  reinterpret_cast<RawOneByteString*>(
-                      reinterpret_cast<RawClass*>(
-                          ptr()->parameterized_class_)->ptr()->name_)),
-              ptr()->token_pos_);
-    UNREACHABLE();
-  }
+  ASSERT(ptr()->type_state_ == RawTypeParameter::kFinalizedUninstantiated);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -457,8 +397,6 @@
                               reader->ObjectHandle()->raw());
   }
 
-  bounded_type.set_is_being_checked(false);
-
   return bounded_type.raw();
 }
 
@@ -1688,15 +1626,48 @@
                                 intptr_t object_id,
                                 intptr_t tags,
                                 Snapshot::Kind kind) {
-  UNREACHABLE();
-  return Instance::null();
+  ASSERT(reader != NULL);
+
+  // Create an Instance object or get canonical one if it is a canonical
+  // constant.
+  Instance& obj = Instance::ZoneHandle(reader->isolate(), Instance::null());
+  if (kind == Snapshot::kFull) {
+    obj = reader->NewInstance();
+  } else {
+    obj ^= Object::Allocate(kInstanceCid,
+                            Instance::InstanceSize(),
+                            HEAP_SPACE(kind));
+    // When reading a script snapshot we need to canonicalize only those object
+    // references that are objects from the core library (loaded from a
+    // full snapshot). Objects that are only in the script need not be
+    // canonicalized as they are already canonical.
+    // When reading a message snapshot we always have to canonicalize.
+    if (RawObject::IsCanonical(tags) &&
+        (RawObject::IsCreatedFromSnapshot(tags) ||
+         (kind == Snapshot::kMessage))) {
+      obj = obj.CheckAndCanonicalize(NULL);
+    }
+  }
+  reader->AddBackRef(object_id, &obj, kIsDeserialized);
+
+  // Set the object tags.
+  obj.set_tags(tags);
+
+  return obj.raw();
 }
 
 
 void RawInstance::WriteTo(SnapshotWriter* writer,
                           intptr_t object_id,
                           Snapshot::Kind kind) {
-  UNREACHABLE();
+  ASSERT(writer != NULL);
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+
+  // Write out the class and tags information.
+  writer->WriteIndexedObject(kInstanceCid);
+  writer->WriteIntptrValue(writer->GetObjectTags(this));
 }
 
 
@@ -2565,6 +2536,9 @@
     array ^= reader->ReadObjectRef();
     result.set_catch_pc_offset_array(array);
 
+    bool expand_inlined = reader->Read<bool>();
+    result.set_expand_inlined(expand_inlined);
+
     return result.raw();
   }
   UNREACHABLE();  // Stacktraces are not sent in a snapshot.
@@ -2587,11 +2561,11 @@
     writer->WriteIndexedObject(kStacktraceCid);
     writer->WriteIntptrValue(writer->GetObjectTags(this));
 
-    // There are no non object pointer fields.
-
     // Write out all the object pointer fields.
     SnapshotWriterVisitor visitor(writer);
     visitor.VisitPointers(from(), to());
+
+    writer->Write(ptr()->expand_inlined_);
   } else {
     // Stacktraces are not allowed in other snapshot forms.
     writer->SetWriteException(Exceptions::kArgument,
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index fe8aaa1..35715e8 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -4,28 +4,100 @@
 
 #include "vm/service.h"
 
+#include "include/dart_api.h"
+
+#include "vm/compiler.h"
 #include "vm/cpu.h"
+#include "vm/dart_api_impl.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
 #include "vm/heap_histogram.h"
 #include "vm/isolate.h"
 #include "vm/message.h"
+#include "vm/native_entry.h"
+#include "vm/native_arguments.h"
 #include "vm/object.h"
 #include "vm/object_id_ring.h"
 #include "vm/object_store.h"
 #include "vm/port.h"
 #include "vm/profiler.h"
+#include "vm/symbols.h"
+
 
 namespace dart {
 
-typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream);
-
-struct ServiceMessageHandlerEntry {
-  const char* command;
-  ServiceMessageHandler handler;
+struct ResourcesEntry {
+  const char* path_;
+  const char* resource_;
+  int length_;
 };
 
-static ServiceMessageHandler FindServiceMessageHandler(const char* command);
+extern ResourcesEntry __service_resources_[];
+
+class Resources {
+ public:
+  static const int kNoSuchInstance = -1;
+  static int ResourceLookup(const char* path, const char** resource) {
+    ResourcesEntry* table = ResourceTable();
+    for (int i = 0; table[i].path_ != NULL; i++) {
+      const ResourcesEntry& entry = table[i];
+      if (strcmp(path, entry.path_) == 0) {
+        *resource = entry.resource_;
+        ASSERT(entry.length_ > 0);
+        return entry.length_;
+      }
+    }
+    return kNoSuchInstance;
+  }
+
+  static const char* Path(int idx) {
+    ASSERT(idx >= 0);
+    ResourcesEntry* entry = At(idx);
+    if (entry == NULL) {
+      return NULL;
+    }
+    ASSERT(entry->path_ != NULL);
+    return entry->path_;
+  }
+
+  static int Length(int idx) {
+    ASSERT(idx >= 0);
+    ResourcesEntry* entry = At(idx);
+    if (entry == NULL) {
+      return kNoSuchInstance;
+    }
+    ASSERT(entry->path_ != NULL);
+    return entry->length_;
+  }
+
+  static const uint8_t* Resource(int idx) {
+    ASSERT(idx >= 0);
+    ResourcesEntry* entry = At(idx);
+    if (entry == NULL) {
+      return NULL;
+    }
+    return reinterpret_cast<const uint8_t*>(entry->resource_);
+  }
+
+ private:
+  static ResourcesEntry* At(int idx) {
+    ASSERT(idx >= 0);
+    ResourcesEntry* table = ResourceTable();
+    for (int i = 0; table[i].path_ != NULL; i++) {
+      if (idx == i) {
+        return &table[i];
+      }
+    }
+    return NULL;
+  }
+
+  static ResourcesEntry* ResourceTable() {
+    return &__service_resources_[0];
+  }
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
+};
 
 
 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
@@ -34,7 +106,360 @@
 }
 
 
-static void PostReply(const String& reply, const Instance& reply_port) {
+static void SendIsolateServiceMessage(Dart_NativeArguments args) {
+  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  Isolate* isolate = arguments->isolate();
+  StackZone zone(isolate);
+  HANDLESCOPE(isolate);
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(1));
+
+  // Extract SendPort port id.
+  const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp));
+  if (sp_id_obj.IsError()) {
+    Exceptions::PropagateError(Error::Cast(sp_id_obj));
+  }
+  Integer& id = Integer::Handle(isolate);
+  id ^= sp_id_obj.raw();
+  Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value());
+  ASSERT(sp_id != ILLEGAL_PORT);
+
+  // Serialize message.
+  uint8_t* data = NULL;
+  MessageWriter writer(&data, &allocator);
+  writer.WriteMessage(message);
+
+  // TODO(turnidge): Throw an exception when the return value is false?
+  PortMap::PostMessage(new Message(sp_id, data, writer.BytesWritten(),
+                                   Message::kOOBPriority));
+}
+
+
+static void SendRootServiceMessage(Dart_NativeArguments args) {
+  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  Isolate* isolate = arguments->isolate();
+  StackZone zone(isolate);
+  HANDLESCOPE(isolate);
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(0));
+  Service::HandleRootMessage(message);
+}
+
+
+struct VmServiceNativeEntry {
+  const char* name;
+  int num_arguments;
+  Dart_NativeFunction function;
+};
+
+
+static VmServiceNativeEntry _VmServiceNativeEntries[] = {
+  {"VMService_SendIsolateServiceMessage", 2, SendIsolateServiceMessage},
+  {"VMService_SendRootServiceMessage", 1, SendRootServiceMessage}
+};
+
+
+static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
+                                                   int num_arguments,
+                                                   bool* auto_setup_scope) {
+  const Object& obj = Object::Handle(Api::UnwrapHandle(name));
+  if (!obj.IsString()) {
+    return NULL;
+  }
+  const char* function_name = obj.ToCString();
+  ASSERT(function_name != NULL);
+  ASSERT(auto_setup_scope != NULL);
+  *auto_setup_scope = true;
+  intptr_t n =
+      sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]);
+  for (intptr_t i = 0; i < n; i++) {
+    VmServiceNativeEntry entry = _VmServiceNativeEntries[i];
+    if (!strcmp(function_name, entry.name) &&
+        (num_arguments == entry.num_arguments)) {
+      return entry.function;
+    }
+  }
+  return NULL;
+}
+
+
+Isolate* Service::service_isolate_ = NULL;
+Dart_LibraryTagHandler Service::default_handler_ = NULL;
+Dart_Port Service::port_ = ILLEGAL_PORT;
+
+static Dart_Port ExtractPort(Dart_Handle receivePort) {
+  HANDLESCOPE(Isolate::Current());
+  const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
+  const Instance& rp = Instance::Cast(unwrapped_rp);
+  // Extract RawReceivePort port id.
+  const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp));
+  if (rp_id_obj.IsError()) {
+    return ILLEGAL_PORT;
+  }
+  ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint());
+  const Integer& id = Integer::Cast(rp_id_obj);
+  return static_cast<Dart_Port>(id.AsInt64Value());
+}
+
+
+Isolate* Service::GetServiceIsolate(void* callback_data) {
+  if (service_isolate_ != NULL) {
+    // Already initialized, return service isolate.
+    return service_isolate_;
+  }
+  Dart_ServiceIsolateCreateCalback create_callback =
+    Isolate::ServiceCreateCallback();
+  if (create_callback == NULL) {
+    return NULL;
+  }
+  Isolate::SetCurrent(NULL);
+  char* error = NULL;
+  Isolate* isolate = reinterpret_cast<Isolate*>(
+      create_callback(callback_data, &error));
+  if (isolate == NULL) {
+    return NULL;
+  }
+  Isolate::SetCurrent(isolate);
+  {
+    // Install the dart:vmservice library.
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    Library& library =
+        Library::Handle(isolate, isolate->object_store()->root_library());
+    // Isolate is empty.
+    ASSERT(library.IsNull());
+    // Grab embedder tag handler.
+    default_handler_ = isolate->library_tag_handler();
+    ASSERT(default_handler_ != NULL);
+    // Temporarily install our own.
+    isolate->set_library_tag_handler(LibraryTagHandler);
+    // Get script resource.
+    const char* resource = NULL;
+    const char* path = "/vmservice.dart";
+    intptr_t r = Resources::ResourceLookup(path, &resource);
+    ASSERT(r != Resources::kNoSuchInstance);
+    ASSERT(resource != NULL);
+    const String& source_str = String::Handle(
+        String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
+    ASSERT(!source_str.IsNull());
+    const String& url_str = String::Handle(Symbols::DartVMService().raw());
+    library ^= Library::LookupLibrary(url_str);
+    ASSERT(library.IsNull());
+    // Setup library.
+    library = Library::New(url_str);
+    library.Register();
+    const Script& script = Script::Handle(
+      isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
+    library.SetLoadInProgress();
+    Dart_EnterScope();  // Need to enter scope for tag handler.
+    const Error& error = Error::Handle(isolate,
+                                       Compiler::Compile(library, script));
+    ASSERT(error.IsNull());
+    Dart_ExitScope();
+    library.SetLoaded();
+    // Install embedder default library tag handler again.
+    isolate->set_library_tag_handler(default_handler_);
+    default_handler_ = NULL;
+    library.set_native_entry_resolver(VmServiceNativeResolver);
+  }
+  {
+    // Boot the dart:vmservice library.
+    Dart_EnterScope();
+    Dart_Handle result;
+    Dart_Handle url_str =
+        Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId));
+    Dart_Handle library = Dart_LookupLibrary(url_str);
+    ASSERT(Dart_IsLibrary(library));
+    result = Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL);
+    ASSERT(!Dart_IsError(result));
+    port_ = ExtractPort(result);
+    ASSERT(port_ != ILLEGAL_PORT);
+    Dart_ExitScope();
+  }
+  Isolate::SetCurrent(NULL);
+  service_isolate_ = reinterpret_cast<Isolate*>(isolate);
+  return service_isolate_;
+}
+
+
+// These must be kept in sync with service/constants.dart
+#define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
+#define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
+
+
+static RawArray* MakeServiceControlMessage(Dart_Port port_id, intptr_t code,
+                                           const String& name) {
+  const Array& list = Array::Handle(Array::New(4));
+  ASSERT(!list.IsNull());
+  const Integer& code_int = Integer::Handle(Integer::New(code));
+  const Integer& port_int = Integer::Handle(Integer::New(port_id));
+  const Object& send_port = Object::Handle(
+      DartLibraryCalls::NewSendPort(port_id));
+  ASSERT(!send_port.IsNull());
+  list.SetAt(0, code_int);
+  list.SetAt(1, port_int);
+  list.SetAt(2, send_port);
+  list.SetAt(3, name);
+  return list.raw();
+}
+
+
+bool Service::SendIsolateStartupMessage() {
+  if (!IsRunning()) {
+    return false;
+  }
+  Isolate* isolate = Isolate::Current();
+  ASSERT(isolate != NULL);
+  HANDLESCOPE(isolate);
+  const String& name = String::Handle(String::New(isolate->name()));
+  ASSERT(!name.IsNull());
+  const Array& list = Array::Handle(
+      MakeServiceControlMessage(Dart_GetMainPortId(),
+                                VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
+                                name));
+  ASSERT(!list.IsNull());
+  uint8_t* data = NULL;
+  MessageWriter writer(&data, &allocator);
+  writer.WriteMessage(list);
+  intptr_t len = writer.BytesWritten();
+  return PortMap::PostMessage(
+      new Message(port_, data, len, Message::kNormalPriority));
+}
+
+
+bool Service::SendIsolateShutdownMessage() {
+  if (!IsRunning()) {
+    return false;
+  }
+  Isolate* isolate = Isolate::Current();
+  ASSERT(isolate != NULL);
+  HANDLESCOPE(isolate);
+  const Array& list = Array::Handle(
+      MakeServiceControlMessage(Dart_GetMainPortId(),
+                                VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID,
+                                String::Handle(String::null())));
+  ASSERT(!list.IsNull());
+  uint8_t* data = NULL;
+  MessageWriter writer(&data, &allocator);
+  writer.WriteMessage(list);
+  intptr_t len = writer.BytesWritten();
+  return PortMap::PostMessage(
+      new Message(port_, data, len, Message::kNormalPriority));
+}
+
+
+bool Service::IsRunning() {
+  return port_ != ILLEGAL_PORT;
+}
+
+
+Dart_Handle Service::GetSource(const char* name) {
+  ASSERT(name != NULL);
+  int i = 0;
+  while (true) {
+    const char* path = Resources::Path(i);
+    if (path == NULL) {
+      break;
+    }
+    ASSERT(*path != '\0');
+    // Skip the '/'.
+    path++;
+    if (strcmp(name, path) == 0) {
+      const uint8_t* str = Resources::Resource(i);
+      intptr_t length = Resources::Length(i);
+      return Dart_NewStringFromUTF8(str, length);
+    }
+    i++;
+  }
+  return Dart_Null();
+}
+
+
+Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
+                                       Dart_Handle url) {
+  if (!Dart_IsLibrary(library)) {
+    return Dart_NewApiError("not a library");
+  }
+  if (!Dart_IsString(url)) {
+    return Dart_NewApiError("url is not a string");
+  }
+  const char* url_string = NULL;
+  Dart_Handle result = Dart_StringToCString(url, &url_string);
+  if (Dart_IsError(result)) {
+    return result;
+  }
+  if (tag == Dart_kImportTag) {
+    // Embedder handles all requests for external libraries.
+    ASSERT(default_handler_ != NULL);
+    return default_handler_(tag, library, url);
+  }
+  ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
+  if (tag == Dart_kCanonicalizeUrl) {
+    // url is already canonicalized.
+    return url;
+  }
+  Dart_Handle source = GetSource(url_string);
+  if (Dart_IsError(source)) {
+    return source;
+  }
+  return Dart_LoadSource(library, url, source);
+}
+
+
+// A handler for a per-isolate request.
+//
+// If a handler returns true, the reply is complete and ready to be
+// posted.  If a handler returns false, then it is responsible for
+// posting the reply (this can be used for asynchronous delegation of
+// the response handling).
+typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream);
+
+struct IsolateMessageHandlerEntry {
+  const char* command;
+  IsolateMessageHandler handler;
+};
+
+static IsolateMessageHandler FindIsolateMessageHandler(const char* command);
+
+
+// A handler for a root (vm-global) request.
+//
+// If a handler returns true, the reply is complete and ready to be
+// posted.  If a handler returns false, then it is responsible for
+// posting the reply (this can be used for asynchronous delegation of
+// the response handling).
+typedef bool (*RootMessageHandler)(JSONStream* stream);
+
+struct RootMessageHandlerEntry {
+  const char* command;
+  RootMessageHandler handler;
+};
+
+static RootMessageHandler FindRootMessageHandler(const char* command);
+
+
+static void PostReply(JSONStream* js) {
+  Dart_Port reply_port = js->reply_port();
+  ASSERT(reply_port != ILLEGAL_PORT);
+  js->set_reply_port(ILLEGAL_PORT);  // Prevent double replies.
+
+  const String& reply = String::Handle(String::New(js->ToCString()));
+  ASSERT(!reply.IsNull());
+
+  uint8_t* data = NULL;
+  MessageWriter writer(&data, &allocator);
+  writer.WriteMessage(reply);
+  PortMap::PostMessage(new Message(reply_port, data,
+                                   writer.BytesWritten(),
+                                   Message::kNormalPriority));
+}
+
+
+static void SetupJSONStream(JSONStream* js, Zone* zone,
+                            const Instance& reply_port,
+                            const GrowableObjectArray& path,
+                            const GrowableObjectArray& option_keys,
+                            const GrowableObjectArray& option_values) {
+  // Setup the reply port.
   const Object& id_obj = Object::Handle(
       DartLibraryCalls::PortGetId(reply_port));
   if (id_obj.IsError()) {
@@ -43,90 +468,33 @@
   const Integer& id = Integer::Cast(id_obj);
   Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value());
   ASSERT(port != ILLEGAL_PORT);
+  js->set_reply_port(port);
 
-  uint8_t* data = NULL;
-  MessageWriter writer(&data, &allocator);
-  writer.WriteMessage(reply);
-  PortMap::PostMessage(new Message(port, data,
-                                   writer.BytesWritten(),
-                                   Message::kNormalPriority));
-}
-
-
-void Service::HandleServiceMessage(Isolate* isolate, const Instance& msg) {
-  ASSERT(isolate != NULL);
-  ASSERT(!msg.IsNull());
-  ASSERT(msg.IsGrowableObjectArray());
-
-  {
-    StackZone zone(isolate);
-    HANDLESCOPE(isolate);
-
-    const GrowableObjectArray& message = GrowableObjectArray::Cast(msg);
-    // Message is a list with three entries.
-    ASSERT(message.Length() == 4);
-
-    Instance& reply_port = Instance::Handle(isolate);
-    GrowableObjectArray& path = GrowableObjectArray::Handle(isolate);
-    GrowableObjectArray& option_keys = GrowableObjectArray::Handle(isolate);
-    GrowableObjectArray& option_values = GrowableObjectArray::Handle(isolate);
-    reply_port ^= message.At(0);
-    path ^= message.At(1);
-    option_keys ^= message.At(2);
-    option_values ^= message.At(3);
-
-    ASSERT(!path.IsNull());
-    ASSERT(!option_keys.IsNull());
-    ASSERT(!option_values.IsNull());
-    // Path always has at least one entry in it.
-    ASSERT(path.Length() > 0);
-    // Same number of option keys as values.
-    ASSERT(option_keys.Length() == option_values.Length());
-
-    String& pathSegment = String::Handle();
-    pathSegment ^= path.At(0);
-    ASSERT(!pathSegment.IsNull());
-
-    ServiceMessageHandler handler =
-        FindServiceMessageHandler(pathSegment.ToCString());
-    ASSERT(handler != NULL);
-    {
-      JSONStream js;
-
-      // Setup JSONStream arguments and options. The arguments and options
-      // are zone allocated and will be freed immediately after handling the
-      // message.
-      Zone* zoneAllocator = zone.GetZone();
-      const char** arguments = zoneAllocator->Alloc<const char*>(path.Length());
-      String& string_iterator = String::Handle();
-      for (intptr_t i = 0; i < path.Length(); i++) {
-        string_iterator ^= path.At(i);
-        arguments[i] =
-            zoneAllocator->MakeCopyOfString(string_iterator.ToCString());
-      }
-      js.SetArguments(arguments, path.Length());
-      if (option_keys.Length() > 0) {
-        const char** option_keys_native =
-            zoneAllocator->Alloc<const char*>(option_keys.Length());
-        const char** option_values_native =
-            zoneAllocator->Alloc<const char*>(option_keys.Length());
-        for (intptr_t i = 0; i < option_keys.Length(); i++) {
-          string_iterator ^= option_keys.At(i);
-          option_keys_native[i] =
-              zoneAllocator->MakeCopyOfString(string_iterator.ToCString());
-          string_iterator ^= option_values.At(i);
-          option_values_native[i] =
-              zoneAllocator->MakeCopyOfString(string_iterator.ToCString());
-        }
-        js.SetOptions(option_keys_native, option_values_native,
-                      option_keys.Length());
-      }
-
-      handler(isolate, &js);
-      const String& reply = String::Handle(String::New(js.ToCString()));
-      ASSERT(!reply.IsNull());
-      PostReply(reply, reply_port);
+  // Setup JSONStream arguments and options. The arguments and options
+  // are zone allocated and will be freed immediately after handling the
+  // message.
+  const char** arguments = zone->Alloc<const char*>(path.Length());
+  String& string_iterator = String::Handle();
+  for (intptr_t i = 0; i < path.Length(); i++) {
+    string_iterator ^= path.At(i);
+    arguments[i] = zone->MakeCopyOfString(string_iterator.ToCString());
+  }
+  js->SetArguments(arguments, path.Length());
+  if (option_keys.Length() > 0) {
+    const char** option_keys_native =
+        zone->Alloc<const char*>(option_keys.Length());
+    const char** option_values_native =
+        zone->Alloc<const char*>(option_keys.Length());
+    for (intptr_t i = 0; i < option_keys.Length(); i++) {
+      string_iterator ^= option_keys.At(i);
+      option_keys_native[i] =
+          zone->MakeCopyOfString(string_iterator.ToCString());
+      string_iterator ^= option_values.At(i);
+      option_values_native[i] =
+          zone->MakeCopyOfString(string_iterator.ToCString());
     }
+    js->SetOptions(option_keys_native, option_values_native,
+                  option_keys.Length());
   }
 }
 
@@ -154,14 +522,6 @@
 }
 
 
-static void PrintGenericError(JSONStream* js) {
-  JSONObject jsobj(js);
-  jsobj.AddProperty("type", "Error");
-  jsobj.AddProperty("text", "Invalid request.");
-  PrintArgumentsAndOptions(jsobj, js);
-}
-
-
 static void PrintError(JSONStream* js, const char* format, ...) {
   Isolate* isolate = Isolate::Current();
 
@@ -183,15 +543,70 @@
 }
 
 
-static void HandleName(Isolate* isolate, JSONStream* js) {
+void Service::HandleIsolateMessage(Isolate* isolate, const Instance& msg) {
+  ASSERT(isolate != NULL);
+  ASSERT(!msg.IsNull());
+  ASSERT(msg.IsGrowableObjectArray());
+
+  {
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+
+    const GrowableObjectArray& message = GrowableObjectArray::Cast(msg);
+    // Message is a list with four entries.
+    ASSERT(message.Length() == 4);
+
+    Instance& reply_port = Instance::Handle(isolate);
+    GrowableObjectArray& path = GrowableObjectArray::Handle(isolate);
+    GrowableObjectArray& option_keys = GrowableObjectArray::Handle(isolate);
+    GrowableObjectArray& option_values = GrowableObjectArray::Handle(isolate);
+    reply_port ^= message.At(0);
+    path ^= message.At(1);
+    option_keys ^= message.At(2);
+    option_values ^= message.At(3);
+
+    ASSERT(!path.IsNull());
+    ASSERT(!option_keys.IsNull());
+    ASSERT(!option_values.IsNull());
+    // Path always has at least one entry in it.
+    ASSERT(path.Length() > 0);
+    // Same number of option keys as values.
+    ASSERT(option_keys.Length() == option_values.Length());
+
+    String& pathSegment = String::Handle();
+    pathSegment ^= path.At(0);
+    ASSERT(!pathSegment.IsNull());
+
+    IsolateMessageHandler handler =
+        FindIsolateMessageHandler(pathSegment.ToCString());
+    {
+      JSONStream js;
+      SetupJSONStream(&js, zone.GetZone(),
+                      reply_port, path, option_keys, option_values);
+      if (handler == NULL) {
+        PrintError(&js, "Unrecognized path");
+        PostReply(&js);
+      } else {
+        if (handler(isolate, &js)) {
+          // Handler returns true if the reply is ready to be posted.
+          PostReply(&js);
+        }
+      }
+    }
+  }
+}
+
+
+static bool HandleName(Isolate* isolate, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "IsolateName");
   jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port()));
   jsobj.AddProperty("name", isolate->name());
+  return true;
 }
 
 
-static void HandleStackTrace(Isolate* isolate, JSONStream* js) {
+static bool HandleStackTrace(Isolate* isolate, JSONStream* js) {
   DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "StackTrace");
@@ -210,45 +625,48 @@
     jsobj.AddProperty("function", frame->function());
     jsobj.AddProperty("code", frame->code());
   }
+  return true;
 }
 
 
-static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) {
+static bool HandleObjectHistogram(Isolate* isolate, JSONStream* js) {
   ObjectHistogram* histogram = Isolate::Current()->object_histogram();
   if (histogram == NULL) {
     JSONObject jsobj(js);
     jsobj.AddProperty("type", "Error");
     jsobj.AddProperty("text", "Run with --print_object_histogram");
-    return;
+    return true;
   }
   histogram->PrintToJSONStream(js);
+  return true;
 }
 
 
-static void HandleEcho(Isolate* isolate, JSONStream* js) {
+static bool HandleIsolateEcho(Isolate* isolate, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "message");
   PrintArgumentsAndOptions(jsobj, js);
+  return true;
 }
 
 
 // Print an error message if there is no ID argument.
-#define REQUIRE_COLLECTION_ID(collection)                                     \
-  if (js->num_arguments() == 1) {                                             \
-    PrintError(js, "Must specify collection object id: /%s/id", collection);  \
-    return;                                                                   \
+#define REQUIRE_COLLECTION_ID(collection)                                      \
+  if (js->num_arguments() == 1) {                                              \
+    PrintError(js, "Must specify collection object id: /%s/id", collection);   \
+    return true;                                                               \
   }
 
 
 #define CHECK_COLLECTION_ID_BOUNDS(collection, length, arg, id, js)            \
   if (!GetIntegerId(arg, &id)) {                                               \
     PrintError(js, "Must specify collection object id: %s/id", collection);    \
-    return;                                                                    \
+    return true;                                                               \
   }                                                                            \
   if ((id < 0) || (id >= length)) {                                            \
     PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \
                                                                length);        \
-    return;                                                                    \
+    return true;                                                               \
   }
 
 
@@ -294,164 +712,171 @@
 }
 
 
-static void HandleClassesClosures(Isolate* isolate, const Class& cls,
+static bool HandleClassesClosures(Isolate* isolate, const Class& cls,
                                   JSONStream* js) {
   intptr_t id;
   if (js->num_arguments() > 4) {
     PrintError(js, "Command too long");
-    return;
+    return true;
   }
   if (!GetIntegerId(js->GetArgument(3), &id)) {
     PrintError(js, "Must specify collection object id: closures/id");
-    return;
+    return true;
   }
   Function& func = Function::Handle();
   func ^= cls.ClosureFunctionFromIndex(id);
   if (func.IsNull()) {
     PrintError(js, "Closure function %" Pd " not found", id);
-    return;
+    return true;
   }
   func.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleClassesDispatchers(Isolate* isolate, const Class& cls,
+static bool HandleClassesDispatchers(Isolate* isolate, const Class& cls,
                                      JSONStream* js) {
   intptr_t id;
   if (js->num_arguments() > 4) {
     PrintError(js, "Command too long");
-    return;
+    return true;
   }
   if (!GetIntegerId(js->GetArgument(3), &id)) {
     PrintError(js, "Must specify collection object id: dispatchers/id");
-    return;
+    return true;
   }
   Function& func = Function::Handle();
   func ^= cls.InvocationDispatcherFunctionFromIndex(id);
   if (func.IsNull()) {
     PrintError(js, "Dispatcher %" Pd " not found", id);
-    return;
+    return true;
   }
   func.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
+static bool HandleClassesFunctions(Isolate* isolate, const Class& cls,
                                    JSONStream* js) {
   intptr_t id;
   if (js->num_arguments() > 4) {
     PrintError(js, "Command too long");
-    return;
+    return true;
   }
   if (!GetIntegerId(js->GetArgument(3), &id)) {
     PrintError(js, "Must specify collection object id: functions/id");
-    return;
+    return true;
   }
   Function& func = Function::Handle();
   func ^= cls.FunctionFromIndex(id);
   if (func.IsNull()) {
     PrintError(js, "Function %" Pd " not found", id);
-    return;
+    return true;
   }
   func.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleClassesImplicitClosures(Isolate* isolate, const Class& cls,
+static bool HandleClassesImplicitClosures(Isolate* isolate, const Class& cls,
                                           JSONStream* js) {
   intptr_t id;
   if (js->num_arguments() > 4) {
     PrintError(js, "Command too long");
-    return;
+    return true;
   }
   if (!GetIntegerId(js->GetArgument(3), &id)) {
     PrintError(js, "Must specify collection object id: implicit_closures/id");
-    return;
+    return true;
   }
   Function& func = Function::Handle();
   func ^= cls.ImplicitClosureFunctionFromIndex(id);
   if (func.IsNull()) {
     PrintError(js, "Implicit closure function %" Pd " not found", id);
-    return;
+    return true;
   }
   func.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleClassesFields(Isolate* isolate, const Class& cls,
+static bool HandleClassesFields(Isolate* isolate, const Class& cls,
                                 JSONStream* js) {
   intptr_t id;
   if (js->num_arguments() > 4) {
     PrintError(js, "Command too long");
-    return;
+    return true;
   }
   if (!GetIntegerId(js->GetArgument(3), &id)) {
     PrintError(js, "Must specify collection object id: fields/id");
-    return;
+    return true;
   }
   Field& field = Field::Handle(cls.FieldFromIndex(id));
   if (field.IsNull()) {
     PrintError(js, "Field %" Pd " not found", id);
-    return;
+    return true;
   }
   field.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleClasses(Isolate* isolate, JSONStream* js) {
+static bool HandleClasses(Isolate* isolate, JSONStream* js) {
   if (js->num_arguments() == 1) {
     ClassTable* table = isolate->class_table();
     table->PrintToJSONStream(js);
-    return;
+    return true;
   }
   ASSERT(js->num_arguments() >= 2);
   intptr_t id;
   if (!GetIntegerId(js->GetArgument(1), &id)) {
     PrintError(js, "Must specify collection object id: /classes/id");
-    return;
+    return true;
   }
   ClassTable* table = isolate->class_table();
   if (!table->IsValidIndex(id)) {
     PrintError(js, "%" Pd " is not a valid class id.", id);;
-    return;
+    return true;
   }
   Class& cls = Class::Handle(table->At(id));
   if (js->num_arguments() == 2) {
     cls.PrintToJSONStream(js, false);
-    return;
+    return true;
   } else if (js->num_arguments() >= 3) {
     const char* second = js->GetArgument(2);
     if (!strcmp(second, "closures")) {
-      HandleClassesClosures(isolate, cls, js);
+      return HandleClassesClosures(isolate, cls, js);
     } else if (!strcmp(second, "fields")) {
-      HandleClassesFields(isolate, cls, js);
+      return HandleClassesFields(isolate, cls, js);
     } else if (!strcmp(second, "functions")) {
-      HandleClassesFunctions(isolate, cls, js);
+      return HandleClassesFunctions(isolate, cls, js);
     } else if (!strcmp(second, "implicit_closures")) {
-      HandleClassesImplicitClosures(isolate, cls, js);
+      return HandleClassesImplicitClosures(isolate, cls, js);
     } else if (!strcmp(second, "dispatchers")) {
-      HandleClassesDispatchers(isolate, cls, js);
+      return HandleClassesDispatchers(isolate, cls, js);
     } else {
       PrintError(js, "Invalid sub collection %s", second);
+      return true;
     }
-    return;
   }
   UNREACHABLE();
+  return true;
 }
 
 
-static void HandleLibrary(Isolate* isolate, JSONStream* js) {
+static bool HandleLibrary(Isolate* isolate, JSONStream* js) {
   if (js->num_arguments() == 1) {
     const Library& lib =
         Library::Handle(isolate->object_store()->root_library());
     lib.PrintToJSONStream(js, false);
-    return;
+    return true;
   }
-  PrintGenericError(js);
+  PrintError(js, "Command too long");
+  return true;
 }
 
 
-static void HandleLibraries(Isolate* isolate, JSONStream* js) {
+static bool HandleLibraries(Isolate* isolate, JSONStream* js) {
   // TODO(johnmccutchan): Support fields and functions on libraries.
   REQUIRE_COLLECTION_ID("libraries");
   const GrowableObjectArray& libs =
@@ -464,10 +889,11 @@
   lib ^= libs.At(id);
   ASSERT(!lib.IsNull());
   lib.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleObjects(Isolate* isolate, JSONStream* js) {
+static bool HandleObjects(Isolate* isolate, JSONStream* js) {
   REQUIRE_COLLECTION_ID("objects");
   ASSERT(js->num_arguments() >= 2);
   ObjectIdRing* ring = isolate->object_id_ring();
@@ -475,41 +901,41 @@
   intptr_t id = -1;
   if (!GetIntegerId(js->GetArgument(1), &id)) {
     Object::null_object().PrintToJSONStream(js, false);
-    return;
+    return true;
   }
   Object& obj = Object::Handle(ring->GetObjectForId(id));
   obj.PrintToJSONStream(js, false);
+  return true;
 }
 
 
 
-static void HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) {
+static bool HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "ScriptList");
-  {
-    JSONArray members(&jsobj, "members");
-    const GrowableObjectArray& libs =
+  JSONArray members(&jsobj, "members");
+  const GrowableObjectArray& libs =
       GrowableObjectArray::Handle(isolate->object_store()->libraries());
-    int num_libs = libs.Length();
-    Library &lib = Library::Handle();
-    Script& script = Script::Handle();
-    for (intptr_t i = 0; i < num_libs; i++) {
-      lib ^= libs.At(i);
-      ASSERT(!lib.IsNull());
-      ASSERT(Smi::IsValid(lib.index()));
-      const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
-      ASSERT(!loaded_scripts.IsNull());
-      intptr_t num_scripts = loaded_scripts.Length();
-      for (intptr_t i = 0; i < num_scripts; i++) {
-        script ^= loaded_scripts.At(i);
-        members.AddValue(script);
-      }
+  int num_libs = libs.Length();
+  Library &lib = Library::Handle();
+  Script& script = Script::Handle();
+  for (intptr_t i = 0; i < num_libs; i++) {
+    lib ^= libs.At(i);
+    ASSERT(!lib.IsNull());
+    ASSERT(Smi::IsValid(lib.index()));
+    const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
+    ASSERT(!loaded_scripts.IsNull());
+    intptr_t num_scripts = loaded_scripts.Length();
+    for (intptr_t i = 0; i < num_scripts; i++) {
+      script ^= loaded_scripts.At(i);
+      members.AddValue(script);
     }
   }
+  return true;
 }
 
 
-static void HandleScriptsFetch(Isolate* isolate, JSONStream* js) {
+static bool HandleScriptsFetch(Isolate* isolate, JSONStream* js) {
   const GrowableObjectArray& libs =
     GrowableObjectArray::Handle(isolate->object_store()->libraries());
   int num_libs = libs.Length();
@@ -533,31 +959,33 @@
       url ^= script.url();
       if (url.Equals(requested_url)) {
         script.PrintToJSONStream(js, false);
-        return;
+        return true;
       }
     }
   }
   PrintError(js, "Cannot find script %s\n", requested_url.ToCString());
+  return true;
 }
 
 
-static void HandleScripts(Isolate* isolate, JSONStream* js) {
+static bool HandleScripts(Isolate* isolate, JSONStream* js) {
   if (js->num_arguments() == 1) {
     // Enumerate all scripts.
-    HandleScriptsEnumerate(isolate, js);
+    return HandleScriptsEnumerate(isolate, js);
   } else if (js->num_arguments() == 2) {
     // Fetch specific script.
-    HandleScriptsFetch(isolate, js);
+    return HandleScriptsFetch(isolate, js);
   } else {
     PrintError(js, "Command too long");
+    return true;
   }
 }
 
 
-static void HandleDebug(Isolate* isolate, JSONStream* js) {
+static bool HandleDebug(Isolate* isolate, JSONStream* js) {
   if (js->num_arguments() == 1) {
     PrintError(js, "Must specify a subcommand");
-    return;
+    return true;
   }
   const char* command = js->GetArgument(1);
   if (!strcmp(command, "breakpoints")) {
@@ -567,7 +995,7 @@
       jsobj.AddProperty("type", "BreakpointList");
       JSONArray jsarr(&jsobj, "breakpoints");
       isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr);
-
+      return true;
     } else if (js->num_arguments() == 3) {
       // Print individual breakpoint.
       intptr_t id = 0;
@@ -577,52 +1005,49 @@
       }
       if (bpt != NULL) {
         bpt->PrintToJSONStream(js);
+        return true;
       } else {
         PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2));
+        return true;
       }
-
     } else {
       PrintError(js, "Command too long");
+      return true;
     }
   } else {
     PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1));
+    return true;
   }
 }
 
 
-static void HandleCpu(Isolate* isolate, JSONStream* js) {
-  JSONObject jsobj(js);
-  jsobj.AddProperty("type", "CPU");
-  jsobj.AddProperty("architecture", CPU::Id());
-}
-
-
-static void HandleCode(Isolate* isolate, JSONStream* js) {
+static bool HandleCode(Isolate* isolate, JSONStream* js) {
   REQUIRE_COLLECTION_ID("code");
   uintptr_t pc;
   if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) {
     PrintError(js, "Must specify code address: code/c0deadd0.");
-    return;
+    return true;
   }
   Code& code = Code::Handle(Code::LookupCode(pc));
   if (code.IsNull()) {
     PrintError(js, "Could not find code at %" Px "", pc);
-    return;
+    return true;
   }
   code.PrintToJSONStream(js, false);
+  return true;
 }
 
 
-static void HandleProfile(Isolate* isolate, JSONStream* js) {
+static bool HandleProfile(Isolate* isolate, JSONStream* js) {
   Profiler::PrintToJSONStream(isolate, js, true);
+  return true;
 }
 
 
-static ServiceMessageHandlerEntry __message_handlers[] = {
-  { "_echo", HandleEcho },
+static IsolateMessageHandlerEntry isolate_handlers[] = {
+  { "_echo", HandleIsolateEcho },
   { "classes", HandleClasses },
   { "code", HandleCode },
-  { "cpu", HandleCpu },
   { "debug", HandleDebug },
   { "libraries", HandleLibraries },
   { "library", HandleLibrary },
@@ -635,24 +1060,105 @@
 };
 
 
-static void HandleFallthrough(Isolate* isolate, JSONStream* js) {
-  JSONObject jsobj(js);
-  jsobj.AddProperty("type", "Error");
-  jsobj.AddProperty("text", "request not understood.");
-  PrintArgumentsAndOptions(jsobj, js);
-}
-
-
-static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
-  intptr_t num_message_handlers = sizeof(__message_handlers) /
-                                  sizeof(__message_handlers[0]);
+static IsolateMessageHandler FindIsolateMessageHandler(const char* command) {
+  intptr_t num_message_handlers = sizeof(isolate_handlers) /
+                                  sizeof(isolate_handlers[0]);
   for (intptr_t i = 0; i < num_message_handlers; i++) {
-    const ServiceMessageHandlerEntry& entry = __message_handlers[i];
+    const IsolateMessageHandlerEntry& entry = isolate_handlers[i];
     if (!strcmp(command, entry.command)) {
       return entry.handler;
     }
   }
-  return HandleFallthrough;
+  return NULL;
+}
+
+
+void Service::HandleRootMessage(const Instance& msg) {
+  Isolate* isolate = Isolate::Current();
+  ASSERT(!msg.IsNull());
+  ASSERT(msg.IsGrowableObjectArray());
+
+  {
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+
+    const GrowableObjectArray& message = GrowableObjectArray::Cast(msg);
+    // Message is a list with four entries.
+    ASSERT(message.Length() == 4);
+
+    Instance& reply_port = Instance::Handle(isolate);
+    GrowableObjectArray& path = GrowableObjectArray::Handle(isolate);
+    GrowableObjectArray& option_keys = GrowableObjectArray::Handle(isolate);
+    GrowableObjectArray& option_values = GrowableObjectArray::Handle(isolate);
+    reply_port ^= message.At(0);
+    path ^= message.At(1);
+    option_keys ^= message.At(2);
+    option_values ^= message.At(3);
+
+    ASSERT(!path.IsNull());
+    ASSERT(!option_keys.IsNull());
+    ASSERT(!option_values.IsNull());
+    // Path always has at least one entry in it.
+    ASSERT(path.Length() > 0);
+    // Same number of option keys as values.
+    ASSERT(option_keys.Length() == option_values.Length());
+
+    String& pathSegment = String::Handle();
+    pathSegment ^= path.At(0);
+    ASSERT(!pathSegment.IsNull());
+
+    RootMessageHandler handler =
+        FindRootMessageHandler(pathSegment.ToCString());
+    {
+      JSONStream js;
+      SetupJSONStream(&js, zone.GetZone(),
+                      reply_port, path, option_keys, option_values);
+      if (handler == NULL) {
+        PrintError(&js, "Unrecognized path");
+        PostReply(&js);
+      } else {
+        if (handler(&js)) {
+          // Handler returns true if the reply is ready to be posted.
+          PostReply(&js);
+        }
+      }
+    }
+  }
+}
+
+
+static bool HandleRootEcho(JSONStream* js) {
+  JSONObject jsobj(js);
+  jsobj.AddProperty("type", "message");
+  PrintArgumentsAndOptions(jsobj, js);
+  return true;
+}
+
+
+static bool HandleCpu(JSONStream* js) {
+  JSONObject jsobj(js);
+  jsobj.AddProperty("type", "CPU");
+  jsobj.AddProperty("architecture", CPU::Id());
+  return true;
+}
+
+
+static RootMessageHandlerEntry root_handlers[] = {
+  { "_echo", HandleRootEcho },
+  { "cpu", HandleCpu },
+};
+
+
+static RootMessageHandler FindRootMessageHandler(const char* command) {
+  intptr_t num_message_handlers = sizeof(root_handlers) /
+                                  sizeof(root_handlers[0]);
+  for (intptr_t i = 0; i < num_message_handlers; i++) {
+    const RootMessageHandlerEntry& entry = root_handlers[i];
+    if (!strcmp(command, entry.command)) {
+      return entry.handler;
+    }
+  }
+  return NULL;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 84b467b..8806b46 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -13,10 +13,27 @@
 
 class Instance;
 class Isolate;
+class RawInstance;
 
 class Service : public AllStatic {
  public:
-  static void HandleServiceMessage(Isolate* isolate, const Instance& message);
+  // Handles a message which is not directed to an isolate.
+  static void HandleRootMessage(const Instance& message);
+
+  // Handles a message which is directed to a particular isolate.
+  static void HandleIsolateMessage(Isolate* isolate, const Instance& message);
+
+  static Isolate* GetServiceIsolate(void* callback_data);
+  static bool SendIsolateStartupMessage();
+  static bool SendIsolateShutdownMessage();
+ private:
+  static bool IsRunning();
+  static Isolate* service_isolate_;
+  static Dart_LibraryTagHandler default_handler_;
+  static Dart_Port port_;
+  static Dart_Handle GetSource(const char* name);
+  static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
+                                       Dart_Handle url);
 };
 
 }  // namespace dart
diff --git a/runtime/bin/vmservice/client.dart b/runtime/vm/service/client.dart
similarity index 100%
rename from runtime/bin/vmservice/client.dart
rename to runtime/vm/service/client.dart
diff --git a/runtime/bin/vmservice/constants.dart b/runtime/vm/service/constants.dart
similarity index 100%
rename from runtime/bin/vmservice/constants.dart
rename to runtime/vm/service/constants.dart
diff --git a/runtime/bin/vmservice/message.dart b/runtime/vm/service/message.dart
similarity index 73%
rename from runtime/bin/vmservice/message.dart
rename to runtime/vm/service/message.dart
index 9dce2a1..8eaad37 100644
--- a/runtime/bin/vmservice/message.dart
+++ b/runtime/vm/service/message.dart
@@ -63,7 +63,24 @@
     var keys = options.keys.toList();
     var values = options.values.toList();
     var request = [receivePort.sendPort, path, keys, values];
-    sendServiceMessage(sendPort, request);
+    sendIsolateServiceMessage(sendPort, request);
+    return _completer.future;
+  }
+
+  Future<String> sendToVM() {
+    final receivePort = new RawReceivePort();
+    receivePort.handler = (value) {
+      receivePort.close();
+      if (value is Exception) {
+        _completer.completeError(value);
+      } else {
+        _completer.complete(value);
+      }
+    };
+    var keys = options.keys.toList();
+    var values = options.values.toList();
+    var request = [receivePort.sendPort, path, keys, values];
+    sendRootServiceMessage(request);
     return _completer.future;
   }
 
@@ -80,3 +97,9 @@
     }));
   }
 }
+
+void sendIsolateServiceMessage(SendPort sp, List m)
+    native "VMService_SendIsolateServiceMessage";
+
+void sendRootServiceMessage(List m)
+    native "VMService_SendRootServiceMessage";
diff --git a/runtime/bin/vmservice/message_router.dart b/runtime/vm/service/message_router.dart
similarity index 100%
rename from runtime/bin/vmservice/message_router.dart
rename to runtime/vm/service/message_router.dart
diff --git a/runtime/bin/vmservice/running_isolate.dart b/runtime/vm/service/running_isolate.dart
similarity index 100%
rename from runtime/bin/vmservice/running_isolate.dart
rename to runtime/vm/service/running_isolate.dart
diff --git a/runtime/bin/vmservice/running_isolates.dart b/runtime/vm/service/running_isolates.dart
similarity index 91%
rename from runtime/bin/vmservice/running_isolates.dart
rename to runtime/vm/service/running_isolates.dart
index db93d08..3abd09a 100644
--- a/runtime/bin/vmservice/running_isolates.dart
+++ b/runtime/vm/service/running_isolates.dart
@@ -10,17 +10,11 @@
   RunningIsolates();
 
   void isolateStartup(int portId, SendPort sp, String name) {
-    if (isolates[portId] != null) {
-      throw new StateError('Duplicate isolate startup.');
-    }
     var ri = new RunningIsolate(portId, sp, name);
     isolates[portId] = ri;
   }
 
   void isolateShutdown(int portId, SendPort sp) {
-    if (isolates[portId] == null) {
-      throw new StateError('Unknown isolate.');
-    }
     isolates.remove(portId);
   }
 
diff --git a/runtime/bin/vmservice/vmservice.dart b/runtime/vm/service/vmservice.dart
similarity index 89%
rename from runtime/bin/vmservice/vmservice.dart
rename to runtime/vm/service/vmservice.dart
index 5532428..886268d 100644
--- a/runtime/bin/vmservice/vmservice.dart
+++ b/runtime/vm/service/vmservice.dart
@@ -11,7 +11,6 @@
 
 part 'client.dart';
 part 'constants.dart';
-part 'resources.dart';
 part 'running_isolate.dart';
 part 'running_isolates.dart';
 part 'message.dart';
@@ -83,9 +82,15 @@
       _clientCollection(message);
       return message.response;
     }
-    return runningIsolates.route(message);
+    if (message.path[0] == 'isolates') {
+      return runningIsolates.route(message);
+    }
+    return message.sendToVM();
   }
 }
 
-void sendServiceMessage(SendPort sp, Object m)
-    native "VMService_SendServiceMessage";
+RawReceivePort boot() {
+  // Boot the VMService.
+  // Return the port we expect isolate startup and shutdown messages on.
+  return new VMService().receivePort;
+}
diff --git a/runtime/vm/service_sources.gypi b/runtime/vm/service_sources.gypi
new file mode 100644
index 0000000..a0de7e9
--- /dev/null
+++ b/runtime/vm/service_sources.gypi
@@ -0,0 +1,15 @@
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+{
+  'sources': [
+    'service/client.dart',
+    'service/constants.dart',
+    'service/message.dart',
+    'service/message_router.dart',
+    'service/running_isolate.dart',
+    'service/running_isolates.dart',
+    'service/vmservice.dart',
+  ]
+}
\ No newline at end of file
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 03dc4d3..1955b8a 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -115,7 +115,7 @@
 
   // Get the breakpoint list.
   service_msg = Eval(lib, "[port, ['debug', 'breakpoints'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
       "{\"type\":\"BreakpointList\",\"breakpoints\":[{"
@@ -127,7 +127,7 @@
 
   // Individual breakpoint.
   service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
       "{\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true,"
@@ -138,7 +138,7 @@
 
   // Missing sub-command.
   service_msg = Eval(lib, "[port, ['debug'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
       "{\"type\":\"Error\","
@@ -149,7 +149,7 @@
 
   // Unrecognized breakpoint.
   service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1111'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ("{\"type\":\"Error\","
                 "\"text\":\"Unrecognized breakpoint id 1111\","
@@ -161,7 +161,7 @@
   // Command too long.
   service_msg =
       Eval(lib, "[port, ['debug', 'breakpoints', '1111', 'green'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ("{\"type\":\"Error\",\"text\":\"Command too long\","
                 "\"message\":{\"arguments\":[\"debug\",\"breakpoints\","
@@ -171,7 +171,7 @@
 
   // Unrecognized subcommand.
   service_msg = Eval(lib, "[port, ['debug', 'nosferatu'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ("{\"type\":\"Error\","
                 "\"text\":\"Unrecognized subcommand 'nosferatu'\","
@@ -223,7 +223,7 @@
 
   // Request an invalid class id.
   service_msg = Eval(h_lib, "[port, ['classes', '999999'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"999999 is not a valid class id.\","
@@ -232,7 +232,7 @@
 
   // Request the class A over the service.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "'], [], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
       "{\"type\":\"Class\",\"id\":\"classes\\/1009\",\"name\":\"A\","
@@ -261,7 +261,7 @@
   // Request function 0 from class A.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '0'],"
                               "[], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Function\",\"id\":\"classes\\/1009\\/functions\\/0\",\"name\":"
@@ -274,7 +274,7 @@
   // Request field 0 from class A.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '0'],"
                               "[], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Field\",\"id\":\"classes\\/1009\\/fields\\/0\",\"name\":\"a\","
@@ -289,7 +289,7 @@
   // Invalid sub command.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'huh', '0'],"
                               "[], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"Invalid sub collection huh\",\"message\":"
@@ -299,7 +299,7 @@
   // Invalid field request.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9'],"
                               "[], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"Field 9 not found\","
@@ -309,7 +309,7 @@
   // Invalid function request.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9'],"
                               "[], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"Function 9 not found\","
@@ -320,7 +320,7 @@
   // Invalid field subcommand.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9', 'x']"
                              ",[], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":"
@@ -331,7 +331,7 @@
   // Invalid function request.
   service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9',"
                              "'x'], [], []]", cid);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":"
@@ -390,7 +390,7 @@
 
   // Request an invalid code object.
   service_msg = Eval(h_lib, "[port, ['code', '0'], [], []]");
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   EXPECT_STREQ(
     "{\"type\":\"Error\",\"text\":\"Could not find code at 0\",\"message\":"
@@ -402,7 +402,7 @@
   // Request code object at code.EntryPoint()
   // Expect this to succeed as it is inside [entry, entry + size).
   service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", entry);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   {
     // Only perform a partial match.
@@ -417,7 +417,7 @@
   // Expect this to succeed as it is inside [entry, entry + size).
   uintptr_t address = entry + 16;
   service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   {
     // Only perform a partial match.
@@ -432,7 +432,7 @@
   // Expect this to succeed as it is inside [entry, entry + size).
   address = last - 1;
   service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   {
     // Only perform a partial match.
@@ -447,7 +447,7 @@
   // to fail as it's outside of [entry, entry + size).
   address = last;
   service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address);
-  Service::HandleServiceMessage(isolate, service_msg);
+  Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   {
     const intptr_t kBufferSize = 1024;
@@ -460,4 +460,32 @@
   }
 }
 
+
+TEST_CASE(Service_Cpu) {
+  const char* kScript =
+      "var port;\n"  // Set to our mock port by C++.
+      "\n"
+      "main() {\n"   // We set breakpoint here.
+      "}";
+
+  Isolate* isolate = Isolate::Current();
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  // Build a mock message handler and wrap it in a dart port.
+  ServiceTestMessageHandler handler;
+  Dart_Port port_id = PortMap::CreatePort(&handler);
+  Dart_Handle port =
+      Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
+  EXPECT_VALID(port);
+  EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
+
+  Instance& service_msg = Instance::Handle();
+  service_msg = Eval(lib, "[port, ['cpu'], [], []]");
+
+  Service::HandleRootMessage(service_msg);
+  handler.HandleNextMessage();
+  EXPECT_SUBSTRING("\"type\":\"CPU\"", handler.msg());
+}
+
 }  // namespace dart
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index ed254d4..c7f90a2 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -478,6 +478,16 @@
 }
 
 
+RawInstance* SnapshotReader::NewInstance() {
+  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  cls_ = object_store()->object_class();
+  RawInstance* obj = reinterpret_cast<RawInstance*>(
+      AllocateUninitialized(cls_, Instance::InstanceSize()));
+  return obj;
+}
+
+
 RawMint* SnapshotReader::NewMint(int64_t value) {
   ASSERT(kind_ == Snapshot::kFull);
   ASSERT(isolate()->no_gc_scope_depth() != 0);
@@ -701,6 +711,10 @@
     ErrorHandle()->set_exception(exception);
     Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle());
   }
+  // Make sure to initialize the last word, as this can be left untouched in
+  // case the object deserialized has an alignment tail.
+  *reinterpret_cast<RawObject**>(address + size - kWordSize) = Object::null();
+
   RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
   uword tags = 0;
   intptr_t index = cls.id();
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index b15d249..cc001386 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -252,6 +252,7 @@
   RawTokenStream* NewTokenStream(intptr_t len);
   RawContext* NewContext(intptr_t num_variables);
   RawClass* NewClass(intptr_t class_id);
+  RawInstance* NewInstance();
   RawMint* NewMint(int64_t value);
   RawBigint* NewBigint(const char* hex_string);
   RawDouble* NewDouble(double value);
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index a1a45d5..142a904 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -34,7 +34,6 @@
   V(DeoptimizeLazy)                                                            \
   V(BreakpointRuntime)                                                         \
   V(BreakpointStatic)                                                          \
-  V(BreakpointReturn)                                                          \
   V(DebugStepCheck)                                                            \
   V(Subtype1TestCache)                                                         \
   V(Subtype2TestCache)                                                         \
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index a80c548..8f340be 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1860,23 +1860,6 @@
 }
 
 
-//  R0: return value.
-void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ Push(R0);
-  __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0);
-  __ Pop(R0);
-  __ LeaveStubFrame();
-
-  // Instead of returning to the patched Dart function, emulate the
-  // smashed return code pattern and return to the function's caller.
-  __ LeaveDartFrame();
-  __ Ret();
-}
-
-
 //  LR: return address (Dart code).
 //  R5: inline cache data array.
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index c6ca8d7..62e503d 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1889,25 +1889,6 @@
 }
 
 
-//  TOS(0): return address (Dart code).
-void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ pushl(EAX);
-  __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0);
-  __ popl(EAX);
-  __ LeaveFrame();
-
-  // Instead of returning to the patched Dart function, emulate the
-  // smashed return code pattern and return to the function's caller.
-  __ popl(ECX);  // Discard return address to patched dart code.
-  // Execute function epilog code that was smashed in the Dart code.
-  __ LeaveFrame();
-  __ ret();
-}
-
-
 //  ECX: Inline cache data array.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 3fb0b94..464fdef 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -2106,23 +2106,6 @@
 }
 
 
-//  V0: return value.
-void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
-  __ TraceSimMsg("BreakpoingReturnStub");
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ Push(V0);
-  __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0);
-  __ Pop(V0);
-  __ LeaveStubFrame();
-
-  // Instead of returning to the patched Dart function, emulate the
-  // smashed return code pattern and return to the function's caller.
-  __ LeaveDartFrameAndReturn();
-}
-
-
 //  RA: return address (Dart code).
 //  S5: Inline cache data array.
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 3fc862b..e8fa755 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1871,19 +1871,6 @@
 }
 
 
-//  TOS(0): return address (Dart code).
-void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(RAX);
-  __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0);
-  __ popq(RAX);
-  __ LeaveStubFrame();
-  __ popq(R11);  // discard return address of call to this stub.
-  __ LeaveDartFrame();
-  __ ret();
-}
-
-
 //  RBX: Inline cache data array.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index c636537..f529934 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -273,12 +273,13 @@
   V(DartAsync, "dart:async")                                                   \
   V(DartCore, "dart:core")                                                     \
   V(DartCollection, "dart:collection")                                         \
-  V(DartCollectionDev, "dart:_collection-dev")                                 \
   V(DartConvert, "dart:convert")                                               \
+  V(DartInternal, "dart:_internal")                                            \
   V(DartIsolate, "dart:isolate")                                               \
   V(DartMath, "dart:math")                                                     \
   V(DartMirrors, "dart:mirrors")                                               \
   V(DartTypedData, "dart:typed_data")                                          \
+  V(DartVMService, "dart:vmservice")                                           \
   V(_Random, "_Random")                                                        \
   V(_state, "_state")                                                          \
   V(_A, "_A")                                                                  \
@@ -297,6 +298,7 @@
   V(hashCode, "get:hashCode")                                                  \
   V(_leftShiftWithMask32, "_leftShiftWithMask32")                              \
   V(OptimizedOut, "<optimized out>")                                           \
+  V(NotInitialized, "<not initialized>")                                       \
   V(ClassId, "get:_classId")                                                   \
 
 
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index a0b7efd..20f2b47 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -35,7 +35,7 @@
     VisitPointers(p, (p + len - 1));
   }
 
-  void VisitPointer(RawObject** p) { VisitPointers(p , p); }
+  void VisitPointer(RawObject** p) { VisitPointers(p, p); }
 
  private:
   Isolate* isolate_;
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 4257608..ddb0db7 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -13,32 +13,40 @@
     'corelib_patch_cc_file': '<(gen_source_dir)/corelib_patch_gen.cc',
     'collection_cc_file': '<(gen_source_dir)/collection_gen.cc',
     'collection_patch_cc_file': '<(gen_source_dir)/collection_patch_gen.cc',
-    'collection_dev_cc_file': '<(gen_source_dir)/collection_dev_gen.cc',
-    'collection_dev_patch_cc_file': '<(gen_source_dir)/collection_dev_patch_gen.cc',
     'convert_cc_file': '<(gen_source_dir)/convert_gen.cc',
     'convert_patch_cc_file': '<(gen_source_dir)/convert_patch_gen.cc',
+    'internal_cc_file': '<(gen_source_dir)/internal_gen.cc',
+    'internal_patch_cc_file': '<(gen_source_dir)/internal_patch_gen.cc',
+    'isolate_cc_file': '<(gen_source_dir)/isolate_gen.cc',
+    'isolate_patch_cc_file': '<(gen_source_dir)/isolate_patch_gen.cc',
     'math_cc_file': '<(gen_source_dir)/math_gen.cc',
     'math_patch_cc_file': '<(gen_source_dir)/math_patch_gen.cc',
     'mirrors_cc_file': '<(gen_source_dir)/mirrors_gen.cc',
     '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',
-    'typed_data_cc_file': '<(gen_source_dir)/typed_data_gen.cc',
-    'typed_data_patch_cc_file': '<(gen_source_dir)/typed_data_patch_gen.cc',
+    'service_cc_file': '<(gen_source_dir)/service_gen.cc',
     'snapshot_test_dat_file': '<(gen_source_dir)/snapshot_test.dat',
     'snapshot_test_in_dat_file': 'snapshot_test_in.dat',
     'snapshot_test_dart_file': 'snapshot_test.dart',
+    'typed_data_cc_file': '<(gen_source_dir)/typed_data_gen.cc',
+    'typed_data_patch_cc_file': '<(gen_source_dir)/typed_data_patch_gen.cc',
   },
   'targets': [
     {
       'target_name': 'libdart_vm',
       'type': 'static_library',
       'toolsets':['host', 'target'],
+      'dependencies': [
+        'generate_service_cc_file#host'
+      ],
       'includes': [
         'vm_sources.gypi',
         '../platform/platform_headers.gypi',
         '../platform/platform_sources.gypi',
       ],
+      'sources': [
+        # Include generated source files.
+        '<(service_cc_file)',
+      ],
       'sources/': [
         # Exclude all _test.[cc|h] files.
         ['exclude', '_test\\.(cc|h)$'],
@@ -91,14 +99,14 @@
         'generate_corelib_patch_cc_file#host',
         'generate_collection_cc_file#host',
         'generate_collection_patch_cc_file#host',
-        'generate_collection_dev_cc_file#host',
-        'generate_collection_dev_patch_cc_file#host',
         'generate_convert_cc_file#host',
         'generate_convert_patch_cc_file#host',
-        'generate_math_cc_file#host',
-        'generate_math_patch_cc_file#host',
+        'generate_internal_cc_file#host',
+        'generate_internal_patch_cc_file#host',
         'generate_isolate_cc_file#host',
         'generate_isolate_patch_cc_file#host',
+        'generate_math_cc_file#host',
+        'generate_math_patch_cc_file#host',
         'generate_mirrors_cc_file#host',
         'generate_mirrors_patch_cc_file#host',
         'generate_typed_data_cc_file#host',
@@ -122,14 +130,14 @@
         '<(corelib_patch_cc_file)',
         '<(collection_cc_file)',
         '<(collection_patch_cc_file)',
-        '<(collection_dev_cc_file)',
-        '<(collection_dev_patch_cc_file)',
         '<(convert_cc_file)',
         '<(convert_patch_cc_file)',
-        '<(math_cc_file)',
-        '<(math_patch_cc_file)',
+        '<(internal_cc_file)',
+        '<(internal_patch_cc_file)',
         '<(isolate_cc_file)',
         '<(isolate_patch_cc_file)',
+        '<(math_cc_file)',
+        '<(math_patch_cc_file)',
         '<(mirrors_cc_file)',
         '<(mirrors_patch_cc_file)',
         '<(typed_data_cc_file)',
@@ -199,6 +207,206 @@
       ]
     },
     {
+      'target_name': 'generate_async_patch_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the runtime implementation sources.
+        '../lib/async_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_async_patch_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(async_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(async_patch_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::async_patch_paths_',
+            '--library_name', 'dart:async',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(async_patch_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_collection_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the shared collection library sources.
+        '../../sdk/lib/collection/collection_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_collection_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(collection_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(collection_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::collection_source_paths_',
+            '--library_name', 'dart:collection',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(collection_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_collection_patch_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the runtime implementation sources.
+        '../lib/collection_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_collection_patch_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(collection_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(collection_patch_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::collection_patch_paths_',
+            '--library_name', 'dart:collection',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(collection_patch_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_convert_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the shared convert library sources.
+        '../../sdk/lib/convert/convert_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_convert_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(convert_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(convert_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::convert_source_paths_',
+            '--library_name', 'dart:convert',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(convert_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_convert_patch_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the shared convert library sources.
+        '../lib/convert_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_convert_patch_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(convert_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(convert_patch_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::convert_patch_paths_',
+            '--library_name', 'dart:convert',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(convert_patch_cc_file)'' file.'
+        },
+      ]
+    },
+    {
       'target_name': 'generate_corelib_cc_file',
       'type': 'none',
       'toolsets':['host'],
@@ -279,52 +487,12 @@
       ]
     },
     {
-      'target_name': 'generate_collection_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the shared collection library sources.
-        '../../sdk/lib/collection/collection_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_collection_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(collection_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(collection_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::collection_source_paths_',
-            '--library_name', 'dart:collection',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(collection_cc_file)'' file.'
-        },
-      ]
-    },
-    {
-      'target_name': 'generate_collection_dev_patch_cc_file',
+      'target_name': 'generate_internal_patch_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'includes': [
         # Load the runtime implementation sources.
-        '../lib/collection_dev_sources.gypi',
+        '../lib/internal_sources.gypi',
       ],
       'sources/': [
         # Exclude all .[cc|h] files.
@@ -335,36 +503,36 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_collection_dev_patch_cc',
+          'action_name': 'generate_internal_patch_cc',
           'inputs': [
             '../tools/gen_library_src_paths.py',
             '<(libgen_in_cc_file)',
             '<@(_sources)',
           ],
           'outputs': [
-            '<(collection_dev_patch_cc_file)',
+            '<(internal_patch_cc_file)',
           ],
           'action': [
             'python',
             'tools/gen_library_src_paths.py',
-            '--output', '<(collection_dev_patch_cc_file)',
+            '--output', '<(internal_patch_cc_file)',
             '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::collection_dev_patch_paths_',
-            '--library_name', 'dart:_collection-dev',
+            '--var_name', 'dart::Bootstrap::internal_patch_paths_',
+            '--library_name', 'dart:_internal',
             '<@(_sources)',
           ],
-          'message': 'Generating ''<(collection_dev_patch_cc_file)'' file.'
+          'message': 'Generating ''<(internal_patch_cc_file)'' file.'
         },
       ]
     },
     {
-      'target_name': 'generate_collection_dev_cc_file',
+      'target_name': 'generate_internal_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'includes': [
-        # Load the shared collection_dev library sources.
-        '../../sdk/lib/_collection_dev/collection_dev_sources.gypi',
+        # Load the shared internal library sources.
+        '../../sdk/lib/internal/internal_sources.gypi',
       ],
       'sources/': [
         # Exclude all .[cc|h] files.
@@ -375,36 +543,36 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_collection_dev_cc',
+          'action_name': 'generate_internal_cc',
           'inputs': [
             '../tools/gen_library_src_paths.py',
             '<(libgen_in_cc_file)',
             '<@(_sources)',
           ],
           'outputs': [
-            '<(collection_dev_cc_file)',
+            '<(internal_cc_file)',
           ],
           'action': [
             'python',
             'tools/gen_library_src_paths.py',
-            '--output', '<(collection_dev_cc_file)',
+            '--output', '<(internal_cc_file)',
             '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::collection_dev_source_paths_',
-            '--library_name', 'dart:_collection-dev',
+            '--var_name', 'dart::Bootstrap::internal_source_paths_',
+            '--library_name', 'dart:_internal',
             '<@(_sources)',
           ],
-          'message': 'Generating ''<(collection_dev_cc_file)'' file.'
+          'message': 'Generating ''<(internal_cc_file)'' file.'
         },
       ]
     },
     {
-      'target_name': 'generate_convert_cc_file',
+      'target_name': 'generate_isolate_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'includes': [
-        # Load the shared convert library sources.
-        '../../sdk/lib/convert/convert_sources.gypi',
+        # Load the runtime implementation sources.
+        '../../sdk/lib/isolate/isolate_sources.gypi',
       ],
       'sources/': [
         # Exclude all .[cc|h] files.
@@ -415,36 +583,36 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_convert_cc',
+          'action_name': 'generate_isolate_cc',
           'inputs': [
             '../tools/gen_library_src_paths.py',
             '<(libgen_in_cc_file)',
             '<@(_sources)',
           ],
           'outputs': [
-            '<(convert_cc_file)',
+            '<(isolate_cc_file)',
           ],
           'action': [
             'python',
             'tools/gen_library_src_paths.py',
-            '--output', '<(convert_cc_file)',
+            '--output', '<(isolate_cc_file)',
             '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::convert_source_paths_',
-            '--library_name', 'dart:convert',
+            '--var_name', 'dart::Bootstrap::isolate_source_paths_',
+            '--library_name', 'dart:isolate',
             '<@(_sources)',
           ],
-          'message': 'Generating ''<(convert_cc_file)'' file.'
+          'message': 'Generating ''<(isolate_cc_file)'' file.'
         },
       ]
     },
     {
-      'target_name': 'generate_convert_patch_cc_file',
+      'target_name': 'generate_isolate_patch_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'includes': [
-        # Load the shared convert library sources.
-        '../lib/convert_sources.gypi',
+        # Load the runtime implementation sources.
+        '../lib/isolate_sources.gypi',
       ],
       'sources/': [
         # Exclude all .[cc|h] files.
@@ -455,26 +623,26 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_convert_patch_cc',
+          'action_name': 'generate_isolate_patch_cc',
           'inputs': [
             '../tools/gen_library_src_paths.py',
             '<(libgen_in_cc_file)',
             '<@(_sources)',
           ],
           'outputs': [
-            '<(convert_patch_cc_file)',
+            '<(isolate_patch_cc_file)',
           ],
           'action': [
             'python',
             'tools/gen_library_src_paths.py',
-            '--output', '<(convert_patch_cc_file)',
+            '--output', '<(isolate_patch_cc_file)',
             '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::convert_patch_paths_',
-            '--library_name', 'dart:convert',
+            '--var_name', 'dart::Bootstrap::isolate_patch_paths_',
+            '--library_name', 'dart:isolate',
             '<@(_sources)',
           ],
-          'message': 'Generating ''<(convert_patch_cc_file)'' file.'
+          'message': 'Generating ''<(isolate_patch_cc_file)'' file.'
         },
       ]
     },
@@ -639,166 +807,6 @@
       ]
     },
     {
-      'target_name': 'generate_isolate_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the runtime implementation sources.
-        '../../sdk/lib/isolate/isolate_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_isolate_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(isolate_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(isolate_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::isolate_source_paths_',
-            '--library_name', 'dart:isolate',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(isolate_cc_file)'' file.'
-        },
-      ]
-    },
-    {
-      'target_name': 'generate_async_patch_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the runtime implementation sources.
-        '../lib/async_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_async_patch_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(async_patch_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(async_patch_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::async_patch_paths_',
-            '--library_name', 'dart:async',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(async_patch_cc_file)'' file.'
-        },
-      ]
-    },
-    {
-      'target_name': 'generate_collection_patch_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the runtime implementation sources.
-        '../lib/collection_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_collection_patch_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(collection_patch_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(collection_patch_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::collection_patch_paths_',
-            '--library_name', 'dart:collection',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(collection_patch_cc_file)'' file.'
-        },
-      ]
-    },
-    {
-      'target_name': 'generate_isolate_patch_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the runtime implementation sources.
-        '../lib/isolate_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_isolate_patch_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(isolate_patch_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(isolate_patch_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::isolate_patch_paths_',
-            '--library_name', 'dart:isolate',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(isolate_patch_cc_file)'' file.'
-        },
-      ]
-    },
-    {
       'target_name': 'generate_typed_data_cc_file',
       'type': 'none',
       'toolsets':['host'],
@@ -906,5 +914,35 @@
         },
       ]
     },
+    {
+      'target_name': 'generate_service_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        'service_sources.gypi',
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_service_cc',
+          'inputs': [
+            '../tools/create_resources.py',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(service_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_resources.py',
+            '--output', '<(service_cc_file)',
+            '--outer_namespace', 'dart',
+            '--table_name', 'service',
+            '--root_prefix', 'vm/service/',
+            '<@(_sources)'
+          ],
+          'message': 'Generating ''<(service_cc_file)'' file.'
+        },
+      ]
+    },
   ]
 }
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 92c5524..660cbe4 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -186,9 +186,6 @@
     'heap.h',
     'heap_histogram.cc',
     'heap_histogram.h',
-    'heap_profiler.cc',
-    'heap_profiler.h',
-    'heap_profiler_test.cc',
     'heap_test.cc',
     'il_printer.cc',
     'il_printer.h',
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 66325f7..11913ba 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -146,6 +146,13 @@
    */
   final Element methodElement;
 
+  // A [ClosureClassElement] is nested inside a function or initializer in terms
+  // of [enclosingElement], but still has to be treated as a top-level
+  // element.
+  bool isTopLevel() => true;
+
+  get enclosingElement => methodElement;
+
   accept(ElementVisitor visitor) => visitor.visitClosureClassElement(this);
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 7846c9a..417ed7b 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -452,7 +452,7 @@
   // Initialized after mirrorSystemClass has been resolved.
   FunctionElement mirrorSystemGetNameFunction;
 
-  // Initialized when dart:_collection-dev is loaded.
+  // Initialized when dart:_internal is loaded.
   ClassElement symbolImplementationClass;
 
   // Initialized when symbolImplementationClass has been resolved.
@@ -809,7 +809,7 @@
       typedDataLibrary = library;
       typedDataClass =
           findRequiredElement(library, 'TypedData');
-    } else if (uri == new Uri(scheme: 'dart', path: '_collection-dev')) {
+    } else if (uri == new Uri(scheme: 'dart', path: '_internal')) {
       symbolImplementationClass =
           findRequiredElement(library, 'Symbol');
     } else if (uri == new Uri(scheme: 'dart', path: 'async')) {
@@ -1065,9 +1065,7 @@
       // compile-time constants that are metadata.  This means adding
       // something to the resolution queue.  So we cannot wait with
       // this until after the resolution queue is processed.
-      // TODO(ahe): Clean this up, for example, by not enqueueing
-      // classes only used for metadata.
-      deferredLoadTask.findDeferredLibraries(mainApp);
+      deferredLoadTask.ensureMetadataResolved(this);
     }
 
     log('Resolving...');
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index d030524..272fd6a 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -17,6 +17,7 @@
   R visitConstructed(ConstructedConstant constant);
   R visitType(TypeConstant constant);
   R visitInterceptor(InterceptorConstant constant);
+  R visitDummyReceiver(DummyReceiverConstant constant);
 }
 
 abstract class Constant {
@@ -41,6 +42,7 @@
   bool isType() => false;
   bool isSentinel() => false;
   bool isInterceptor() => false;
+  bool isDummyReceiver() => false;
 
   bool isNaN() => false;
   bool isMinusZero() => false;
@@ -538,6 +540,33 @@
   }
 }
 
+class DummyReceiverConstant extends Constant {
+  final ti.TypeMask typeMask;
+
+  DummyReceiverConstant(this.typeMask);
+
+  bool isDummyReceiver() => true;
+
+  bool operator ==(other) {
+    return other is DummyReceiverConstant
+        && typeMask == other.typeMask;
+  }
+
+  get hashCode => typeMask.hashCode;
+
+  List<Constant> getDependencies() => const <Constant>[];
+
+  accept(ConstantVisitor visitor) => visitor.visitDummyReceiver(this);
+
+  DartType computeType(Compiler compiler) => compiler.types.dynamicType;
+
+  ti.TypeMask computeMask(Compiler compiler) => typeMask;
+
+  String toString() {
+    return 'DummyReceiverConstant($typeMask)';
+  }
+}
+
 class ConstructedConstant extends ObjectConstant {
   final List<Constant> fields;
   final int hashCode;
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index f51abf5..2f546dc 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -326,6 +326,8 @@
 
   options.add('--source-map=$sourceMapOut');
 
+  List<String> allOutputFiles = new List<String>();
+
   compilationDone(String code) {
     if (analyzeOnly) return;
     if (code == null) {
@@ -337,7 +339,14 @@
          'compiled ${inputProvider.dartCharactersRead} characters Dart '
          '-> $totalCharactersWritten characters $outputLanguage '
          'in ${relativize(currentDirectory, out, isWindows)}');
-    if (!explicitOut) {
+    if (diagnosticHandler.verbose) {
+      String input = uriPathToNative(arguments[0]);
+      print('Dart file ($input) compiled to $outputLanguage.');
+      print('Wrote the following files:');
+      for (String filename in allOutputFiles) {
+        print("  $filename");
+      }
+    } else if (!explicitOut) {
       String input = uriPathToNative(arguments[0]);
       String output = relativize(currentDirectory, out, isWindows);
       print('Dart file ($input) compiled to $outputLanguage: $output');
@@ -376,11 +385,14 @@
     }
 
     RandomAccessFile output =
-        new File(uriPathToNative(uri.path)).openSync(mode: FileMode.WRITE);
+        new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
+
+    allOutputFiles.add(relativize(currentDirectory, uri, isWindows));
+
     int charactersWritten = 0;
 
     writeStringSync(String data) {
-      // Write the data in chunks of 8kb, otherwise we risk running OOM
+      // Write the data in chunks of 8kb, otherwise we risk running OOM.
       int chunkSize = 8*1024;
 
       int offset = 0;
@@ -445,7 +457,7 @@
   if (uri.scheme != 'file') {
     fail('Error: Unhandled scheme ${uri.scheme}.');
   }
-  var file = new File(uriPathToNative(uri.path)).openSync(mode: FileMode.WRITE);
+  var file = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
   file.writeStringSync(text);
   file.closeSync();
 }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index 2158855..470d9e4 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -88,19 +88,16 @@
     // TODO(smok): Do not rename type if it is in platform library or
     // js-helpers.
     StringBuffer result = new StringBuffer(renameElement(type.element));
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      if (!interfaceType.treatAsRaw) {
-        result.write('<');
-        Link<DartType> argumentsLink = interfaceType.typeArguments;
-        result.write(renameType(argumentsLink.head, renameElement));
-        for (Link<DartType> link = argumentsLink.tail; !link.isEmpty;
-             link = link.tail) {
-          result.write(',');
-          result.write(renameType(link.head, renameElement));
-        }
-        result.write('>');
+    if (type is GenericType && !type.treatAsRaw) {
+      result.write('<');
+      Link<DartType> argumentsLink = type.typeArguments;
+      result.write(renameType(argumentsLink.head, renameElement));
+      for (Link<DartType> link = argumentsLink.tail; !link.isEmpty;
+           link = link.tail) {
+        result.write(',');
+        result.write(renameType(link.head, renameElement));
       }
+      result.write('>');
     }
     return result.toString();
   }
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index 1a182f7..8c0907e 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -1,147 +1,277 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for 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 deferred_load;
 
-import 'dart2jslib.dart'
-       show Compiler,
-            CompilerTask,
-            ConstructedConstant,
-            MessageKind,
-            StringConstant;
+import 'dart2jslib.dart' show
+    Compiler,
+    CompilerTask,
+    Constant,
+    ConstructedConstant,
+    MessageKind,
+    StringConstant,
+    invariant;
 
-import 'elements/elements.dart'
-       show ClassElement,
-            Element,
-            Elements,
-            FunctionElement,
-            LibraryElement,
-            MetadataAnnotation,
-            ScopeContainerElement;
+import 'elements/elements.dart' show
+    Element,
+    ClassElement,
+    ElementKind,
+    Elements,
+    FunctionElement,
+    LibraryElement,
+    MetadataAnnotation,
+    ScopeContainerElement,
+    ClosureContainer;
 
-import 'util/util.dart'
-       show Link;
+import 'util/util.dart' show
+    Link;
 
-import 'tree/tree.dart'
-       show LibraryTag,
-            Node,
-            Visitor;
+import 'util/setlet.dart' show
+    Setlet;
 
-import 'resolution/resolution.dart'
-       show TreeElements;
+import 'tree/tree.dart' show
+    LibraryTag,
+    Node,
+    NewExpression,
+    Import,
+    LiteralString,
+    LiteralDartString;
 
+import 'resolution/resolution.dart' show
+    TreeElements;
+
+import 'mirrors_used.dart' show
+    MirrorUsageAnalyzer,
+    MirrorUsageAnalyzerTask,
+    MirrorUsage;
+
+/// A "hunk" of the program that will be loaded whenever one of its [imports]
+/// are loaded.
+///
+/// Elements that are only used in one deferred import, is in an OutputUnit with
+/// the deferred import as single element in the [imports] set.
+///
+/// Whenever a deferred Element is shared between several deferred imports it is
+/// in an output unit with those imports in the [imports] Set.
+///
+/// OutputUnits are equal if their [imports] are equal.
+class OutputUnit {
+  /// The deferred imports that will load this output unit when one of them is
+  /// loaded.
+  final Setlet<Import> imports = new Setlet<Import>();
+
+  /// A unique name representing this [OutputUnit].
+  /// Based on the set of [imports].
+  String name;
+
+  String toString() => "OutputUnit($name)";
+
+  bool operator==(OutputUnit other) {
+    return imports.length == other.imports.length &&
+        imports.containsAll(other.imports);
+  }
+
+  int get hashCode {
+    int sum = 0;
+    for (Import import in imports) {
+      sum = (sum + import.hashCode) & 0x3FFFFFFF;  // Stay in 30 bit range.
+    }
+    return sum;
+  }
+}
+
+/// For each deferred import, find elements and constants to be loaded when that
+/// import is loaded. Elements that are used by several deferred imports are in
+/// shared OutputUnits.
 class DeferredLoadTask extends CompilerTask {
-  final Set<LibraryElement> deferredLibraries = new Set<LibraryElement>();
-
-  /// Records all elements that are deferred.
-  ///
-  /// Long term, we want to split deferred element into more than one
-  /// file (one for each library that is deferred), and this field
-  /// should become obsolete.
-  final Set<Element> allDeferredElements = new Set<Element>();
-
-  DeferredLoadTask(Compiler compiler) : super(compiler);
-
+  /// The name of this task.
   String get name => 'Deferred Loading';
 
   /// DeferredLibrary from dart:async
   ClassElement get deferredLibraryClass => compiler.deferredLibraryClass;
 
-  bool get areAnyElementsDeferred => !allDeferredElements.isEmpty;
+  /// A synthetic [Import] representing the loading of the main
+  /// program.
+  final Import _fakeMainImport = new Import(null, new LiteralString(null,
+      new LiteralDartString("main")), null, null, null);
+
+  /// The OutputUnit that will be loaded when the program starts.
+  final OutputUnit mainOutputUnit = new OutputUnit();
+
+  /// A set containing (eventually) all output units that will result from the
+  /// program.
+  final Set<OutputUnit> allOutputUnits = new Set<OutputUnit>();
+
+  /// Will be `true` if the program contains deferred libraries.
+  bool splitProgram = false;
+
+  /// A mapping from the name of a [DeferredLibrary] annotation to all dependent
+  /// output units.
+  final Map<String, Set<OutputUnit>> hunksToLoad =
+      new Map<String, Set<OutputUnit>>();
+
+  /// A mapping from elements and constants to their output unit. Query this via
+  /// [outputUnitForElement]
+  final Map<Element, OutputUnit> _elementToOutputUnit =
+      new Map<Element, OutputUnit>();
+
+  /// A mapping from constants to their output unit. Query this via
+  /// [outputUnitForConstant]
+  final Map<Constant, OutputUnit> _constantToOutputUnit =
+      new Map<Constant, OutputUnit>();
+
+  /// All the imports with a [DeferredLibrary] annotation, mapped to the
+  /// [LibraryElement] they import.
+  /// The main library is included in this set for convenience.
+  final Map<Import, LibraryElement> _allDeferredImports =
+      new Map<Import, LibraryElement>();
+
+  // For each deferred import we want to know exactly what elements have to
+  // be loaded.
+  Map<Import, Set<Element>> _importedDeferredBy = null;
+  Map<Import, Set<Constant>> _constantsDeferredBy = null;
+
+  Set<Element> _mainElements = new Set<Element>();
+
+  DeferredLoadTask(Compiler compiler) : super(compiler);
+
+  /// Returns the [OutputUnit] where [element] belongs.
+  OutputUnit outputUnitForElement(Element element) {
+    if (!splitProgram) return mainOutputUnit;
+
+    element = element.implementation;
+    while (!_elementToOutputUnit.containsKey(element)) {
+      element = element.enclosingElement.implementation;
+    }
+    return _elementToOutputUnit[element];
+  }
+
+  /// Returns the [OutputUnit] where [constant] belongs.
+  OutputUnit outputUnitForConstant(Constant constant) {
+    if (!splitProgram) return mainOutputUnit;
+
+    return _constantToOutputUnit[constant];
+  }
 
   bool isDeferred(Element element) {
-    element = element.implementation;
-    return allDeferredElements.contains(element);
+    return outputUnitForElement(element) != mainOutputUnit;
   }
 
-  bool isExplicitlyDeferred(Element element) {
-    element = element.implementation;
-    return deferredLibraries.contains(element.getLibrary());
+  /// Mark that [import] is part of the [OutputputUnit] for [element].
+  ///
+  /// [element] can be either a [Constant] or an [Element].
+  void _addImportToOutputUnitOfElement(Element element, Import import) {
+    // Only one file should be loaded when the program starts, so make
+    // sure that only one OutputUnit is created for [fakeMainImport].
+    if (import == _fakeMainImport) {
+      _elementToOutputUnit[element] = mainOutputUnit;
+    }
+    _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit())
+        .imports.add(import);
   }
 
-  void onResolutionComplete(FunctionElement main) {
-    if (main == null) return;
-    LibraryElement mainApp = main.getLibrary();
-    measureElement(mainApp, () {
-      deferredLibraries.addAll(findDeferredLibraries(mainApp).toList());
-      if (deferredLibraries.isEmpty) return;
+  /// Mark that [import] is part of the [OutputputUnit] for [constant].
+  ///
+  /// [constant] can be either a [Constant] or an [Element].
+  void _addImportToOutputUnitOfConstant(Constant constant, Import import) {
+    // Only one file should be loaded when the program starts, so make
+    // sure that only one OutputUnit is created for [fakeMainImport].
+    if (import == _fakeMainImport) {
+      _constantToOutputUnit[constant] = mainOutputUnit;
+    }
+    _constantToOutputUnit.putIfAbsent(constant, () => new OutputUnit())
+        .imports.add(import);
+  }
 
-      // TODO(ahe): Enforce the following invariants on
-      // [deferredElements] and [eagerElements]:
-      // 1. Only static or top-level elements are recorded.
-      // 2. Only implementation is stored.
-      Map<LibraryElement, Set<Element>> deferredElements =
-          new Map<LibraryElement, Set<Element>>();
-      Set<Element> eagerElements = new Set<Element>();
-
-      // Iterate through live local members of the main script.  Create
-      // a root-set of elements that must be loaded eagerly
-      // (everything that is directly referred to from the main
-      // script, but not imported from a deferred library), as well as
-      // root-sets for deferred libraries.
-      mainApp.forEachLocalMember((Element e) {
-        if (compiler.enqueuer.resolution.isLive(e)) {
-          for (Element dependency in allElementsResolvedFrom(e)) {
-            if (isExplicitlyDeferred(dependency)) {
-              Set<Element> deferredElementsFromLibrary =
-                  deferredElements.putIfAbsent(
-                      dependency.getLibrary(),
-                      () => new Set<Element>());
-              deferredElementsFromLibrary.add(dependency);
-            } else if (dependency.getLibrary() != mainApp) {
-              eagerElements.add(dependency.implementation);
-            }
-          }
-        }
-      });
-
-      // Also add "global" dependencies to the eager root-set.  These
-      // are things that the backend need but cannot associate with a
-      // particular element, for example, startRootIsolate.  This set
-      // also contains elements for which we lack precise information.
-      eagerElements.addAll(compiler.globalDependencies.otherDependencies);
-
-      addTransitiveClosureTo(eagerElements);
-
-      for (Set<Element> e in deferredElements.values) {
-        addTransitiveClosureTo(e);
-        e.removeAll(eagerElements);
-        for (Element element in e) {
-          allDeferredElements.add(element);
-        }
+  /// Answers whether the [import] has a [DeferredLibrary] annotation.
+  bool _isImportDeferred(Import import) {
+    Link<MetadataAnnotation> metadatalist = import.metadata;
+    if (metadatalist == null) return false;
+    for (MetadataAnnotation metadata in metadatalist) {
+      metadata.ensureResolved(compiler);
+      Element element = metadata.value.computeType(compiler).element;
+      if (metadata.value.computeType(compiler).element
+          == deferredLibraryClass) {
+        return true;
       }
-
-      // TODO(ahe): The following code has no effect yet.  I'm
-      // including it as a comment for how to extend this to support
-      // multiple deferred files.
-      Map<Element, List<LibraryElement>> reverseMap =
-          new Map<Element, List<LibraryElement>>();
-
-      deferredElements.forEach((LibraryElement library, Set<Element> map) {
-        for (Element element in map) {
-          List<LibraryElement> libraries =
-              reverseMap.putIfAbsent(element, () => <LibraryElement>[]);
-          libraries.add(library);
-        }
-      });
-
-      // Now compute the output files based on the lists in reverseMap.
-      // TODO(ahe): Do that.
-    });
+    }
+    return false;
   }
 
-  /// Returns all elements in the tree map of [element], but not the
-  /// transitive closure.
-  Set<Element> allElementsResolvedFrom(Element element) {
+  /// Answers whether [element] is explicitly deferred when referred to from
+  /// [library].
+  bool _isExplicitlyDeferred(Element element, LibraryElement library) {
+    Link<Import> imports = _getImports(element, library);
+    // If the element is not imported explicitly, it is implicitly imported
+    // not deferred.
+    if (imports.isEmpty) return false;
+    // An element could potentially be loaded by several imports. If all of them
+    // is explicitly deferred, we say the element is explicitly deferred.
+    // TODO(sigurdm): We might want to give a warning if the imports do not
+    // agree.
+    return imports.every(_isImportDeferred);
+  }
+
+  /// Returns a [Link] of every [Import] that imports [element] into [library].
+  Link<Import> _getImports(Element element, LibraryElement library) {
+    if (!element.isTopLevel()) {
+      element = element.getEnclosingClass();
+    }
+
+    return library.getImportsFor(element);
+  }
+
+  /// Replaces the imports of [outputUnit] with those in
+  /// [replacementImports]. Because mainOutputUnit has a special handling we
+  /// create a new outputUnit instead, and update the mapping from the
+  /// dependency to its outputUnit.
+  void _replaceOutputUnitImports(dynamic dependency,
+                                 OutputUnit outputUnit,
+                                 Iterable<Import> replacementImports) {
+    Map<dynamic, OutputUnit> dependencyToOutputUnit = dependency is Element
+        ? _elementToOutputUnit
+        : _constantToOutputUnit;
+    assert(outputUnit == dependencyToOutputUnit[dependency]);
+    if (outputUnit == mainOutputUnit) {
+      outputUnit = new OutputUnit();
+      dependencyToOutputUnit[dependency] = outputUnit;
+    } else {
+      outputUnit.imports.clear();
+    }
+    outputUnit.imports.addAll(replacementImports);
+  }
+
+  /// Collects all direct dependencies of [element].
+  ///
+  /// The collected dependent elements and constants are are added to
+  /// [elementDependencies] and [constantDependencies] respectively.
+  void _collectDependencies(Element element,
+                            Set<Element> elementDependencies,
+                            Set<Constant> constantDependencies) {
+    TreeElements elements =
+        compiler.enqueuer.resolution.getCachedElements(element);
+    if (elements == null) return;
+    for (Element dependency in elements.allElements) {
+      if (Elements.isLocal(dependency) && !dependency.isFunction()) continue;
+      if (Elements.isUnresolved(dependency)) continue;
+      if (dependency.isStatement()) continue;
+      elementDependencies.add(dependency);
+    }
+    constantDependencies.addAll(elements.allConstants);
+    elementDependencies.addAll(elements.otherDependencies);
+  }
+
+  /// Finds all elements and constants that [element] depends directly on.
+  /// (not the transitive closure.)
+  ///
+  /// Adds the results to [elements] and [constants].
+  void _collectAllElementsAndConstantsResolvedFrom(Element element,
+      Set<Element> elements,
+      Set<Constant> constants) {
     element = element.implementation;
-    Set<Element> result = new Set<Element>();
-    if (element.isGenerativeConstructor()) {
-      // When instantiating a class, we record a reference to the
-      // constructor, not the class itself.  We must add all the
-      // instance members of the constructor's class (see below).
-      result.addAll(
-          allElementsResolvedFrom(element.getEnclosingClass().implementation));
+    for (MetadataAnnotation metadata in element.metadata) {
+      if (metadata.value != null) constants.add(metadata.value);
     }
     if (element.isClass()) {
       // If we see a class, add everything its instance members refer
@@ -149,95 +279,360 @@
       ClassElement cls = element.declaration;
       cls.forEachLocalMember((Element e) {
         if (!e.isInstanceMember()) return;
-        result.addAll(DependencyCollector.collect(e.implementation, compiler));
+        _collectDependencies(e.implementation, elements, constants);
       });
       if (cls.implementation != cls) {
         // TODO(ahe): Why doesn't ClassElement.forEachLocalMember do this?
         cls.implementation.forEachLocalMember((Element e) {
           if (!e.isInstanceMember()) return;
-          result.addAll(DependencyCollector.collect(e.implementation,
-                                                    compiler));
+          _collectDependencies(e.implementation, elements, constants);
         });
       }
-      for (var type in cls.allSupertypes) {
-        result.add(type.element.implementation);
+      for (var type in cls.implementation.allSupertypes) {
+        elements.add(type.element.implementation);
       }
-      result.add(cls.implementation);
-    } else if (Elements.isStaticOrTopLevel(element)
-               || element.isConstructor()) {
-      result.addAll(DependencyCollector.collect(element, compiler));
+      elements.add(cls.implementation);
+    } else if (Elements.isStaticOrTopLevel(element) ||
+               element.isConstructor()) {
+      _collectDependencies(element, elements, constants);
     }
+    if (element.isGenerativeConstructor()) {
+      // When instantiating a class, we record a reference to the
+      // constructor, not the class itself.  We must add all the
+      // instance members of the constructor's class.
+      ClassElement implementation =
+          element.getEnclosingClass().implementation;
+      _collectAllElementsAndConstantsResolvedFrom(
+          implementation, elements, constants);
+    }
+
     // Other elements, in particular instance members, are ignored as
     // they are processed as part of the class.
+  }
+
+  /// Returns the transitive closure of all libraries that are imported
+  /// from root without DeferredLibrary annotations.
+  Set<LibraryElement> _nonDeferredReachableLibraries(LibraryElement root) {
+    Set<LibraryElement> result = new Set<LibraryElement>();
+
+    void traverseLibrary(LibraryElement library) {
+      if (result.contains(library)) return;
+      result.add(library);
+      // TODO(sigurdm): Make helper getLibraryImportTags when tags is changed to
+      // be a List instead of a Link.
+      for (LibraryTag tag in library.tags) {
+        if (tag is! Import) continue;
+        Import import = tag;
+        if (!_isImportDeferred(import)) {
+          LibraryElement importedLibrary = library.getLibraryFromTag(tag);
+          traverseLibrary(importedLibrary);
+        }
+      }
+    }
+    traverseLibrary(root);
     return result;
   }
 
-  void addTransitiveClosureTo(Set<Element> elements) {
-    Set<Element> workSet = new Set.from(elements);
-    Set<Element> closure = new Set<Element>();
-    while (!workSet.isEmpty) {
-      Element current = workSet.first;
-      workSet.remove(current);
-      if (closure.contains(current)) continue;
-      workSet.addAll(allElementsResolvedFrom(current));
-      closure.add(current);
+  /// Recursively traverses the graph of dependencies from [element], mapping
+  /// deferred imports to each dependency it needs in the sets
+  /// [_importedDeferredBy] and [_constantsDeferredBy].
+  void _mapDependencies(Element element, Import import) {
+    Set<Element> elements = _importedDeferredBy.putIfAbsent(import,
+        () => new Set<Element>());
+    Set<Constant> constants = _constantsDeferredBy.putIfAbsent(import,
+        () => new Set<Constant>());
+
+    if (elements.contains(element)) return;
+    // Anything used directly by main will be loaded from the start
+    // We do not need to traverse it again.
+    if (import != _fakeMainImport && _mainElements.contains(element)) return;
+
+    // Here we modify [_importedDeferredBy].
+    elements.add(element);
+
+    Set<Element> dependentElements = new Set<Element>();
+
+    // This call can modify [_importedDeferredBy] and [_constantsDeferredBy].
+    _collectAllElementsAndConstantsResolvedFrom(
+        element, dependentElements, constants);
+
+    LibraryElement library = element.getLibrary();
+    for (Element dependency in dependentElements) {
+      if (_isExplicitlyDeferred(dependency, library)) {
+        for (Import deferredImport in _getImports(dependency, library)) {
+          _mapDependencies(dependency, deferredImport);
+        };
+      } else {
+        _mapDependencies(dependency, import);
+      }
     }
-    elements.addAll(closure);
   }
 
-  Link<LibraryElement> findDeferredLibraries(LibraryElement library) {
-    Link<LibraryElement> link = const Link<LibraryElement>();
-    for (LibraryTag tag in library.tags) {
-      // TODO(ahe): This iterates over parts and exports as well, but should
-      // only iterate over imports.
-      Link<MetadataAnnotation> metadata = tag.metadata;
-      if (metadata == null) continue;
-      for (MetadataAnnotation metadata in tag.metadata) {
-        metadata.ensureResolved(compiler);
-        Element element = metadata.value.computeType(compiler).element;
-        if (element == deferredLibraryClass) {
-          ConstructedConstant value = metadata.value;
-          StringConstant nameField = value.fields[0];
-          String expectedName = nameField.toDartString().slowToString();
-          LibraryElement deferredLibrary = library.getLibraryFromTag(tag);
-          link = link.prepend(deferredLibrary);
-          String actualName = deferredLibrary.getLibraryOrScriptName();
-          if (expectedName != actualName) {
-            compiler.reportError(
-                metadata,
-                MessageKind.DEFERRED_LIBRARY_NAME_MISMATCH,
-                { 'expectedName': expectedName, 'actualName': actualName });
+  /// Adds extra dependencies coming from mirror usage.
+  ///
+  /// The elements are added with [_mapDependencies].
+  void _addMirrorElements() {
+    MirrorUsageAnalyzerTask mirrorTask = compiler.mirrorUsageAnalyzerTask;
+    // For each import we record all mirrors-used elements from all the
+    // libraries reached directly from that import.
+    for (Import deferredImport in _allDeferredImports.keys) {
+      LibraryElement deferredLibrary = _allDeferredImports[deferredImport];
+      for (LibraryElement library in
+          _nonDeferredReachableLibraries(deferredLibrary)) {
+        if (mirrorTask.librariesWithUsage.contains(library)) {
+
+          Map<LibraryElement, List<MirrorUsage>> mirrorsResult =
+              mirrorTask.analyzer.collectMirrorsUsedAnnotation();
+
+          // If there is a MirrorsUsed annotation we add only the needed
+          // things to the output units for the library.
+          List<MirrorUsage> mirrorUsages = mirrorsResult[library];
+          if (mirrorUsages == null) continue;
+          for (MirrorUsage usage in mirrorUsages) {
+            if (usage.targets != null) {
+              for (Element dependency in usage.targets) {
+                _mapDependencies(dependency, deferredImport);
+              }
+            }
+            if (usage.metaTargets != null) {
+              for (Element dependency in usage.metaTargets) {
+                _mapDependencies(dependency, deferredImport);
+              }
+            }
+          }
+        } else {
+          // If there is no MirrorsUsed annotation we add _everything_ to
+          // the output units for the library.
+
+          // TODO(sigurdm): This is too expensive.
+          // Plan: If mirrors are used without MirrorsUsed, create an
+          // "EverythingElse" library that contains all elements that are
+          // not referred by main or deferred libraries that don't contain
+          // mirrors (without MirrorsUsed).
+          //
+          // So basically we want:
+          //   mainImport
+          //   deferredA
+          //   deferredB
+          //   deferredCwithMirrorsUsed
+          //   deferredEverythingElse
+          //
+          // Where deferredEverythingElse will be loaded for *all* libraries
+          // that contain a mirror usage without MirrorsUsed.
+          //   When loading the deferredEverythingElse also load all other
+          //   deferred libraries at the same time.
+          bool usesMirrors = false;
+          for (LibraryTag tag in library.tags) {
+            if (tag is! Import) continue;
+            if (library.getLibraryFromTag(tag) == compiler.mirrorsLibrary) {
+              usesMirrors = true;
+              break;
+            }
+          }
+          if (usesMirrors) {
+            for (Link link in compiler.enqueuer.allElementsByName.values) {
+              for (Element dependency in link) {
+                _mapDependencies(dependency, deferredImport);
+              }
+            }
           }
         }
       }
     }
-    return link;
-  }
-}
-
-class DependencyCollector extends Visitor {
-  final Set<Element> dependencies = new Set<Element>();
-  final TreeElements elements;
-  final Compiler compiler;
-
-  DependencyCollector(this.elements, this.compiler);
-
-  visitNode(Node node) {
-    node.visitChildren(this);
-    Element dependency = elements[node];
-    if (Elements.isUnresolved(dependency)) return;
-    dependencies.add(dependency.implementation);
   }
 
-  static Set<Element> collect(Element element, Compiler compiler) {
-    TreeElements elements =
-        compiler.enqueuer.resolution.getCachedElements(element);
-    if (elements == null) return new Set<Element>();
-    Node node = element.parseNode(compiler);
-    if (node == null) return new Set<Element>();
-    var collector = new DependencyCollector(elements, compiler);
-    node.accept(collector);
-    collector.dependencies.addAll(elements.otherDependencies);
-    return collector.dependencies;
+  /// Goes through [allConstants] and adjusts their outputUnits.
+  void _adjustConstantsOutputUnit(Set<Constant> allConstants) {
+    // A constant has three dependencies:
+    // 1- the libraries it is used in.
+    // 2- its class.
+    // 3- its arguments.
+    // The constant should only be loaded if all three dependencies are
+    // loaded.
+    // TODO(floitsch): only load constants when all three dependencies are
+    // satisfied.
+    //
+    // So far we only looked at where the constants were used. For now, we
+    // use a simplified approach to fix this (partially): if the current
+    // library is not deferred, only look at the class (2). Otherwise store
+    // the constant in the current (deferred) library.
+    for (Constant constant in allConstants) {
+      // If the constant is not a "constructed" constant, it can stay where
+      // it is.
+      if (!constant.isConstructedObject()) continue;
+      OutputUnit constantUnit = _constantToOutputUnit[constant];
+      Setlet<Import> constantImports = constantUnit.imports;
+      ConstructedConstant constructed = constant;
+      Element classElement = constructed.type.element;
+      OutputUnit classUnit = _elementToOutputUnit[classElement];
+      // This happens with classes that are only used as annotations.
+      // TODO(sigurdm): Find out if we can use a specific check for this.
+      if (classUnit == null) continue;
+      Setlet<Import> classImports = classUnit.imports;
+      // The class exists in the main-unit. Just leave the constant where it
+      // is. We know that the constructor will be available.
+      if (classImports.length == 1 && classImports.single == _fakeMainImport) {
+        continue;
+      }
+      // The class is loaded for all imports in the classImport-set.
+      // If the constant's imports are included in the class' set, we can
+      // keep the constant unit as is.
+      // If the constant is used otherwise, we need to make sure that the
+      // class is available before constructing the constant.
+      if (classImports.containsAll(constantImports)) continue;
+      // We could now just copy the OutputUnit from the class to the output
+      // unit of the constant, but we prefer separate instances.
+      // Replace the imports of the constant to match the ones of the class.
+      _replaceOutputUnitImports(constant, constantUnit, classImports);
+    }
+  }
+
+  /// Computes a unique string for the name field for each outputUnit.
+  ///
+  /// Also sets up the [hunksToLoad] mapping.
+  void _assignNamesToOutputUnits(Set<OutputUnit> allOutputUnits) {
+    Map<Import, String> deferNameCache = new Map<Import, String>();
+    // Finds the first argument to the [DeferredLibrary] annotation
+    String importDeferName(Import import) {
+      if (deferNameCache.containsKey(import)) return deferNameCache[import];
+      if (import == _fakeMainImport) return "main";
+      Link<MetadataAnnotation> metadatas = import.metadata;
+      assert(metadatas != null);
+      for (MetadataAnnotation metadata in metadatas) {
+        metadata.ensureResolved(compiler);
+        Element element = metadata.value.computeType(compiler).element;
+        if (metadata.value.computeType(compiler).element ==
+            deferredLibraryClass) {
+          ConstructedConstant constant = metadata.value;
+          StringConstant s = constant.fields[0];
+          String result = s.value.slowToString();
+          deferNameCache[import] = result;
+          return result;
+        }
+      }
+      assert(false);
+    }
+
+    Set<String> usedNames = new Set<String>();
+    Map<OutputUnit, String> generatedNames = new Map<OutputUnit, String>();
+
+    void computeOutputUnitName(OutputUnit outputUnit) {
+      if (generatedNames[outputUnit] != null) return;
+      String suggestedName = outputUnit.imports.map((import) {
+        return importDeferName(import);
+      }).join('_');
+      if (!usedNames.contains(suggestedName)) {
+        outputUnit.name = suggestedName;
+      } else {
+        int counter = 0;
+        while (usedNames.contains("$suggestedName$counter")) {
+          counter++;
+        }
+        outputUnit.name = "$suggestedName$counter";
+      }
+      generatedNames[outputUnit] = outputUnit.name;
+    }
+
+    for (OutputUnit outputUnit in allOutputUnits) {
+      computeOutputUnitName(outputUnit);
+    }
+
+    // For each deferred import we find out which outputUnits to load.
+    for (Import import in _allDeferredImports.keys) {
+      hunksToLoad[importDeferName(import)] = new Set<OutputUnit>();
+      for (OutputUnit outputUnit in allOutputUnits) {
+        if (outputUnit == mainOutputUnit) continue;
+        hunksToLoad[importDeferName(import)].add(outputUnit);
+      }
+    }
+  }
+
+  void onResolutionComplete(FunctionElement main) {
+    if (!splitProgram) {
+      allOutputUnits.add(mainOutputUnit);
+      return;
+    }
+    if (main == null) return;
+    LibraryElement mainLibrary = main.getLibrary();
+    _importedDeferredBy = new Map<Import, Set<Element>>();
+    _constantsDeferredBy = new Map<Import, Set<Constant>>();
+    _importedDeferredBy[_fakeMainImport] = _mainElements;
+
+    measureElement(mainLibrary, () {
+
+      // Starting from main, traverse the program and find all dependencies.
+      _mapDependencies(compiler.mainFunction, _fakeMainImport);
+
+      // Also add "global" dependencies to the main OutputUnit.  These are
+      // things that the backend need but cannot associate with a particular
+      // element, for example, startRootIsolate.  This set also contains
+      // elements for which we lack precise information.
+      for (Element element in compiler.globalDependencies.otherDependencies) {
+        _mapDependencies(element, _fakeMainImport);
+      }
+
+      // Now check to see if we have to add more elements due to mirrors.
+      if (compiler.mirrorsLibrary != null) {
+        _addMirrorElements();
+      }
+
+      Set<Constant> allConstants = new Set<Constant>();
+      // Reverse the mapping. For each element record an OutputUnit collecting
+      // all deferred imports using this element. Same for constants.
+      for (Import import in _importedDeferredBy.keys) {
+        for (Element element in _importedDeferredBy[import]) {
+          _addImportToOutputUnitOfElement(element, import);
+        }
+        for (Constant constant in _constantsDeferredBy[import]) {
+          allConstants.add(constant);
+          _addImportToOutputUnitOfConstant(constant, import);
+        }
+      }
+
+      // Release maps;
+      _importedDeferredBy = null;
+      _constantsDeferredBy = null;
+
+      _adjustConstantsOutputUnit(allConstants);
+
+      // Find all the output units we have used.
+      // Also generate a unique name for each OutputUnit.
+      for (OutputUnit outputUnit in _elementToOutputUnit.values) {
+        allOutputUnits.add(outputUnit);
+      }
+      for (OutputUnit outputUnit in _constantToOutputUnit.values) {
+        allOutputUnits.add(outputUnit);
+      }
+
+      _assignNamesToOutputUnits(allOutputUnits);
+    });
+  }
+
+  void ensureMetadataResolved(Compiler compiler) {
+    _allDeferredImports[_fakeMainImport] = compiler.mainApp;
+    bool deferredUsedFromMain = false;
+    var lastDeferred;
+    for (LibraryElement library in compiler.libraries.values) {
+      // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List
+      // instead of a Link.
+      for (LibraryTag tag in library.tags) {
+        if (tag is! Import) continue;
+        Import import = tag;
+        if (_isImportDeferred(import)) {
+          splitProgram = true;
+          _allDeferredImports[tag] = library.getLibraryFromTag(tag);
+          lastDeferred = import.metadata.first;
+          if (library == compiler.mainApp) {
+            deferredUsedFromMain = true;
+          }
+        }
+      }
+    }
+    if (splitProgram && !deferredUsedFromMain) {
+      compiler.reportInfo(
+          lastDeferred,
+          MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN);
+      splitProgram = false;
+    }
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 693e4af..5b80da6 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -210,6 +210,12 @@
   bool isAmbiguous();
   bool isWarnOnUse();
 
+  /// Returns true if this [Element] is a top level element.
+  /// That is, if it is not defined within the scope of a class.
+  ///
+  /// This means whether the enclosing element is a compilation unit.
+  /// With the exception of [ClosureClassElement] that is considered top level
+  /// as all other classes.
   bool isTopLevel();
   bool isAssignable();
   bool isNative();
@@ -707,6 +713,9 @@
   Element findExported(String elementName);
   void forEachExport(f(Element element));
 
+  /// Returns the imports that import element into this library.
+  Link<Import> getImportsFor(Element element);
+
   bool hasLibraryName();
   String getLibraryName();
   String getLibraryOrScriptName();
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 78ad547..0aa0c27 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -931,6 +931,8 @@
     exports.forEach((Element e) => f(e));
   }
 
+  Link<Import> getImportsFor(Element element) => importers.getImports(element);
+
   void forEachLocalMember(f(Element element)) {
     if (isPatch) {
       // Patch libraries traverse both origin and injected members.
@@ -971,6 +973,9 @@
    * 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.
+   *
+   * Note: the returned filename will still be escaped ("a%20b.dart" instead of
+   * "a b.dart").
    */
   String getLibraryOrScriptName() {
     if (libraryTag != null) {
@@ -1627,6 +1632,8 @@
 
   Token position() => constructor.position();
 
+  Element getOutermostEnclosingMemberOrTopLevel() => constructor;
+
   accept(ElementVisitor visitor) => visitor.visitConstructorBodyElement(this);
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 986ebec..2be6abe 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -622,6 +622,7 @@
       throw new SpannableAssertionFailure(element,
           "Resolution work list is closed. Trying to add $element.");
     }
+
     compiler.world.registerUsedElement(element);
 
     queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator()));
@@ -662,12 +663,13 @@
 
   void enableIsolateSupport(LibraryElement element) {
     compiler.isolateLibrary = element.patch;
-    var startRootIsolate =
-        compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE);
-    addToWorkList(startRootIsolate);
-    compiler.globalDependencies.registerDependency(startRootIsolate);
-    addToWorkList(compiler.isolateHelperLibrary.find('_currentIsolate'));
-    addToWorkList(compiler.isolateHelperLibrary.find('_callInIsolate'));
+    for (String name in const [Compiler.START_ROOT_ISOLATE,
+                               '_currentIsolate',
+                               '_callInIsolate']) {
+      Element element = compiler.isolateHelperLibrary.find(name);
+      addToWorkList(element);
+      compiler.globalDependencies.registerDependency(element);
+    }
   }
 
   void enableNoSuchMethod(Element element) {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart
index 3d41263..0814f6e 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/closure_tracer.dart
@@ -5,17 +5,18 @@
 part of type_graph_inferrer;
 
 class ClosureTracerVisitor extends TracerVisitor {
-  ClosureTracerVisitor(tracedType, inferrer) : super(tracedType, inferrer);
+  final FunctionElement tracedElement;
+
+  ClosureTracerVisitor(this.tracedElement, tracedType, inferrer)
+      : super(tracedType, inferrer);
 
   void run() {
-    ClosureTypeInformation closure = tracedType;
-    FunctionElement element = closure.element;
-    element.functionSignature.forEachParameter((Element parameter) {
+    tracedElement.functionSignature.forEachParameter((Element parameter) {
       ElementTypeInformation info = inferrer.types.getInferredTypeOf(parameter);
       info.abandonInferencing = false;
     });
     analyze();
-    element.functionSignature.forEachParameter((Element parameter) {
+    tracedElement.functionSignature.forEachParameter((Element parameter) {
       ElementTypeInformation info = inferrer.types.getInferredTypeOf(parameter);
       if (continueAnalyzing) {
         info.disableHandleSpecialCases = true;
@@ -30,12 +31,10 @@
   }
 
   void analyzeCall(CallSiteTypeInformation info) {
-    ClosureTypeInformation closure = tracedType;
-    FunctionElement element = closure.element;
     Selector selector = info.selector;
-    if (!selector.signatureApplies(element, compiler)) return;
+    if (!selector.signatureApplies(tracedElement, compiler)) return;
     inferrer.updateParameterAssignments(
-        info, element, info.arguments, selector, remove: false,
+        info, tracedElement, info.arguments, selector, remove: false,
         addToQueue: false);
   }
 
@@ -51,10 +50,16 @@
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
     super.visitStaticCallSiteTypeInformation(info);
     Element called = info.calledElement;
-    if (called.isForeign(compiler) && called.name == 'JS') {
-      bailout('Used in JS ${info.call}');
+    if (called.isForeign(compiler)) {
+      String name = called.name;
+      if (name == 'JS' || name == 'DART_CLOSURE_TO_JS') {
+        bailout('Used in JS ${info.call}');
+      }
     }
-    if (inferrer.types.getInferredTypeOf(called) == currentUser) {
+    if (called.isGetter()
+        && info.selector != null
+        && info.selector.isCall()
+        && inferrer.types.getInferredTypeOf(called) == currentUser) {
       // This node can be a closure call as well. For example, `foo()`
       // where `foo` is a getter.
       analyzeCall(info);
@@ -77,3 +82,17 @@
     }
   }
 }
+
+class StaticTearOffClosureTracerVisitor extends ClosureTracerVisitor {
+  StaticTearOffClosureTracerVisitor(tracedElement, tracedType, inferrer)
+      : super(tracedElement, tracedType, inferrer);
+
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    super.visitStaticCallSiteTypeInformation(info);
+    if (info.calledElement == tracedElement
+        && info.selector != null
+        && info.selector.isGetter()) {
+      addNewEscapeInformation(info);
+    }
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index 6f17205..b568d03 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -59,9 +59,8 @@
   final Map<Node, TypeInformation> allocatedLists =
       new Map<Node, TypeInformation>();
 
-  /// [ClosureTypeInformation] for allocated closures.
-  final Map<Node, TypeInformation> allocatedClosures =
-      new Map<Node, TypeInformation>();
+  /// Closures found during the analysis.
+  final Set<TypeInformation> allocatedClosures = new Set<TypeInformation>();
 
   /// Cache of [ConcreteTypeInformation].
   final Map<TypeMask, TypeInformation> concreteTypes =
@@ -307,8 +306,9 @@
   }
 
   TypeInformation allocateClosure(Node node, Element element) {
-    return allocatedClosures[node] =
-        new ClosureTypeInformation(node, element);
+    TypeInformation result = new ClosureTypeInformation(node, element);
+    allocatedClosures.add(result);
+    return result;
   }
 
   TypeInformation allocateMap(TypeInformation keyType,
@@ -486,8 +486,10 @@
       workQueue.add(info.elementType);
     });
 
-    types.allocatedClosures.values.forEach((ClosureTypeInformation info) {
-      ClosureTracerVisitor tracer = new ClosureTracerVisitor(info, this);
+    types.allocatedClosures.forEach((info) {
+      ClosureTracerVisitor tracer = info is ClosureTypeInformation
+          ? new ClosureTracerVisitor(info.element, info, this)
+          : new StaticTearOffClosureTracerVisitor(info.element, info, this);
       tracer.run();
       if (!tracer.continueAnalyzing) return;
       FunctionElement element = info.element;
@@ -626,7 +628,7 @@
   void buildWorkQueue() {
     workQueue.addAll(types.typeInformations.values);
     workQueue.addAll(types.allocatedTypes);
-    workQueue.addAll(types.allocatedClosures.values);
+    workQueue.addAll(types.allocatedClosures);
     workQueue.addAll(allocatedCalls);
   }
 
@@ -659,11 +661,14 @@
         info.closurizedCount--;
       } else {
         info.closurizedCount++;
+        if (Elements.isStaticOrTopLevel(callee)) {
+          types.allocatedClosures.add(info);
+        }
         FunctionElement function = callee.implementation;
         FunctionSignature signature = function.computeSignature(compiler);
         signature.forEachParameter((Element parameter) {
           ElementTypeInformation info = types.getInferredTypeOf(parameter);
-          info.giveUp(this);
+          info.giveUp(this, clearAssignments: false);
           if (addToQueue) workQueue.addAll(info.users);
         });
       }
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 fa0082a..bd34d0c 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -66,10 +66,16 @@
     users.remove(user);
   }
 
+  static final STOP_TRACKING_ASSIGNMENTS_MARKER =  const <TypeInformation>[];
+
+  bool areAssignmentsTracked() {
+    return assignments != STOP_TRACKING_ASSIGNMENTS_MARKER;
+  }
+
   void addAssignment(TypeInformation assignment) {
     // Cheap one-level cycle detection.
     if (assignment == this) return;
-    if (!abandonInferencing) {
+    if (areAssignmentsTracked()) {
       assignments.add(assignment);
     }
     // Even if we abandon inferencing on this [TypeInformation] we
@@ -104,7 +110,7 @@
   }
 
   void clear() {
-    assignments = const <TypeInformation>[];
+    assignments = STOP_TRACKING_ASSIGNMENTS_MARKER;
     users = const <TypeInformation>[];
   }
 
@@ -135,7 +141,7 @@
   void stabilize(TypeGraphInferrerEngine inferrer) {
     removeAndClearReferences(inferrer);
     users = const <TypeInformation>[];
-    assignments = const <TypeInformation>[];
+    assignments = STOP_TRACKING_ASSIGNMENTS_MARKER;
     abandonInferencing = true;
     isStable = true;
   }
@@ -388,6 +394,10 @@
         && !(element.modifiers.isConst() || element.modifiers.isFinal())) {
       return false;
     }
+    // If the method is closurized, the closure tracing phase will go
+    // through the users.
+    if (closurizedCount != 0) return false;
+
     return super.hasStableType(inferrer);
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
index 925841e..94b0810 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
@@ -95,7 +95,7 @@
         compiler.enableConcreteTypeInference) {
       return false;
     }
-    return true;
+    return const bool.fromEnvironment('enable_ir', defaultValue: true);
   }
 
   bool canBuild(Element element) {
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
index 964b822..bd79382 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
@@ -8,7 +8,8 @@
 import '../dart2jslib.dart' show
     Constant, FalseConstant, TrueConstant, IntConstant, DoubleConstant,
     StringConstant, NullConstant, ListConstant, MapConstant,
-    InterceptorConstant, FunctionConstant, TypeConstant, ConstructedConstant,
+    InterceptorConstant, DummyReceiverConstant, FunctionConstant, TypeConstant,
+    ConstructedConstant,
     ConstantVisitor, ConstantSystem,
     Compiler;
 import 'dart:typed_data' show ByteData, Endianness, Uint8List;
@@ -461,6 +462,7 @@
   void visitList(ListConstant constant) => abort(constant);
   void visitMap(MapConstant constant) => abort(constant);
   void visitInterceptor(InterceptorConstant constant) => abort(constant);
+  void visitDummyReceiver(DummyReceiverConstant constant) => abort(constant);
   void visitFunction(FunctionConstant constant) => abort(constant);
   void visitType(TypeConstant constant) => abort(constant);
   void visitConstructed(ConstructedConstant constant) => abort(constant);
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index f5a51a4..56bf967 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -165,11 +165,20 @@
    * know whether a send must be intercepted or not.
    */
   final Map<String, Set<Element>> interceptedElements;
-  // TODO(sra): Not all methods in the Set always require an interceptor.  A
-  // method may be mixed into a true interceptor *and* a plain class. For the
-  // method to work on the interceptor class it needs to use the explicit
-  // receiver.  This constrains the call on a known plain receiver to pass the
-  // explicit receiver.  https://code.google.com/p/dart/issues/detail?id=8942
+
+  /**
+   * The members of mixin classes that are mixed into an instantiated
+   * interceptor class.  This is a cached subset of [interceptedElements].
+   *
+   * Mixin methods are not specialized for the class they are mixed into.
+   * Methods mixed into intercepted classes thus always make use of the explicit
+   * receiver argument, even when mixed into non-interceptor classes.
+   *
+   * These members must be invoked with a correct explicit receiver even when
+   * the receiver is not an intercepted class.
+   */
+  final Map<String, Set<Element>> interceptedMixinElements =
+      new Map<String, Set<Element>>();
 
   /**
    * A map of specialized versions of the [getInterceptorMethod].
@@ -187,10 +196,11 @@
   final Set<ClassElement> _interceptedClasses = new Set<ClassElement>();
 
   /**
-   * Set of classes used as mixins on native classes.  Methods on these classes
-   * might also be mixed in to non-native classes.
+   * Set of classes used as mixins on intercepted (native and primitive)
+   * classes.  Methods on these classes might also be mixed in to regular Dart
+   * (unintercepted) classes.
    */
-  final Set<ClassElement> classesMixedIntoNativeClasses =
+  final Set<ClassElement> classesMixedIntoInterceptedClasses =
       new Set<ClassElement>();
 
   /**
@@ -328,7 +338,7 @@
     if (element == null) return false;
     if (Elements.isNativeOrExtendsNative(element)) return true;
     if (interceptedClasses.contains(element)) return true;
-    if (classesMixedIntoNativeClasses.contains(element)) return true;
+    if (classesMixedIntoInterceptedClasses.contains(element)) return true;
     return false;
   }
 
@@ -368,6 +378,29 @@
     return interceptedElements[selector.name] != null;
   }
 
+  /**
+   * Returns `true` iff [selector] matches an element defined in a class mixed
+   * into an intercepted class.  These selectors are not eligible for the 'dummy
+   * explicit receiver' optimization.
+   */
+  bool isInterceptedMixinSelector(Selector selector) {
+    Set<Element> elements = interceptedMixinElements.putIfAbsent(
+        selector.name,
+        () {
+          Set<Element> elements = interceptedElements[selector.name];
+          if (elements == null) return null;
+          return elements
+              .where((element) =>
+                  classesMixedIntoInterceptedClasses.contains(
+                      element.getEnclosingClass()))
+              .toSet();
+        });
+
+    if (elements == null) return false;
+    if (elements.isEmpty) return false;
+    return elements.any((element) => selector.applies(element, compiler));
+  }
+
   final Map<String, Set<ClassElement>> interceptedClassesCache =
       new Map<String, Set<ClassElement>>();
 
@@ -388,7 +421,7 @@
             || interceptedClasses.contains(classElement)) {
           result.add(classElement);
         }
-        if (classesMixedIntoNativeClasses.contains(classElement)) {
+        if (classesMixedIntoInterceptedClasses.contains(classElement)) {
           Set<ClassElement> nativeSubclasses =
               nativeSubclassesOfMixin(classElement);
           if (nativeSubclasses != null) result.addAll(nativeSubclasses);
@@ -462,6 +495,7 @@
     implementationClasses[compiler.doubleClass] = jsDoubleClass;
     implementationClasses[compiler.stringClass] = jsStringClass;
     implementationClasses[compiler.listClass] = jsArrayClass;
+    implementationClasses[compiler.nullClass] = jsNullClass;
 
     jsIndexableClass = compiler.findInterceptor('JSIndexable');
     jsMutableIndexableClass = compiler.findInterceptor('JSMutableIndexable');
@@ -562,7 +596,7 @@
       for (; cls != null; cls = cls.superclass) {
         if (cls.isMixinApplication) {
           MixinApplicationElement mixinApplication = cls;
-          classesMixedIntoNativeClasses.add(mixinApplication.mixin);
+          classesMixedIntoInterceptedClasses.add(mixinApplication.mixin);
         }
       }
     }
@@ -1008,33 +1042,15 @@
   }
 
   void registerRequiredType(DartType type, Element enclosingElement) {
-    /**
-     * If [argument] has type variables or is a type variable, this
-     * method registers a RTI dependency between the class where the
-     * type variable is defined (that is the enclosing class of the
-     * current element being resolved) and the class of [annotation].
-     * If the class of [annotation] requires RTI, then the class of
-     * the type variable does too.
-     */
-    void analyzeTypeArgument(DartType annotation, DartType argument) {
-      if (argument == null) return;
-      if (argument.element.isTypeVariable()) {
-        ClassElement enclosing = argument.element.getEnclosingClass();
-        assert(enclosing == enclosingElement.getEnclosingClass().declaration);
-        rti.registerRtiDependency(annotation.element, enclosing);
-      } else if (argument is InterfaceType) {
-        InterfaceType type = argument;
-        type.typeArguments.forEach((DartType argument) {
-          analyzeTypeArgument(annotation, argument);
-        });
-      }
-    }
-
-    if (type is InterfaceType) {
-      InterfaceType itf = type;
-      itf.typeArguments.forEach((DartType argument) {
-        analyzeTypeArgument(type, argument);
-      });
+    // If [argument] has type variables or is a type variable, this method
+    // registers a RTI dependency between the class where the type variable is
+    // defined (that is the enclosing class of the current element being
+    // resolved) and the class of [type]. If the class of [type] requires RTI,
+    // then the class of the type variable does too.
+    ClassElement contextClass = Types.getClassContext(type);
+    if (contextClass != null) {
+      assert(contextClass == enclosingElement.getEnclosingClass().declaration);
+      rti.registerRtiDependency(type.element, contextClass);
     }
   }
 
@@ -1553,7 +1569,7 @@
 
   /// Called when resolving the `Symbol` constructor.
   void registerSymbolConstructor(TreeElements elements) {
-    // Make sure that collection_dev.Symbol.validated is registered.
+    // Make sure that _internals.Symbol.validated is registered.
     assert(compiler.symbolValidatedConstructor != null);
     enqueueInResolution(compiler.symbolValidatedConstructor, elements);
   }
@@ -1670,15 +1686,6 @@
       return registerNameOf(element);
     }
 
-    if (element is ClosureClassElement) {
-      // TODO(ahe): Try to fix the enclosing element of ClosureClassElement
-      // instead.
-      ClosureClassElement closureClass = element;
-      if (isNeededForReflection(closureClass.methodElement)) {
-        return registerNameOf(element);
-      }
-    }
-
     // TODO(kasperl): Consider caching this information. It is consulted
     // multiple times because of the way we deal with the enclosing element.
     return false;
@@ -1855,6 +1862,8 @@
 
   void visitInterceptor(InterceptorConstant constant) => copy(constant);
 
+  void visitDummyReceiver(DummyReceiverConstant constant) => copy(constant);
+
   void visitList(ListConstant constant) {
     copy(constant.entries);
     copy(constant);
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index c6ee2e5..c436744 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -144,6 +144,10 @@
   jsAst.Expression visitInterceptor(InterceptorConstant constant) {
     return emitCanonicalVersion(constant);
   }
+
+  jsAst.Expression visitDummyReceiver(DummyReceiverConstant constant) {
+    return new jsAst.LiteralNumber('0');
+  }
 }
 
 /**
@@ -313,6 +317,10 @@
         'prototype');
   }
 
+  jsAst.Expression visitDummyReceiver(DummyReceiverConstant constant) {
+    return _reference(constant);
+  }
+
   jsAst.Expression visitConstructed(ConstructedConstant constant) {
     Element element = constant.type.element;
     if (element.isForeign(compiler)
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 9b18a37..484fa22 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -1181,6 +1181,10 @@
     addRoot(constant.dispatchedType.element.name);
     add('methods');
   }
+
+  visitDummyReceiver(DummyReceiverConstant constant) {
+    add('dummy_receiver');
+  }
 }
 
 /**
@@ -1258,6 +1262,11 @@
     return _hashString(5, typeName);
   }
 
+  visitDummyReceiver(DummyReceiverConstant constant) {
+    compiler.internalError(
+        'DummyReceiverConstant should never be named and never be subconstant');
+  }
+
   int _hashString(int hash, String s) {
     int length = s.length;
     hash = _combine(hash, length);
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 175c932..b178723 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -457,7 +457,9 @@
       return false;
     }
 
-    if (backend.classesMixedIntoNativeClasses.contains(element)) return true;
+    if (backend.classesMixedIntoInterceptedClasses.contains(element)) {
+      return true;
+    }
 
     return subtypes[element] != null;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
index 9d9a89b..1d7c419 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
@@ -316,11 +316,11 @@
       statics.add(staticsBuilder.toObjectInitializer().properties.single);
     }
 
-    Map<String, ClassBuilder> classPropertyLists =
-        task.elementDecriptors.remove(classElement);
+    Map<OutputUnit, ClassBuilder> classPropertyLists =
+        task.elementDescriptors.remove(classElement);
     if (classPropertyLists != null) {
       for (ClassBuilder classProperties in classPropertyLists.values) {
-        // TODO(ahe): What about deferred?
+        // TODO(sigurdm): What about deferred?
         if (classProperties != null) {
           statics.addAll(classProperties.properties);
         }
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 835a673..93241b7 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
@@ -24,16 +24,15 @@
   final Namer namer;
   ConstantEmitter constantEmitter;
   NativeEmitter nativeEmitter;
-  CodeBuffer mainBuffer;
-  final CodeBuffer deferredLibrariesBuffer = new CodeBuffer();
+  Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>();
   final CodeBuffer deferredConstants = new CodeBuffer();
   /** Shorter access to [isolatePropertiesName]. Both here in the code, as
       well as in the generated code. */
   String isolateProperties;
   String classesCollector;
   final Set<ClassElement> neededClasses = new Set<ClassElement>();
-  final List<ClassElement> regularClasses = <ClassElement>[];
-  final List<ClassElement> deferredClasses = <ClassElement>[];
+  final Map<OutputUnit, List<ClassElement>> outputClassLists =
+      new Map<OutputUnit, List<ClassElement>>();
   final List<ClassElement> nativeClasses = <ClassElement>[];
   final Map<String, String> mangledFieldNames = <String, String>{};
   final Map<String, String> mangledGlobalFieldNames = <String, String>{};
@@ -57,6 +56,11 @@
   String get n => compiler.enableMinification ? "" : "\n";
   String get N => compiler.enableMinification ? "\n" : ";\n";
 
+  CodeBuffer get mainBuffer {
+    return outputBuffers.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit,
+        () => new CodeBuffer());
+  }
+
   /**
    * List of expressions and statements that will be included in the
    * precompiled function.
@@ -80,20 +84,17 @@
    *
    * For supporting deferred loading we keep one list per output unit.
    *
-   * The String determines the outputUnit, either "main" or "deferred"
-   *
    * See [getElementDecriptor].
    */
   // TODO(ahe): Generate statics with their class, and store only libraries in
   // this map.
-  final Map<Element, Map<String, ClassBuilder>> elementDecriptors
-      = new Map<Element, Map<String, ClassBuilder>>();
+  final Map<Element, Map<OutputUnit, ClassBuilder>> elementDescriptors
+      = new Map<Element, Map<OutputUnit, ClassBuilder>>();
 
   final bool generateSourceMap;
 
   CodeEmitterTask(Compiler compiler, Namer namer, this.generateSourceMap)
-      : mainBuffer = new CodeBuffer(),
-        this.namer = namer,
+      : this.namer = namer,
         constantEmitter = new ConstantEmitter(compiler, namer),
         super(compiler) {
     nativeEmitter = new NativeEmitter(this);
@@ -803,6 +804,7 @@
     unneededClasses.add(backend.jsUInt32Class);
     unneededClasses.add(backend.jsUInt31Class);
     unneededClasses.add(backend.jsPositiveIntClass);
+    unneededClasses.add(compiler.dynamicClass);
 
     return (ClassElement cls) => !unneededClasses.contains(cls);
   }
@@ -891,15 +893,29 @@
     return null;
   }
 
-  void emitCompileTimeConstants(CodeBuffer eagerBuffer) {
+  void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) {
     ConstantHandler handler = compiler.constantHandler;
     List<Constant> constants = handler.getConstantsForEmission(
         compareConstants);
+    Set<Constant> outputUnitConstants = null;
+    // TODO(sigurdm): We shouldn't run through all constants for every
+    // outputUnit.
     for (Constant constant in constants) {
       if (isConstantInlinedOrAlreadyEmitted(constant)) continue;
+      OutputUnit constantUnit =
+          compiler.deferredLoadTask.outputUnitForConstant(constant);
+      if (constantUnit != outputUnit && constantUnit != null) continue;
+      if (outputUnit != compiler.deferredLoadTask.mainOutputUnit
+          && constantUnit == null) {
+        // The back-end introduces some constants, like "InterceptorConstant" or
+        // some list constants. They are emitted in the main output-unit, and
+        // ignored otherwise.
+        // TODO(sigurdm): We should track those constants.
+        continue;
+      }
+
       String name = namer.constantName(constant);
-      if (constant.isList()) emitMakeConstantListIfNotEmitted(eagerBuffer);
-      CodeBuffer buffer = bufferForConstant(constant, eagerBuffer);
+      if (constant.isList()) emitMakeConstantListIfNotEmitted(buffer);
       jsAst.Expression init = js(
           '${namer.globalObjectForConstant(constant)}.$name = #',
           constantInitializerExpression(constant));
@@ -909,8 +925,9 @@
   }
 
   bool isConstantInlinedOrAlreadyEmitted(Constant constant) {
-    if (constant.isFunction()) return true;   // Already emitted.
-    if (constant.isPrimitive()) return true;  // Inlined.
+    if (constant.isFunction()) return true;       // Already emitted.
+    if (constant.isPrimitive()) return true;      // Inlined.
+    if (constant.isDummyReceiver()) return true;  // Inlined.
     // The name is null when the constant is already a JS constant.
     // TODO(floitsch): every constant should be registered, so that we can
     // share the ones that take up too much space (like some strings).
@@ -1093,18 +1110,23 @@
 
     for (ClassElement element in sortedClasses) {
       if (typeTestEmitter.rtiNeededClasses.contains(element)) {
-        regularClasses.add(element);
+        // TODO(sigurdm): We might be able to defer some of these.
+        outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit,
+            () => new List<ClassElement>()).add(element);
       } else if (Elements.isNativeOrExtendsNative(element)) {
         // For now, native classes and related classes cannot be deferred.
         nativeClasses.add(element);
         if (!element.isNative()) {
-          assert(invariant(element, !isDeferred(element)));
-          regularClasses.add(element);
+          assert(invariant(element,
+                           !compiler.deferredLoadTask.isDeferred(element)));
+          outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit,
+              () => new List<ClassElement>()).add(element);
         }
-      } else if (isDeferred(element)) {
-        deferredClasses.add(element);
       } else {
-        regularClasses.add(element);
+        outputClassLists.putIfAbsent(
+            compiler.deferredLoadTask.outputUnitForElement(element),
+            () => new List<ClassElement>())
+            .add(element);
       }
     }
   }
@@ -1162,24 +1184,23 @@
       uri = relativize(
           compiler.sourceMapUri, library.canonicalUri, false);
     }
-    Map<String, ClassBuilder> descriptors =
-        elementDecriptors[library];
+    Map<OutputUnit, ClassBuilder> descriptors =
+        elementDescriptors[library];
 
-    Map<String, CodeBuffer> outputBuffers =
-      {"main": mainBuffer,
-       "deferred": deferredLibrariesBuffer};
-
-    for (String outputUnit in outputBuffers.keys) {
+    for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
       ClassBuilder descriptor =
           descriptors.putIfAbsent(outputUnit, ()
               => new ClassBuilder());
       if (descriptor.properties.isEmpty) continue;
-      bool isDeferred = outputUnit != "main";
+      bool isDeferred =
+          outputUnit != compiler.deferredLoadTask.mainOutputUnit;
       jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library);
 
       jsAst.ObjectInitializer initializers =
           descriptor.toObjectInitializer();
-      int sizeBefore = outputBuffers[outputUnit].length;
+      CodeBuffer outputBuffer =
+          outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer());
+      int sizeBefore = outputBuffer.length;
       outputBuffers[outputUnit]
           ..write('["${library.getLibraryName()}",$_')
           ..write('"${uri}",$_')
@@ -1191,7 +1212,7 @@
           ..write(jsAst.prettyPrint(initializers, compiler))
           ..write(library == compiler.mainApp ? ',${n}1' : "")
           ..write('],$n');
-      int sizeAfter = outputBuffers[outputUnit].length;
+      int sizeAfter = outputBuffer.length;
       compiler.dumpInfoTask.codeSizeCounter
           .countCode(library, sizeAfter - sizeBefore);
     }
@@ -1208,7 +1229,7 @@
       mainBuffer.add(buildGeneratedBy());
       addComment(HOOKS_API_USAGE, mainBuffer);
 
-      if (!areAnyElementsDeferred) {
+      if (!compiler.deferredLoadTask.splitProgram) {
         mainBuffer.add('(function(${namer.currentIsolate})$_{$n');
       }
 
@@ -1235,10 +1256,10 @@
 
       emitStaticFunctions();
 
-      if (!regularClasses.isEmpty ||
-          !deferredClasses.isEmpty ||
-          !nativeClasses.isEmpty ||
-          !compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty) {
+      // Only output the classesCollector if we actually have any classes.
+      if (!(nativeClasses.isEmpty &&
+            compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
+          outputClassLists.values.every((classList) => classList.isEmpty))) {
         // Shorten the code by using "$$" as temporary.
         classesCollector = r"$$";
         mainBuffer.add('var $classesCollector$_=$_{}$N$n');
@@ -1260,8 +1281,8 @@
       // emitted until we have emitted all other classes (native or not).
 
       // Might create methodClosures.
-      if (!regularClasses.isEmpty) {
-        for (ClassElement element in regularClasses) {
+      for (List<ClassElement> outputClassList in outputClassLists.values) {
+        for (ClassElement element in outputClassList) {
           generateClass(element, getElementDecriptor(element));
         }
       }
@@ -1269,24 +1290,20 @@
       nativeEmitter.finishGenerateNativeClasses();
       nativeEmitter.assembleCode(nativeBuffer);
 
-      if (!deferredClasses.isEmpty) {
-        for (ClassElement element in deferredClasses) {
-          generateClass(element, getElementDecriptor(element));
-        }
-      }
 
       // After this assignment we will produce invalid JavaScript code if we use
       // the classesCollector variable.
       classesCollector = 'classesCollector should not be used from now on';
 
-      if (!elementDecriptors.isEmpty) {
+      // TODO(sigurdm): Need to check this for each outputUnit.
+      if (!elementDescriptors.isEmpty) {
         var oldClassesCollector = classesCollector;
         classesCollector = r"$$";
         if (compiler.enableMinification) {
           mainBuffer.write(';');
         }
 
-        for (Element element in elementDecriptors.keys) {
+        for (Element element in elementDescriptors.keys) {
           // TODO(ahe): Should iterate over all libraries.  Otherwise, we will
           // not see libraries that only have fields.
           if (element.isLibrary()) {
@@ -1294,7 +1311,8 @@
             ClassBuilder builder = new ClassBuilder();
             if (classEmitter.emitFields(
                     library, builder, null, emitStatics: true)) {
-              getElementDescriptorForOutputUnit(library, "main")
+              OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit;
+              getElementDescriptorForOutputUnit(library, mainUnit)
                   .properties.addAll(builder.toObjectInitializer().properties);
             }
           }
@@ -1338,11 +1356,11 @@
             ..write('([$n');
 
         List<Element> sortedElements =
-            Elements.sortedByPosition(elementDecriptors.keys);
+            Elements.sortedByPosition(elementDescriptors.keys);
 
         Iterable<Element> pendingStatics = sortedElements.where((element) {
             return !element.isLibrary() &&
-                elementDecriptors[element].values.any((descriptor) =>
+                elementDescriptors[element].values.any((descriptor) =>
                     descriptor != null);
         });
 
@@ -1353,7 +1371,7 @@
         for (LibraryElement library in sortedElements.where((element) =>
             element.isLibrary())) {
           writeLibraryDescriptors(library);
-          elementDecriptors[library] = const {};
+          elementDescriptors[library] = const {};
         }
         if (!pendingStatics.isEmpty) {
           compiler.internalError('Pending statics (see above).');
@@ -1371,7 +1389,24 @@
       // which may need getInterceptor (and one-shot interceptor) methods, so
       // we have to make sure that [emitGetInterceptorMethods] and
       // [emitOneShotInterceptors] have been called.
-      emitCompileTimeConstants(mainBuffer);
+      emitCompileTimeConstants(
+          mainBuffer, compiler.deferredLoadTask.mainOutputUnit);
+
+      // We write a javascript mapping from DeferredLibrary elements
+      // (really their String argument) to the js hunk to load.
+      // TODO(sigurdm): Create a syntax tree for this.
+      // TODO(sigurdm): Also find out where to place it.
+      mainBuffer.write("\$.libraries_to_load = {");
+      for (String constant in compiler.deferredLoadTask.hunksToLoad.keys) {
+        // TODO(sigurdm): Escape these strings.
+        mainBuffer.write('"$constant":[');
+        for (OutputUnit outputUnit in
+            compiler.deferredLoadTask.hunksToLoad[constant]) {
+          mainBuffer.write('"${outputUnit.name}.js", ');
+        }
+        mainBuffer.write("],\n");
+      }
+      mainBuffer.write("}$N");
       // Static field initializations require the classes and compile-time
       // constants to be set up.
       emitStaticNonFinalFieldInitializations(mainBuffer);
@@ -1443,7 +1478,7 @@
       jsAst.FunctionDeclaration precompiledFunctionAst =
           buildPrecompiledFunction();
       emitInitFunction(mainBuffer);
-      if (!areAnyElementsDeferred) {
+      if (!compiler.deferredLoadTask.splitProgram) {
         mainBuffer.add('})()\n');
       } else {
         mainBuffer.add('\n');
@@ -1467,10 +1502,10 @@
   }
 
   ClassBuilder getElementDescriptorForOutputUnit(Element element,
-      String outputUnit) {
-    Map<String, ClassBuilder> descriptors =
-        elementDecriptors.putIfAbsent(
-            element, () => new Map<String, ClassBuilder>());
+                                                 OutputUnit outputUnit) {
+    Map<OutputUnit, ClassBuilder> descriptors =
+        elementDescriptors.putIfAbsent(
+            element, () => new Map<OutputUnit, ClassBuilder>());
     return descriptors.putIfAbsent(outputUnit,
         () => new ClassBuilder());
   }
@@ -1491,42 +1526,20 @@
     if (owner == null) {
       compiler.internalErrorOnElement(element, 'Owner is null');
     }
-    String outputUnit = isDeferred(element) ? "deferred" : "main";
-    return getElementDescriptorForOutputUnit(owner, outputUnit);
+    return getElementDescriptorForOutputUnit(owner,
+        compiler.deferredLoadTask.outputUnitForElement(element));
   }
 
-  /**
-   * Returns the appropriate buffer for [constant].  If [constant] is
-   * itself an instance of a deferred type (or built from constants
-   * that are instances of deferred types) attempting to use
-   * [constant] before the deferred type has been loaded will not
-   * work, and [constant] itself must be deferred.
-   */
-  CodeBuffer bufferForConstant(Constant constant, CodeBuffer eagerBuffer) {
-    var queue = new Queue()..add(constant);
-    while (!queue.isEmpty) {
-      constant = queue.removeFirst();
-      if (isDeferred(constant.computeType(compiler).element)) {
-        return deferredConstants;
-      }
-      queue.addAll(constant.getDependencies());
-    }
-    return eagerBuffer;
-  }
-
-
-
   void emitDeferredCode() {
-    if (deferredLibrariesBuffer.isEmpty && deferredConstants.isEmpty) return;
+    for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
+      if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
+      CodeBuffer outputBuffer = outputBuffers.putIfAbsent(outputUnit,
+          () => new CodeBuffer());
 
-    var oldClassesCollector = classesCollector;
-    classesCollector = r"$$";
+      var oldClassesCollector = classesCollector;
+      classesCollector = r"$$";
 
-    // It does not make sense to defer constants if there are no
-    // deferred elements.
-    assert(!deferredLibrariesBuffer.isEmpty);
-
-    var buffer = new CodeBuffer()
+      var buffer = new CodeBuffer()
         ..write(buildGeneratedBy())
         ..write('var old${namer.currentIsolate}$_='
                 '$_${namer.currentIsolate}$N'
@@ -1540,31 +1553,30 @@
                 '$classesCollector$_=$_{};$n')
         ..write(getReflectionDataParser(classesCollector, backend))
         ..write('([$n')
-        ..addBuffer(deferredLibrariesBuffer)
+        ..addBuffer(outputBuffer)
         ..write('])$N');
 
-    if (!deferredClasses.isEmpty) {
+      if (outputClassLists.containsKey(outputUnit)) {
+        buffer.write(
+            '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
+            '$_$isolatePropertiesName)$N');
+      }
+
       buffer.write(
-          '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
-          '$_$isolatePropertiesName)$N');
+          // Reset the classesCollector ($$).
+          '$classesCollector$_=${_}null$N$n'
+          '${namer.currentIsolate}$_=${_}old${namer.currentIsolate}$N');
+
+      classesCollector = oldClassesCollector;
+
+      emitCompileTimeConstants(buffer, outputUnit);
+
+      String code = buffer.getText();
+      compiler.outputProvider(outputUnit.name, 'js')
+        ..add(code)
+        ..close();
+      outputSourceMap(compiler.assembledCode, outputUnit.name);
     }
-
-    buffer.write(
-        // Reset the classesCollector ($$).
-        '$classesCollector$_=${_}null$N$n'
-        '${namer.currentIsolate}$_=${_}old${namer.currentIsolate}$N');
-
-    classesCollector = oldClassesCollector;
-
-    if (!deferredConstants.isEmpty) {
-      buffer.addBuffer(deferredConstants);
-    }
-
-    String code = buffer.getText();
-    compiler.outputProvider('part', 'js')
-      ..add(code)
-      ..close();
-    outputSourceMap(compiler.assembledCode, 'part');
   }
 
   String buildGeneratedBy() {
@@ -1592,14 +1604,6 @@
         ..close();
   }
 
-  bool isDeferred(Element element) {
-    return compiler.deferredLoadTask.isDeferred(element);
-  }
-
-  bool get areAnyElementsDeferred {
-    return compiler.deferredLoadTask.areAnyElementsDeferred;
-  }
-
   void registerReadTypeVariable(TypeVariableElement element) {
     readTypeVariables.add(element);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
index 688a7eb..6e90176 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -413,7 +413,7 @@
 
     expressions.add(code);
 
-    List tearOffInfo = [new jsAst.LiteralString('$callSelectorString')];
+    List tearOffInfo = [new jsAst.LiteralString(callSelectorString)];
 
     if (needsStubs || canTearOff) {
       addParameterStubs(member, (Selector selector, jsAst.Fun function) {
@@ -445,7 +445,7 @@
             callSelectors.contains(callSelector)) {
           callSelectorString = '"${namer.invocationName(callSelector)}"';
         }
-        tearOffInfo.add(new jsAst.LiteralString('$callSelectorString'));
+        tearOffInfo.add(new jsAst.LiteralString(callSelectorString));
       }, canTearOff);
     }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
index 71fcaee..9070243 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
@@ -61,6 +61,9 @@
 
 import '../dump_info.dart' as dumpInfo;
 
+import '../deferred_load.dart' show
+    OutputUnit;
+
 part 'class_builder.dart';
 part 'class_emitter.dart';
 part 'code_emitter_helper.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart
index 09e7eb2..8733590 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart
@@ -123,7 +123,7 @@
 
     bool haveSameTypeVariables(ClassElement a, ClassElement b) {
       if (a.isClosure()) return true;
-      return a.typeVariables == b.typeVariables;
+      return backend.rti.isTrivialSubstitution(a, b);
     }
 
     if (superclass != null && superclass != compiler.objectClass &&
@@ -135,9 +135,12 @@
       Set<ClassElement> emitted = new Set<ClassElement>();
       // TODO(karlklose): move the computation of these checks to
       // RuntimeTypeInformation.
-      if (backend.classNeedsRti(cls)) {
-        emitSubstitution(superclass, emitNull: true);
-        emitted.add(superclass);
+      while (superclass != null) {
+        if (backend.classNeedsRti(superclass)) {
+          emitSubstitution(superclass, emitNull: true);
+          emitted.add(superclass);
+        }
+        superclass = superclass.superclass;
       }
       for (DartType supertype in cls.allSupertypes) {
         ClassElement superclass = supertype.element;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
index fad167e..d9e860d 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
@@ -147,8 +147,7 @@
 
       if (named.name.source == 'symbols') {
         analyzer.cachedStrings[value] =
-            builder.convertToListOfStrings(
-                builder.convertConstantToUsageList(value, onlyStrings: true));
+            builder.convertConstantToUsageList(value, onlyStrings: true);
       } else if (named.name.source == 'targets') {
         analyzer.cachedElements[value] =
             builder.resolveUsageList(builder.convertConstantToUsageList(value));
@@ -390,14 +389,17 @@
   /// constant is a single [String], it is assumed to be a comma-separated list
   /// of qualified names. If the constant is a [Type] t, the result is [:[t]:].
   /// Otherwise, the constant is assumed to represent a list of strings (each a
-  /// qualified name) and types, and such a list is constructed.
+  /// qualified name) and types, and such a list is constructed.  If
+  /// [onlyStrings] is true, the returned list is a [:List<String>:] and any
+  /// [Type] values are treated as an error (meaning that the value is ignored
+  /// and a hint is emitted).
   List convertConstantToUsageList(
       Constant constant, { bool onlyStrings: false }) {
     if (constant.isNull()) {
       return null;
     } else if (constant.isList()) {
       ListConstant list = constant;
-      List result = [];
+      List result = onlyStrings ? <String> [] : [];
       for (Constant entry in list.entries) {
         if (entry.isString()) {
           StringConstant string = entry;
@@ -421,8 +423,9 @@
       return [type.representedType];
     } else if (constant.isString()) {
       StringConstant string = constant;
-      return
-          string.value.slowToString().split(',').map((e) => e.trim()).toList();
+      var iterable =
+          string.value.slowToString().split(',').map((e) => e.trim());
+      return onlyStrings ? new List<String>.from(iterable) : iterable.toList();
     } else {
       Spannable node = positionOf(constant);
       MessageKind kind = onlyStrings
@@ -452,18 +455,6 @@
     return type;
   }
 
-  /// Ensure a list contains only strings.
-  List<String> convertToListOfStrings(List list) {
-    if (list == null) return null;
-    List<String> result = new List<String>(list.length);
-    int count = 0;
-    for (var entry in list) {
-      assert(invariant(spannable, entry is String));
-      result[count++] = entry;
-    }
-    return result;
-  }
-
   /// Convert a list of strings and types to a list of elements. Types are
   /// converted to their corresponding element, and strings are resolved as
   /// follows:
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 455a091..152863d 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -8,6 +8,11 @@
   Element get currentElement;
   Setlet<Node> get superUses;
 
+  /// Iterables of the dependencies that this [TreeElement] records of
+  /// [currentElement].
+  Iterable<Element> get allElements;
+  Iterable<Constant> get allConstants;
+
   /// A set of additional dependencies.  See [registerDependency] below.
   Setlet<Element> get otherDependencies;
 
@@ -69,6 +74,7 @@
       new Map<VariableElement, List<Node>>();
   final Map<Node, Map<VariableElement, List<Node>>> accessedByClosureIn =
       new Map<Node, Map<VariableElement, List<Node>>>();
+  final Setlet<Element> elements = new Setlet<Element>();
 
   final int hashCode = ++hashCodeCounter;
   static int hashCodeCounter = 0;
@@ -97,6 +103,7 @@
     //                  getTreeElement(node) == null,
     //                  message: '${getTreeElement(node)}; $element'));
 
+    elements.add(element);
     setTreeElement(node, element);
   }
 
@@ -235,6 +242,10 @@
   }
 
   String toString() => 'TreeElementMapping($currentElement)';
+
+  Iterable<Element> get allElements => elements;
+
+  Iterable<Constant> get allConstants => constants.values;
 }
 
 class ResolverTask extends CompilerTask {
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 4640ff5..ab11a77 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -42,7 +42,7 @@
     }
     List<int> source;
     try {
-      source = readAll(uriPathToNative(resourceUri.path));
+      source = readAll(resourceUri.toFilePath());
     } on FileSystemException catch (ex) {
       return new Future.error(
           "Error reading '${relativize(cwd, resourceUri, isWindows)}' "
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 6d233b5..8cc7017 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1204,11 +1204,13 @@
     if (cachedCanBeInlined == false) return false;
 
     bool meetsHardConstraints() {
-      // We cannot inline a method from a deferred library into a method
-      // which isn't deferred.
-      // TODO(ahe): But we should still inline into the same
-      // connected-component of the deferred library.
-      if (compiler.deferredLoadTask.isDeferred(element)) return false;
+      // Don't inline from one output unit to another. If something is deferred
+      // it is to save space in the loading code.
+      var getOutputUnit = compiler.deferredLoadTask.outputUnitForElement;
+      if (getOutputUnit(element) !=
+          getOutputUnit(compiler.currentElement)) {
+        return false;
+      }
       if (compiler.disableInlining) return false;
 
       assert(selector != null
@@ -1511,7 +1513,6 @@
   bool inTryStatement = false;
 
   Constant getConstantForNode(Node node) {
-    ConstantHandler handler = compiler.constantHandler;
     Constant constant = elements.getConstant(node);
     assert(invariant(node, constant != null,
         message: 'No constant computed for $node'));
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index e4a4ad8..441d653 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -83,7 +83,7 @@
     TypeMask receiverType = instruction.instructionType;
     return interceptedClasses
         .where((cls) => cls != compiler.objectClass)
-        .map((cls) => backend.classesMixedIntoNativeClasses.contains(cls)
+        .map((cls) => backend.classesMixedIntoInterceptedClasses.contains(cls)
             ? new TypeMask.subtype(cls)
             : new TypeMask.subclass(cls))
         .every((mask) => receiverType.intersection(mask, compiler).isEmpty);
@@ -186,7 +186,7 @@
       if (interceptedClasses.contains(backend.jsNumberClass)
           && !(interceptedClasses.contains(backend.jsDoubleClass)
                || interceptedClasses.contains(backend.jsIntClass))) {
-        for (var user in node.usedBy) {
+        for (HInstruction user in node.usedBy) {
           if (user is! HInvoke) continue;
           Set<ClassElement> intercepted =
               backend.getInterceptedClassesOn(user.selector.name);
@@ -200,7 +200,7 @@
       }
     } else {
       interceptedClasses = new Set<ClassElement>();
-      for (var user in node.usedBy) {
+      for (HInstruction user in node.usedBy) {
         if (user is HIs) {
           // Is-checks can be performed on any intercepted class.
           interceptedClasses.addAll(backend.interceptedClasses);
@@ -215,8 +215,7 @@
 
     HInstruction receiver = node.receiver;
     if (canUseSelfForInterceptor(receiver, interceptedClasses)) {
-      node.block.rewrite(node, receiver);
-      return false;
+      return rewriteToUseSelfAsInterceptor(node, receiver);
     }
 
     // Try computing a constant interceptor.
@@ -254,6 +253,55 @@
     return true;
   }
 
+  bool rewriteToUseSelfAsInterceptor(HInterceptor node, HInstruction receiver) {
+    // `rewrite` below clears `node.usedBy`.
+    List<HInstruction> originalUsers = node.usedBy.toList();
+
+    node.block.rewrite(node, receiver);
+
+    // We have just rewritten:
+    //
+    //     m = getInterceptor(a)
+    //     m.foo$1(a, x)
+    // -->
+    //     m = getInterceptor(a)
+    //     a.foo$1(a, x)
+    //
+    // For the rewritten calls, if the selector matches only methods that ignore
+    // the explicit receiver parameter, replace occurences of the receiver
+    // argument with a dummy receiver '0':
+    //
+    //     a.foo$1(a, x)   -->   a.foo$1(0, x)
+    //
+    JavaScriptBackend backend = compiler.backend;
+    for (HInstruction user in originalUsers) {
+      if (user is HInvokeDynamic) {
+        HInvokeDynamic invoke = user;
+        if (invoke.receiver == receiver &&
+            !backend.isInterceptedMixinSelector(invoke.selector)) {
+          HInstruction receiverArgument = invoke.inputs[1];
+          // TODO(15720): The test here should be
+          //
+          //     invoke.receiver.nonCheck() == receiverArgument.nonCheck()
+          //
+          if (invoke.receiver == receiverArgument) {  // recognize a.foo(a,...)
+            // TODO(15933): Make automatically generated property extraction
+            // closures work with the dummy receiver optimization.
+            if (!invoke.selector.isGetter()) {
+              Constant constant = new DummyReceiverConstant(
+                  receiverArgument.instructionType);
+              HConstant dummy = graph.addConstant(constant, compiler);
+              receiverArgument.usedBy.remove(invoke);
+              invoke.inputs[1] = dummy;
+              dummy.usedBy.add(invoke);
+            }
+          }
+        }
+      }
+    }
+    return false;
+  }
+
   bool visitOneShotInterceptor(HOneShotInterceptor node) {
     HInstruction constant = tryComputeConstantInterceptor(
         node.inputs[1], node.interceptedClasses);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 115ff92..ea74d96 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1424,7 +1424,7 @@
                 {this.targetCanThrow: true})
     : super(inputs, type);
 
-  toString() => 'invoke static: ${element.name}';
+  toString() => 'invoke static: $element';
   accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
   int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index 114d3bf..44b7f29 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -104,6 +104,16 @@
     if (isEmpty) throw new StateError('No elements');
     return head;
   }
+
+  /// Returns true if f returns true for all elements of this list.
+  ///
+  /// Returns true for the empty list.
+  bool every(bool f(T)) {
+    for (Link<T> link = this; !link.isEmpty; link = link.tail){
+      if (!f(link.head)) return false;
+    }
+    return true;
+  }
 }
 
 abstract class LinkBuilder<T> {
diff --git a/sdk/lib/_internal/compiler/implementation/util/setlet.dart b/sdk/lib/_internal/compiler/implementation/util/setlet.dart
index abece72..7b9d0bc 100644
--- a/sdk/lib/_internal/compiler/implementation/util/setlet.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/setlet.dart
@@ -176,6 +176,18 @@
       }
     }
   }
+
+  bool containsAll(Iterable<E> other) {
+    for (E e in other) {
+      if (!this.contains(e)) return false;
+    };
+    return true;
+  }
+
+  clear() {
+    _contents = _MARKER;
+    _extra = null;
+  }
 }
 
 class _SetletMarker {
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 5d5c72d..454b0d1 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -1079,9 +1079,13 @@
   static const MessageKind MISSING_FACTORY_KEYWORD = const MessageKind(
       "Hint: Did you forget a factory keyword here?");
 
-  static const MessageKind DEFERRED_LIBRARY_NAME_MISMATCH =
+  static const MessageKind DEFERRED_LIBRARY_NOT_FROM_MAIN =
       const MessageKind(
-          "Error: Library name mismatch '#{expectedName}' != '#{actualName}'.");
+          "Info: DeferredLibrary used as an annotation here, "
+          "but not used in the main library. Will not split the output.",
+          howToFix:
+            "Try adding a '@DeferredLibrary(...)' annotation in the main "
+            "library");
 
   static const MessageKind ILLEGAL_STATIC = const MessageKind(
       "Error: Modifier static is only allowed on functions declared in "
diff --git a/sdk/lib/_internal/compiler/samples/jsonify/jsonify.dart b/sdk/lib/_internal/compiler/samples/jsonify/jsonify.dart
index 36596aa..e639c4e 100644
--- a/sdk/lib/_internal/compiler/samples/jsonify/jsonify.dart
+++ b/sdk/lib/_internal/compiler/samples/jsonify/jsonify.dart
@@ -31,6 +31,8 @@
 RandomAccessFile output;
 Uri outputUri;
 Uri sdkRoot;
+const bool outputJson =
+    const bool.fromEnvironment('outputJson', defaultValue: false);
 
 main(List<String> arguments) {
   handler = new FormattingDiagnosticHandler()
@@ -77,7 +79,10 @@
     }
   });
 
-  output.writeStringSync('''
+  if (outputJson) {
+    output.writeStringSync(JSON.encode(map));
+  } else {
+    output.writeStringSync('''
 // 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.
@@ -88,7 +93,8 @@
 library dart.sdk_sources;
 
 const Map<String, String> SDK_SOURCES = const <String, String>''');
-  output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
-  output.writeStringSync(';\n');
+    output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
+    output.writeStringSync(';\n');
+  }
   output.closeSync();
 }
diff --git a/sdk/lib/_internal/lib/async_patch.dart b/sdk/lib/_internal/lib/async_patch.dart
index 8d6bb26..053e856 100644
--- a/sdk/lib/_internal/lib/async_patch.dart
+++ b/sdk/lib/_internal/lib/async_patch.dart
@@ -30,18 +30,32 @@
 
 patch class DeferredLibrary {
   patch Future<bool> load() {
-    return _load(libraryName, uri);
+    List hunkNames = new List();
+    if (JS('bool', '\$.libraries_to_load[#] === undefined', libraryName)) {
+      return new Future(() => false);
+    }
+    for (int index = 0;
+         index < JS('int', '\$.libraries_to_load[#].length', libraryName);
+         ++index) {
+      hunkNames.add(JS('String', '\$.libraries_to_load[#][#]',
+                       libraryName, index));
+    }
+    Iterable<Future<bool>> allLoads =
+        hunkNames.map((libraryName) => _load(libraryName, uri));
+    return Future.wait(allLoads).then((results) {
+      return results.any((x) => x);
+    });
   }
 }
 
 // TODO(ahe): This should not only apply to this isolate.
 final Map<String, Future<bool>> _loadedLibraries = <String, Future<bool>>{};
 
-Future<bool> _load(String libraryName, String uri) {
+Future<bool> _load(String hunkName, String uri) {
   // TODO(ahe): Validate libraryName.  Kasper points out that you want
   // to be able to experiment with the effect of toggling @DeferLoad,
   // so perhaps we should silently ignore "bad" library names.
-  Future<bool> future = _loadedLibraries[libraryName];
+  Future<bool> future = _loadedLibraries[hunkName];
   if (future != null) {
     return future.then((_) => false);
   }
@@ -49,8 +63,8 @@
   if (Primitives.isJsshell) {
     // TODO(ahe): Move this code to a JavaScript command helper script that is
     // not included in generated output.
-    return _loadedLibraries[libraryName] = new Future<bool>(() {
-      if (uri == null) uri = 'part.js';
+    return _loadedLibraries[hunkName] = new Future<bool>(() {
+      if (uri == null) uri = '$hunkName';
       // Create a new function to avoid getting access to current function
       // context.
       JS('void', '(new Function(#))()', 'loadRelativeToScript("$uri")');
@@ -59,11 +73,11 @@
   } else if (Primitives.isD8) {
     // TODO(ahe): Move this code to a JavaScript command helper script that is
     // not included in generated output.
-    return _loadedLibraries[libraryName] = new Future<bool>(() {
+    return _loadedLibraries[hunkName] = new Future<bool>(() {
       if (uri == null) {
         uri = IsolateNatives.computeThisScriptD8();
         int index = uri.lastIndexOf('/');
-        uri = '${uri.substring(0, index + 1)}part.js';
+        uri = '${uri.substring(0, index + 1)}$hunkName';
       }
       // Create a new function to avoid getting access to current function
       // context.
@@ -72,12 +86,12 @@
     });
   }
 
-  return _loadedLibraries[libraryName] = new Future<bool>(() {
+  return _loadedLibraries[hunkName] = new Future<bool>(() {
     Completer completer = new Completer<bool>();
     if (uri == null) {
       uri = IsolateNatives.thisScript;
       int index = uri.lastIndexOf('/');
-      uri = '${uri.substring(0, index + 1)}part.js';
+      uri = '${uri.substring(0, index + 1)}$hunkName';
     }
 
     // Inject a script tag.
diff --git a/sdk/lib/_internal/lib/core_patch.dart b/sdk/lib/_internal/lib/core_patch.dart
index b4a7bd2..30aa9264 100644
--- a/sdk/lib/_internal/lib/core_patch.dart
+++ b/sdk/lib/_internal/lib/core_patch.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // Patch file for dart:core classes.
-import "dart:_collection-dev" as _symbol_dev;
+import "dart:_internal" as _symbol_dev;
 import 'dart:_interceptors';
 import 'dart:_js_helper' show checkNull,
                               getRuntimeType,
diff --git a/sdk/lib/_internal/lib/interceptors.dart b/sdk/lib/_internal/lib/interceptors.dart
index 1562b57..6b25628 100644
--- a/sdk/lib/_internal/lib/interceptors.dart
+++ b/sdk/lib/_internal/lib/interceptors.dart
@@ -5,8 +5,8 @@
 library _interceptors;
 
 import 'dart:collection';
-import 'dart:_collection-dev' hide Symbol;
-import "dart:_collection-dev" as _symbol_dev show Symbol;
+import 'dart:_internal' hide Symbol;
+import "dart:_internal" as _symbol_dev show Symbol;
 import 'dart:_js_helper' show allMatchesInStringUnchecked,
                               Null,
                               JSSyntaxRegExp,
diff --git a/sdk/lib/_internal/lib/collection_dev_patch.dart b/sdk/lib/_internal/lib/internal_patch.dart
similarity index 99%
rename from sdk/lib/_internal/lib/collection_dev_patch.dart
rename to sdk/lib/_internal/lib/internal_patch.dart
index cd766c4..cccc6569 100644
--- a/sdk/lib/_internal/lib/collection_dev_patch.dart
+++ b/sdk/lib/_internal/lib/internal_patch.dart
@@ -11,4 +11,4 @@
 
 patch void printToConsole(String line) {
   printString('$line');
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index bc490dd..e7bde64 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -33,8 +33,8 @@
     RAW_DART_FUNCTION_REF;
 
 import 'dart:_interceptors';
-import 'dart:_collection-dev' as _symbol_dev;
-import 'dart:_collection-dev' show MappedIterable;
+import 'dart:_internal' as _symbol_dev;
+import 'dart:_internal' show MappedIterable;
 
 import 'dart:_js_names' show
     extractKeys,
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 18829bf..c55da2a 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -17,7 +17,7 @@
     JS_CURRENT_ISOLATE_CONTEXT,
     JS_GET_NAME;
 
-import 'dart:_collection-dev' as _symbol_dev;
+import 'dart:_internal' as _symbol_dev;
 
 import 'dart:_js_helper' show
     BoundClosure,
@@ -687,6 +687,7 @@
   final ClassMirror superclass;
   final ClassMirror mixin;
   Symbol _cachedSimpleName;
+  Map<Symbol, MethodMirror> _cachedInstanceMembers;
 
   JsMixinApplication(ClassMirror superclass, ClassMirror mixin,
                      String mangledName)
@@ -721,6 +722,20 @@
 
   Map<Symbol, DeclarationMirror> get declarations => mixin.declarations;
 
+  Map<Symbol, MethodMirror> get instanceMembers {
+    if (_cachedInstanceMembers == null) {
+      var result = new Map<Symbol, MethodMirror>();
+      if (superclass != null) {
+        result.addAll(superclass.instanceMembers);
+      }
+      result.addAll(mixin.instanceMembers);
+      _cachedInstanceMembers = result;
+    }
+    return _cachedInstanceMembers;
+  }
+
+  Map<Symbol, MethodMirror> get staticMembers => mixin.staticMembers;
+
   _asRuntimeType() => null;
 
   InstanceMirror invoke(
@@ -766,14 +781,9 @@
   List<TypeMirror> get typeArguments => const <TypeMirror>[];
 
   // TODO(ahe): Implement this.
-  Map<Symbol, MethodMirror> get instanceMembers
-      => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this.
-  Map<Symbol, MethodMirror> get staticMembers => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this.
   Function operator [](Symbol name) => throw new UnimplementedError();
+
+  bool get isAbstract => throw new UnimplementedError();
 }
 
 abstract class JsObjectMirror implements ObjectMirror {
@@ -967,6 +977,8 @@
   List<JsMethodMirror> _cachedMethods;
   ClassMirror _superclass;
   List<ClassMirror> _cachedSuperinterfaces;
+  Map<Symbol, MethodMirror> _cachedInstanceMembers;
+  Map<Symbol, MethodMirror> _cachedStaticMembers;
 
   JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
       : _class = originalDeclaration,
@@ -1092,6 +1104,56 @@
         new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
   }
 
+  Map<Symbol, MethodMirror> get staticMembers {
+    if (_cachedStaticMembers == null) {
+      var result = new Map<Symbol, MethodMirror>();
+      declarations.values.forEach((decl) {
+        if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
+          result[decl.simpleName] = decl;
+        }
+        if (decl is VariableMirror && decl.isStatic) {
+          var getterName = decl.simpleName;
+          result[getterName] = new JsSyntheticAccessor(
+              this, getterName, true, true, false, decl);
+          if (!decl.isFinal) {
+            var setterName = setterSymbol(decl.simpleName);
+            result[setterName] = new JsSyntheticAccessor(
+                this, setterName, false, true, false, decl);
+          }
+        }
+      });
+      _cachedStaticMembers = result;
+    }
+    return _cachedStaticMembers;
+  }
+
+  Map<Symbol, MethodMirror> get instanceMembers {
+    if (_cachedInstanceMembers == null) {
+      var result = new Map<Symbol, MethodMirror>();
+      if (superclass != null) {
+        result.addAll(superclass.instanceMembers);
+      }
+      declarations.values.forEach((decl) {
+        if (decl is MethodMirror && !decl.isStatic &&
+            !decl.isConstructor && !decl.isAbstract) {
+          result[decl.simpleName] = decl;
+        }
+        if (decl is VariableMirror && !decl.isStatic) {
+          var getterName = decl.simpleName;
+          result[getterName] = new JsSyntheticAccessor(
+              this, getterName, true, false, false, decl);
+          if (!decl.isFinal) {
+            var setterName = setterSymbol(decl.simpleName);
+            result[setterName] = new JsSyntheticAccessor(
+                this, setterName, false, false, false, decl);
+          }
+        }
+      });
+      _cachedInstanceMembers = result;
+    }
+    return _cachedInstanceMembers;
+  }
+
   InstanceMirror setField(Symbol fieldName, Object arg) {
     return _class.setField(fieldName, arg);
   }
@@ -1146,6 +1208,8 @@
 
   bool get isTopLevel => _class.isTopLevel;
 
+  bool get isAbstract => _class.isAbstract;
+
   SourceLocation get location => _class.location;
 
   MirrorSystem get mirrors => _class.mirrors;
@@ -1159,19 +1223,78 @@
   Symbol get simpleName => _class.simpleName;
 
   // TODO(ahe): Implement this.
-  Map<Symbol, MethodMirror> get instanceMembers
-      => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this.
-  Map<Symbol, MethodMirror> get staticMembers => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this.
   ClassMirror get mixin => throw new UnimplementedError();
 
   // TODO(ahe): Implement this.
   Function operator [](Symbol name) => throw new UnimplementedError();
 }
 
+class JsSyntheticAccessor implements MethodMirror {
+  final DeclarationMirror owner;
+  final Symbol simpleName;
+  final bool isGetter;
+  final bool isStatic;
+  final bool isTopLevel;
+  final _target;  /// The field or type that introduces the synthetic accessor.
+
+  JsSyntheticAccessor(this.owner,
+                      this.simpleName,
+                      this.isGetter,
+                      this.isStatic,
+                      this.isTopLevel,
+                      this._target);
+
+  bool get isSynthetic => true;
+  bool get isRegularMethod => false;
+  bool get isOperator => false;
+  bool get isConstructor => false;
+  bool get isConstConstructor => false;
+  bool get isGenerativeConstructor => false;
+  bool get isFactoryConstructor => false;
+  bool get isRedirectingConstructor => false;
+  bool get isAbstract => false;
+
+  bool get isSetter => !isGetter;
+  bool get isPrivate => n(simpleName).startsWith('_');
+
+  Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
+  Symbol get constructorName => const Symbol('');
+
+  TypeMirror get returnType => _target.type;
+  List<ParameterMirror> get parameters {
+    if (isGetter) return const [];
+    return new UnmodifiableListView(
+        [new JsSyntheticSetterParameter(this, this._target)]);
+  }
+
+  List<InstanceMirror> get metadata => const [];
+  String get source => null;
+  SourceLocation get location => throw new UnimplementedError();
+}
+
+class JsSyntheticSetterParameter implements ParameterMirror {
+  final DeclarationMirror owner;
+  final VariableMirror _target;
+
+  JsSyntheticSetterParameter(this.owner, this._target);
+
+  Symbol get simpleName => _target.simpleName;
+  Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
+  TypeMirror get type => _target.type;
+
+  bool get isOptional => false;
+  bool get isNamed => false;
+  bool get isStatic => false;
+  bool get isTopLevel => false;
+  bool get isConst => false;
+  bool get isFinal => true;
+  bool get isPrivate => false;
+  bool get hasDefaultValue => false;
+  InstanceMirror get defaultValue => null;
+  List<InstanceMirror> get metadata => const [];
+  SourceLocation get location => throw new UnimplementedError();
+}
+
 class JsClassMirror extends JsTypeMirror with JsObjectMirror
     implements ClassMirror {
   final String _mangledName;
@@ -1193,6 +1316,8 @@
   UnmodifiableListView<InstanceMirror> _cachedMetadata;
   UnmodifiableListView<ClassMirror> _cachedSuperinterfaces;
   UnmodifiableListView<TypeVariableMirror> _cachedTypeVariables;
+  Map<Symbol, MethodMirror> _cachedInstanceMembers;
+  Map<Symbol, MethodMirror> _cachedStaticMembers;
 
   // Set as side-effect of accessing JsLibraryMirror.classes.
   JsLibraryMirror _owner;
@@ -1356,6 +1481,56 @@
         new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
   }
 
+  Map<Symbol, MethodMirror> get staticMembers {
+    if (_cachedStaticMembers == null) {
+      var result = new Map<Symbol, MethodMirror>();
+      declarations.values.forEach((decl) {
+        if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
+          result[decl.simpleName] = decl;
+        }
+        if (decl is VariableMirror && decl.isStatic) {
+          var getterName = decl.simpleName;
+          result[getterName] = new JsSyntheticAccessor(
+              this, getterName, true, true, false, decl);
+          if (!decl.isFinal) {
+            var setterName = setterSymbol(decl.simpleName);
+            result[setterName] = new JsSyntheticAccessor(
+                this, setterName, false, true, false, decl);
+          }
+        }
+      });
+      _cachedStaticMembers = result;
+    }
+    return _cachedStaticMembers;
+  }
+
+  Map<Symbol, MethodMirror> get instanceMembers {
+    if (_cachedInstanceMembers == null) {
+      var result = new Map<Symbol, MethodMirror>();
+      if (superclass != null) {
+        result.addAll(superclass.instanceMembers);
+      }
+      declarations.values.forEach((decl) {
+        if (decl is MethodMirror && !decl.isStatic &&
+            !decl.isConstructor && !decl.isAbstract) {
+          result[decl.simpleName] = decl;
+        }
+        if (decl is VariableMirror && !decl.isStatic) {
+          var getterName = decl.simpleName;
+          result[getterName] = new JsSyntheticAccessor(
+              this, getterName, true, false, false, decl);
+          if (!decl.isFinal) {
+            var setterName = setterSymbol(decl.simpleName);
+            result[setterName] = new JsSyntheticAccessor(
+                this, setterName, false, false, false, decl);
+          }
+        }
+      });
+      _cachedInstanceMembers = result;
+    }
+    return _cachedInstanceMembers;
+  }
+
   InstanceMirror setField(Symbol fieldName, Object arg) {
     JsVariableMirror mirror = __variables[fieldName];
     if (mirror != null && mirror.isStatic && !mirror.isFinal) {
@@ -1552,17 +1727,12 @@
   }
 
   // TODO(ahe): Implement this.
-  Map<Symbol, MethodMirror> get instanceMembers
-      => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this.
-  Map<Symbol, MethodMirror> get staticMembers => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this.
   ClassMirror get mixin => throw new UnimplementedError();
 
   // TODO(ahe): Implement this.
   Function operator [](Symbol name) => throw new UnimplementedError();
+
+  bool get isAbstract => throw new UnimplementedError();
 }
 
 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
@@ -2070,6 +2240,8 @@
   get _namedArguments => JS('=Object', '#.named', _typeData);
   bool get isOriginalDeclaration => true;
 
+  bool get isAbstract => false;
+
   TypeMirror get returnType {
     if (_cachedReturnType != null) return _cachedReturnType;
     if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 7135991..fd6e338 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -130,12 +130,12 @@
       maturity: Maturity.WEB_STABLE,
       dart2jsPath: "web_sql/dart2js/web_sql_dart2js.dart"),
 
-  "_collection-dev": const LibraryInfo(
-      "_collection_dev/collection_dev.dart",
+  "_internal": const LibraryInfo(
+      "internal/internal.dart",
       category: "Internal",
       documented: false,
       dart2jsPatchPath:
-          "_internal/lib/collection_dev_patch.dart"),
+          "_internal/lib/internal_patch.dart"),
 
   "_js_helper": const LibraryInfo(
       "_internal/lib/js_helper.dart",
diff --git a/sdk/lib/_internal/pub/bin/pub.dart b/sdk/lib/_internal/pub/bin/pub.dart
index 451ee6c..777105b 100644
--- a/sdk/lib/_internal/pub/bin/pub.dart
+++ b/sdk/lib/_internal/pub/bin/pub.dart
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:math' as math;
 
 import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
@@ -16,13 +15,11 @@
 import '../lib/src/sdk.dart' as sdk;
 import '../lib/src/utils.dart';
 
-final pubArgParser = initArgParser();
-
 void main(List<String> arguments) {
   ArgResults options;
 
   try {
-    options = pubArgParser.parse(arguments);
+    options = PubCommand.pubArgParser.parse(arguments);
   } on FormatException catch (e) {
     log.error(e.message);
     log.error('Run "pub help" to see available options.');
@@ -36,14 +33,14 @@
   }
 
   if (options['help']) {
-    printUsage();
+    PubCommand.printGlobalUsage();
     return;
   }
 
   if (options.command == null) {
     if (options.rest.isEmpty) {
       // No command was chosen.
-      printUsage();
+      PubCommand.printGlobalUsage();
     } else {
       log.error('Could not find a command named "${options.rest[0]}".');
       log.error('Run "pub help" to see available commands.');
@@ -88,36 +85,6 @@
   });
 }
 
-ArgParser initArgParser() {
-  var argParser = new ArgParser();
-
-  // Add the global options.
-  argParser.addFlag('help', abbr: 'h', negatable: false,
-      help: 'Print this usage information.');
-  argParser.addFlag('version', negatable: false,
-      help: 'Print pub version.');
-  argParser.addFlag('trace',
-       help: 'Print debugging information when an error occurs.');
-  argParser.addOption('verbosity',
-      help: 'Control output verbosity.',
-      allowed: ['normal', 'io', 'solver', 'all'],
-      allowedHelp: {
-        'normal': 'Show errors, warnings, and user messages.',
-        'io':     'Also show IO operations.',
-        'solver': 'Show steps during version resolution.',
-        'all':    'Show all output including internal tracing messages.'
-      });
-  argParser.addFlag('verbose', abbr: 'v', negatable: false,
-      help: 'Shortcut for "--verbosity=all".');
-
-  // Register the commands.
-  PubCommand.commands.forEach((name, command) {
-    argParser.addCommand(name, command.commandParser);
-  });
-
-  return argParser;
-}
-
 /// Checks that pub is running on a supported platform. If it isn't, it prints
 /// an error message and exits. Completes when the validation is done.
 Future validatePlatform() {
@@ -132,43 +99,3 @@
     });
   });
 }
-
-/// Displays usage information for the app.
-void printUsage([String description = 'Pub is a package manager for Dart.']) {
-  // Build up a buffer so it shows up as a single log entry.
-  var buffer = new StringBuffer();
-  buffer.write(description);
-  buffer.write('\n\n');
-  buffer.write('Usage: pub command [arguments]\n\n');
-  buffer.write('Global options:\n');
-  buffer.write('${pubArgParser.getUsage()}\n\n');
-
-  // Show the commands sorted.
-  buffer.write('Available commands:\n');
-
-  // TODO(rnystrom): A sorted map would be nice.
-  int length = 0;
-  var names = <String>[];
-  for (var command in PubCommand.commands.keys) {
-    // Hide aliases.
-    if (PubCommand.commands[command].aliases.indexOf(command) >= 0) continue;
-
-    // Hide undocumented commands.
-    if (PubCommand.commands[command].hidden) continue;
-
-    length = math.max(length, command.length);
-    names.add(command);
-  }
-
-  names.sort((a, b) => a.compareTo(b));
-
-  for (var name in names) {
-    buffer.write('  ${padRight(name, length)}   '
-        '${PubCommand.commands[name].description}\n');
-  }
-
-  buffer.write('\n');
-  buffer.write(
-      'Use "pub help [command]" for more information about a command.');
-  log.message(buffer.toString());
-}
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart
index a5a48a6..785d32f 100644
--- a/sdk/lib/_internal/pub/lib/src/barback.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart
@@ -10,6 +10,7 @@
 import 'package:path/path.dart' as path;
 import 'package:stack_trace/stack_trace.dart';
 
+import 'barback/dart2js_transformer.dart';
 import 'barback/load_all_transformers.dart';
 import 'barback/pub_package_provider.dart';
 import 'barback/server.dart';
@@ -42,6 +43,9 @@
 /// incremented to synchronize with that.
 final supportedVersion = new Version(0, 11, 0);
 
+/// A list of the names of all built-in transformers that pub exposes.
+const _BUILT_IN_TRANSFORMERS = const ['\$dart2js'];
+
 /// An identifier for a transformer and the configuration that will be passed to
 /// it.
 ///
@@ -63,9 +67,12 @@
 
   /// The configuration to pass to the transformer.
   ///
-  /// This will be null if no configuration was provided.
+  /// This will be an empty map if no configuration was provided.
   final Map configuration;
 
+  /// Whether this ID points to a built-in transformer exposed by pub.
+  bool get isBuiltInTransformer => package.startsWith('\$');
+
   /// Parses a transformer identifier.
   ///
   /// A transformer identifier is a string of the form "package_name" or
@@ -85,13 +92,11 @@
     return new TransformerId(parts.first, parts.last, configuration);
   }
 
-  TransformerId(this.package, this.path, this.configuration) {
-    if (configuration == null) return;
-    for (var reserved in ['include', 'exclude']) {
-      if (!configuration.containsKey(reserved)) continue;
-      throw new FormatException('Transformer configuration may not include '
-          'reserved key "$reserved".');
-    }
+  TransformerId(this.package, this.path, Map configuration)
+      : configuration = configuration == null ? {} : configuration {
+    if (!package.startsWith('\$')) return;
+    if (_BUILT_IN_TRANSFORMERS.contains(package)) return;
+    throw new FormatException('Unsupported built-in transformer $package.');
   }
 
   // TODO(nweiz): support deep equality on [configuration] as well.
@@ -134,6 +139,19 @@
 Future<BarbackServer> createServer(String host, int port, PackageGraph graph,
     BarbackMode mode, {Iterable<Transformer> builtInTransformers,
     WatcherType watcher: WatcherType.AUTO}) {
+
+  // If the entrypoint package manually configures the dart2js transformer,
+  // remove it from the built-in transformer list.
+  //
+  // TODO(nweiz): if/when we support more built-in transformers, make this more
+  // general.
+  var containsDart2Js = graph.entrypoint.root.pubspec.transformers.any(
+      (transformers) => transformers.any((id) => id.package == '\$dart2js'));
+  if (containsDart2Js) {
+    builtInTransformers = builtInTransformers.where(
+        (transformer) => transformer is! Dart2JSTransformer);
+  }
+
   var provider = new PubPackageProvider(graph);
   var barback = new Barback(provider);
 
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 9bb3022..aa09244 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -22,14 +22,19 @@
 import '../io.dart';
 import '../package.dart';
 import '../package_graph.dart';
+import '../utils.dart';
+
+/// The set of all valid configuration options for this transformer.
+final _validOptions = new Set<String>.from([
+  'commandLineOptions', 'checked', 'minify', 'verbose', 'environment',
+  'analyzeAll', 'suppressWarnings', 'suppressHints', 'terse'
+]);
 
 /// A [Transformer] that uses dart2js's library API to transform Dart
 /// entrypoints in "web" to JavaScript.
 class Dart2JSTransformer extends Transformer {
   final PackageGraph _graph;
-
-  /// The mode that the transformer is running in.
-  final BarbackMode _mode;
+  final BarbackSettings _settings;
 
   /// The [AssetId]s the transformer has discovered so far. Used by pub build
   /// to determine where to copy the JS bootstrap files.
@@ -46,7 +51,18 @@
   /// is here: https://code.google.com/p/dart/issues/detail?id=14730.
   Future _running;
 
-  Dart2JSTransformer(this._graph, this._mode);
+  Dart2JSTransformer.withSettings(this._graph, this._settings) {
+    var invalidOptions = _settings.configuration.keys.toSet()
+        .difference(_validOptions);
+    if (invalidOptions.isEmpty) return;
+
+    throw new FormatException("Unrecognized dart2js "
+        "${pluralize('option', invalidOptions.length)} "
+        "${toSentence(invalidOptions.map((option) => '"$option"'))}.");
+  }
+
+  Dart2JSTransformer(PackageGraph graph, BarbackMode mode)
+      : this.withSettings(graph, new BarbackSettings({}, mode));
 
   /// Only ".dart" files within "web/" are processed.
   Future<bool> isPrimary(Asset asset) {
@@ -96,7 +112,6 @@
       entrypoints.add(id);
 
       var entrypoint = path.join(_graph.packages[id.package].dir, id.path);
-      var packageRoot = path.join(_graph.entrypoint.root.dir, "packages");
 
       // TODO(rnystrom): Should have more sophisticated error-handling here.
       // Need to report compile errors to the user in an easily visible way.
@@ -104,8 +119,17 @@
       // path so they can understand them.
       return Chain.track(dart.compile(
           entrypoint, provider,
-          packageRoot: packageRoot,
-          minify: _mode == BarbackMode.RELEASE)).then((_) {
+          commandLineOptions: _configCommandLineOptions,
+          checked: _configBool('checked'),
+          minify: _configBool(
+              'minify', defaultsTo: _settings.mode == BarbackMode.RELEASE),
+          verbose: _configBool('verbose'),
+          environment: _configEnvironment,
+          packageRoot: path.join(_graph.entrypoint.root.dir, "packages"),
+          analyzeAll: _configBool('analyzeAll'),
+          suppressWarnings: _configBool('suppressWarnings'),
+          suppressHints: _configBool('suppressHints'),
+          terse: _configBool('terse'))).then((_) {
         stopwatch.stop();
         transform.logger.info("Took ${stopwatch.elapsed} to compile $id.");
       });
@@ -114,6 +138,46 @@
       _running = null;
     });
   }
+
+  /// Parses and returns the "commandLineOptions" configuration option.
+  List<String> get _configCommandLineOptions {
+    if (!_settings.configuration.containsKey('commandLineOptions')) return null;
+
+    var options = _settings.configuration['commandLineOptions'];
+    if (options is List && options.every((option) => option is String)) {
+      return options;
+    }
+
+    throw new FormatException('Invalid value for '
+        '\$dart2js.commandLineOptions: ${JSON.encode(options)} (expected list '
+        'of strings).');
+  }
+
+  /// Parses and returns the "environment" configuration option.
+  Map<String, String> get _configEnvironment {
+    if (!_settings.configuration.containsKey('environment')) return null;
+
+    var environment = _settings.configuration['environment'];
+    if (environment is Map &&
+        environment.keys.every((key) => key is String) &&
+        environment.values.every((key) => key is String)) {
+      return environment;
+    }
+
+    throw new FormatException('Invalid value for \$dart2js.environment: '
+        '${JSON.encode(environment)} (expected map from strings to strings).');
+  }
+
+  /// Parses and returns a boolean configuration option.
+  ///
+  /// [defaultsTo] is the default value of the option.
+  bool _configBool(String name, {bool defaultsTo: false}) {
+    if (!_settings.configuration.containsKey(name)) return defaultsTo;
+    var value = _settings.configuration[name];
+    if (value is bool) return value;
+    throw new FormatException('Invalid value for \$dart2js.$name: '
+        '${JSON.encode(value)} (expected true or false).');
+  }
 }
 
 /// Defines an interface for dart2js to communicate with barback and pub.
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
index 1c2c38b..93c523c 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
@@ -8,6 +8,7 @@
 
 import 'package:barback/barback.dart';
 
+import 'dart2js_transformer.dart';
 import 'load_transformers.dart';
 import 'rewrite_import_transformer.dart';
 import 'server.dart';
@@ -161,6 +162,7 @@
 /// Returns the set of transformer dependencies for [package].
 Set<String> _transformerDeps(PackageGraph graph, String package) =>
   unionAll(graph.packages[package].pubspec.transformers)
+      .where((id) => !id.isBuiltInTransformer)
       .map((id) => id.package).toSet();
 
 /// Returns an [ApplicationException] describing an ordering dependency cycle
@@ -199,6 +201,7 @@
   for (var package in graph.packages.values) {
     for (var phase in package.pubspec.transformers) {
       for (var id in phase) {
+        if (id.isBuiltInTransformer) continue;
         packageTransformers[id.package].add(id);
       }
     }
@@ -208,6 +211,7 @@
 
 /// A class that loads transformers defined in specific files.
 class _TransformerLoader {
+  final PackageGraph _graph;
   final BarbackServer _server;
 
   /// The mode that pub is running barback in.
@@ -222,8 +226,8 @@
   /// Used for error reporting.
   final _transformerUsers = new Map<Pair<String, String>, Set<String>>();
 
-  _TransformerLoader(this._server, this._mode, PackageGraph graph) {
-    for (var package in graph.packages.values) {
+  _TransformerLoader(this._server, this._mode, this._graph) {
+    for (var package in _graph.packages.values) {
       for (var id in unionAll(package.pubspec.transformers)) {
         _transformerUsers.putIfAbsent(
             new Pair(id.package, id.path), () => new Set<String>())
@@ -249,7 +253,7 @@
       }
 
       var message = "No transformers";
-      if (id.configuration != null) {
+      if (id.configuration.isNotEmpty) {
         message += " that accept configuration";
       }
 
@@ -273,7 +277,18 @@
   /// It's an error to call this before [load] is called with [id] and the
   /// future it returns has completed.
   Set<Transformer> transformersFor(TransformerId id) {
-    assert(_transformers.containsKey(id));
+    if (_transformers.containsKey(id)) return _transformers[id];
+
+    assert(id.package == '\$dart2js');
+    var transformer;
+    try {
+      transformer = new Dart2JSTransformer.withSettings(
+          _graph, new BarbackSettings(id.configuration, _mode));
+    } on FormatException catch (error, stackTrace) {
+      fail(error.message, error, stackTrace);
+    }
+
+    _transformers[id] = new Set.from([transformer]);
     return _transformers[id];
   }
 }
\ No newline at end of file
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 c92791b..0f59bf9 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -66,7 +66,7 @@
     if (declaration is! ClassMirror) return null;
     var classMirror = declaration;
     if (classMirror.isPrivate) return null;
-    if (isAbstract(classMirror)) return null;
+    if (classMirror.isAbstract) return null;
     if (!classIsA(classMirror, transformerClass) &&
         !classIsA(classMirror, groupClass)) {
       return null;
@@ -75,15 +75,11 @@
     var constructor = getConstructor(classMirror, 'asPlugin');
     if (constructor == null) return null;
     if (constructor.parameters.isEmpty) {
-      if (configuration != null) return null;
+      if (configuration.isNotEmpty) return null;
       return classMirror.newInstance(const Symbol('asPlugin'), []).reflectee;
     }
     if (constructor.parameters.length != 1) return null;
 
-    // If the constructor expects configuration and none was passed, it defaults
-    // to an empty map.
-    if (configuration == null) configuration = {};
-
     return classMirror.newInstance(const Symbol('asPlugin'),
         [new BarbackSettings(configuration, mode)]).reflectee;
   }).where((classMirror) => classMirror != null);
@@ -164,11 +160,6 @@
       mirror.superinterfaces.any((int) => classIsA(int, superclass));
 }
 
-// TODO(nweiz): get rid of this when issue 12826 is fixed.
-/// Returns whether or not [mirror] is an abstract class.
-bool isAbstract(ClassMirror mirror) => mirror.declarations.values
-    .any((member) => member is MethodMirror && member.isAbstract);
-
 /// Converts [transformerOrGroup] into a serializable map.
 Map _serializeTransformerOrGroup(transformerOrGroup) {
   if (transformerOrGroup is Transformer) {
@@ -188,8 +179,11 @@
         return transformer.isPrimary(deserializeAsset(message['asset']));
       } else {
         assert(message['type'] == 'apply');
+
+        // Make sure we return null so that if the transformer's [apply] returns
+        // a non-serializable value it doesn't cause problems.
         return transformer.apply(
-            new ForeignTransform(message['transform']));
+            new ForeignTransform(message['transform'])).then((_) => null);
       }
     });
   });
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index cb6c46e..65e9f7d 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -260,6 +260,12 @@
   /// Responds to [request] with a 404 response and closes it.
   void _notFound(HttpRequest request, message) {
     _logRequest(request, "404 Not Found");
+
+    // Force a UTF-8 encoding so that error messages in non-English locales are
+    // sent correctly.
+    request.response.headers.contentType =
+        ContentType.parse("text/plain; charset=utf-8");
+
     request.response.statusCode = 404;
     request.response.reasonPhrase = "Not Found";
     request.response.write(message);
diff --git a/sdk/lib/_internal/pub/lib/src/barback/sources.dart b/sdk/lib/_internal/pub/lib/src/barback/sources.dart
index ece690b..672450a 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/sources.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/sources.dart
@@ -50,6 +50,16 @@
         var parts = path.split(event.path);
         if (parts.contains("packages") || parts.contains("assets")) return;
 
+        // Skip ".js" files that were (most likely) compiled from nearby ".dart"
+        // files. These are created by the Editor's "Run as JavaScript" command
+        // and are written directly into the package's directory. When pub's
+        // dart2js transformer then tries to create the same file name, we get
+        // a build error. To avoid that, just don't consider that file to be a
+        // source.
+        // TODO(rnystrom): Remove this when the Editor no longer generates .js
+        // files. See #15859.
+        if (event.path.endsWith(".dart.js")) return;
+
         var id = new AssetId(package.name,
             path.relative(event.path, from: package.dir));
         if (event.type == ChangeType.REMOVE) {
@@ -90,6 +100,16 @@
       // Skip directories.
       if (!fileExists(entry)) continue;
 
+      // Skip ".js" files that were (most likely) compiled from nearby ".dart"
+      // files. These are created by the Editor's "Run as JavaScript" command
+      // and are written directly into the package's directory. When pub's
+      // dart2js transformer then tries to create the same file name, we get
+      // a build error. To avoid that, just don't consider that file to be a
+      // source.
+      // TODO(rnystrom): Remove this when the Editor no longer generates .js
+      // files. See #15859.
+      if (entry.endsWith(".dart.js")) continue;
+
       var id = new AssetId(package.name,
           path.relative(entry, from: package.dir));
       files.add(id);
diff --git a/sdk/lib/_internal/pub/lib/src/command.dart b/sdk/lib/_internal/pub/lib/src/command.dart
index 5e0229c..b36cae4 100644
--- a/sdk/lib/_internal/pub/lib/src/command.dart
+++ b/sdk/lib/_internal/pub/lib/src/command.dart
@@ -4,8 +4,9 @@
 
 library pub.command;
 
-import 'dart:io';
 import 'dart:async';
+import 'dart:io';
+import 'dart:math' as math;
 
 import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
@@ -34,6 +35,40 @@
   /// The commands that pub understands.
   static final Map<String, PubCommand> commands = _initCommands();
 
+  /// The top-level [ArgParser] used to parse the pub command line.
+  static final pubArgParser = _initArgParser();
+
+  /// Displays usage information for the app.
+  static void printGlobalUsage() {
+    // Build up a buffer so it shows up as a single log entry.
+    var buffer = new StringBuffer();
+    buffer.writeln('Pub is a package manager for Dart.');
+    buffer.writeln();
+    buffer.writeln('Usage: pub command [arguments]');
+    buffer.writeln();
+    buffer.writeln('Global options:');
+    buffer.writeln(pubArgParser.getUsage());
+    buffer.writeln();
+
+    // Show the public commands alphabetically.
+    var names = ordered(commands.keys.where((name) =>
+        !commands[name].aliases.contains(name) &&
+        !commands[name].hidden));
+
+    var length = names.map((name) => name.length).reduce(math.max);
+
+    buffer.writeln('Available commands:');
+    for (var name in names) {
+      buffer.writeln('  ${padRight(name, length)}   '
+          '${commands[name].description}');
+    }
+
+    buffer.writeln();
+    buffer.write(
+        'Use "pub help [command]" for more information about a command.');
+    log.message(buffer.toString());
+  }
+
   SystemCache cache;
 
   /// The parsed options for this command.
@@ -211,3 +246,34 @@
 
   return commands;
 }
+
+/// Creates the top-level [ArgParser] used to parse the pub command line.
+ArgParser _initArgParser() {
+  var argParser = new ArgParser();
+
+  // Add the global options.
+  argParser.addFlag('help', abbr: 'h', negatable: false,
+      help: 'Print this usage information.');
+  argParser.addFlag('version', negatable: false,
+      help: 'Print pub version.');
+  argParser.addFlag('trace',
+       help: 'Print debugging information when an error occurs.');
+  argParser.addOption('verbosity',
+      help: 'Control output verbosity.',
+      allowed: ['normal', 'io', 'solver', 'all'],
+      allowedHelp: {
+        'normal': 'Show errors, warnings, and user messages.',
+        'io':     'Also show IO operations.',
+        'solver': 'Show steps during version resolution.',
+        'all':    'Show all output including internal tracing messages.'
+      });
+  argParser.addFlag('verbose', abbr: 'v', negatable: false,
+      help: 'Shortcut for "--verbosity=all".');
+
+  // Register the commands.
+  PubCommand.commands.forEach((name, command) {
+    argParser.addCommand(name, command.commandParser);
+  });
+
+  return argParser;
+}
diff --git a/sdk/lib/_internal/pub/lib/src/command/help.dart b/sdk/lib/_internal/pub/lib/src/command/help.dart
index f02841f..9118175 100644
--- a/sdk/lib/_internal/pub/lib/src/command/help.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/help.dart
@@ -20,7 +20,7 @@
 
   Future onRun() {
     if (commandOptions.rest.isEmpty) {
-      printUsage();
+      PubCommand.printGlobalUsage();
     } else {
       var name = commandOptions.rest[0];
       var command = PubCommand.commands[name];
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index 6833282..af2c409 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -50,16 +50,41 @@
 /// By default, the package root is assumed to be adjacent to [entrypoint], but
 /// if [packageRoot] is passed that will be used instead.
 Future compile(String entrypoint, CompilerProvider provider, {
-    String packageRoot, bool toDart: false, bool minify: true}) {
+    Iterable<String> commandLineOptions,
+    bool checked: false,
+    bool minify: true,
+    bool verbose: false,
+    Map<String, String> environment,
+    String packageRoot,
+    bool analyzeAll: false,
+    bool suppressWarnings: false,
+    bool suppressHints: false,
+    bool terse: false,
+    bool toDart: false}) {
   return syncFuture(() {
     var options = <String>['--categories=Client,Server'];
-    if (toDart) options.add('--output-type=dart');
+    if (checked) options.add('--checked');
     if (minify) options.add('--minify');
+    if (verbose) options.add('--verbose');
+    if (analyzeAll) options.add('--analyze-all');
+    if (suppressWarnings) options.add('--suppress-warnings');
+    if (suppressHints) options.add('--suppress-hints');
+    if (terse) options.add('--terse');
+    if (toDart) options.add('--output-type=dart');
+
+    if (environment != null) {
+      environment.forEach((name, value) {
+        options.add('-D$name=$value');
+      });
+    }
+
+    if (commandLineOptions != null) options.addAll(commandLineOptions);
 
     if (packageRoot == null) {
       packageRoot = path.join(path.dirname(entrypoint), 'packages');
     }
 
+    options.add('--asdfsadfsadf');
     return Chain.track(compiler.compile(
         path.toUri(entrypoint),
         path.toUri(appendSlash(_libPath)),
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 06bd104..804267c 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -295,16 +295,46 @@
 /// Deletes whatever's at [path], whether it's a file, directory, or symlink. If
 /// it's a directory, it will be deleted recursively.
 void deleteEntry(String path) {
-  if (linkExists(path)) {
-    log.io("Deleting link $path.");
-    new Link(path).deleteSync();
-  } else if (dirExists(path)) {
-    log.io("Deleting directory $path.");
-    new Directory(path).deleteSync(recursive: true);
-  } else if (fileExists(path)) {
-    log.io("Deleting file $path.");
-    new File(path).deleteSync();
+  tryDeleteEntry() {
+    if (linkExists(path)) {
+      log.io("Deleting link $path.");
+      new Link(path).deleteSync();
+    } else if (dirExists(path)) {
+      log.io("Deleting directory $path.");
+      new Directory(path).deleteSync(recursive: true);
+    } else if (fileExists(path)) {
+      log.io("Deleting file $path.");
+      new File(path).deleteSync();
+    }
   }
+
+  if (Platform.operatingSystem != 'windows') {
+    tryDeleteEntry();
+    return;
+  }
+
+  // On Windows, we can fail to delete an entry if it's in use by another
+  // process. The only case where we know this to cause a problem is when
+  // testing "pub serve", since it can poll a file at the same time we try to
+  // delete it in the test process (issue 16129).
+  //
+  // TODO(nweiz): Once issue 14428 is fixed for Windows, remove this special
+  // handling.
+  for (var i = 0; i < 2; i++) {
+    try {
+      tryDeleteEntry();
+    } on FileSystemException catch (error) {
+      // Errno 32 indicates that the deletion failed because the file was in
+      // use.
+      if (error.osError.errorCode != 32) rethrow;
+
+      log.io("Failed to delete entry because it was in use by another process. "
+          "Retrying in 50ms.");
+      sleep(new Duration(milliseconds: 50));
+    }
+  }
+
+  tryDeleteEntry();
 }
 
 /// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
diff --git a/sdk/lib/_internal/pub/lib/src/oauth2.dart b/sdk/lib/_internal/pub/lib/src/oauth2.dart
index 7146817..f3b1c27 100644
--- a/sdk/lib/_internal/pub/lib/src/oauth2.dart
+++ b/sdk/lib/_internal/pub/lib/src/oauth2.dart
@@ -13,7 +13,6 @@
 import 'http.dart';
 import 'io.dart';
 import 'log.dart' as log;
-import 'safe_http_server.dart';
 import 'system_cache.dart';
 import 'utils.dart';
 
@@ -168,7 +167,7 @@
   // Spin up a one-shot HTTP server to receive the authorization code from the
   // Google OAuth2 server via redirect. This server will close itself as soon as
   // the code is received.
-  return SafeHttpServer.bind('127.0.0.1', 0).then((server) {
+  return HttpServer.bind('127.0.0.1', 0).then((server) {
     var authUrl = grant.getAuthorizationUrl(
         Uri.parse('http://127.0.0.1:${server.port}'), scopes: _scopes);
 
diff --git a/sdk/lib/_internal/pub/lib/src/pubspec.dart b/sdk/lib/_internal/pub/lib/src/pubspec.dart
index c5c5c1a..df9359a 100644
--- a/sdk/lib/_internal/pub/lib/src/pubspec.dart
+++ b/sdk/lib/_internal/pub/lib/src/pubspec.dart
@@ -177,7 +177,7 @@
             "$field.$library",
             () => new TransformerId.parse(library, configuration));
 
-        if (id.package != name &&
+        if (id.package != name && !id.isBuiltInTransformer &&
             !dependencies.any((ref) => ref.name == id.package)) {
           _error('"$field.$library" refers to a package that\'s not listed in '
               '"dependencies".');
diff --git a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
deleted file mode 100644
index f45741f..0000000
--- a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
+++ /dev/null
@@ -1,169 +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 pub.safe_http_server;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-// TODO(nweiz): remove this when issue 9140 is fixed.
-/// A wrapper around [HttpServer] that swallows errors caused by requests
-/// behaving badly. This provides the following guarantees:
-///
-/// * The [SafeHttpServer.listen] onError callback will only emit server-wide
-///   errors. It will not emit errors for requests that were unparseable or
-///   where the connection was closed too soon.
-/// * [HttpResponse.done] will emit no errors.
-///
-/// The [HttpRequest] data stream can still emit errors.
-class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
-  final HttpServer _inner;
-
-  static Future<SafeHttpServer> bind([String host = "localhost",
-      int port = 0, int backlog = 0]) {
-    return HttpServer.bind(host, port, backlog: backlog)
-        .then((server) => new SafeHttpServer(server));
-  }
-
-  SafeHttpServer(HttpServer server)
-      : super(server),
-        _inner = server;
-
-  Future close({bool force: false}) => _inner.close(force: force);
-
-  InternetAddress get address => _inner.address;
-  int get port => _inner.port;
-
-  set sessionTimeout(int timeout) {
-    _inner.sessionTimeout = timeout;
-  }
-
-  String get serverHeader => _inner.serverHeader;
-  set serverHeader(String value) {
-    _inner.serverHeader = value;
-  }
-
-  Duration get idleTimeout => _inner.idleTimeout;
-  set idleTimeout(Duration value) {
-    _inner.idleTimeout = value;
-  }
-
-  HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
-
-  StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
-      {Function onError, void onDone(),
-      bool cancelOnError: false}) {
-    var subscription;
-    subscription = super.listen((request) {
-      onData(new _HttpRequestWrapper(request));
-    }, onError: (error, [stackTrace]) {
-      // Ignore socket error 104, which is caused by a request being cancelled
-      // before it writes any headers. There's no reason to care about such
-      // requests.
-      if (error is SocketException && error.osError.errorCode == 104) return;
-      // Ignore any parsing errors, which come from malformed requests.
-      if (error is HttpException) return;
-      // Manually handle cancelOnError so the above (ignored) errors don't
-      // cause unsubscription.
-      if (cancelOnError) subscription.cancel();
-      if (onError != null) {
-        if (onError is ZoneBinaryCallback) {
-          onError(error, stackTrace);
-        } else {
-          onError(error);
-        }
-      }
-    }, onDone: onDone);
-    return subscription;
-  }
-}
-
-/// A wrapper around [HttpRequest] for the sole purpose of swallowing errors on
-/// [HttpResponse.done].
-class _HttpRequestWrapper extends StreamView<List<int>> implements HttpRequest {
-  final HttpRequest _inner;
-  final HttpResponse response;
-
-  _HttpRequestWrapper(HttpRequest inner)
-      : super(inner),
-        _inner = inner,
-        response = new _HttpResponseWrapper(inner.response);
-
-  int get contentLength => _inner.contentLength;
-  String get method => _inner.method;
-  Uri get uri => _inner.uri;
-  HttpHeaders get headers => _inner.headers;
-  List<Cookie> get cookies => _inner.cookies;
-  bool get persistentConnection => _inner.persistentConnection;
-  X509Certificate get certificate => _inner.certificate;
-  HttpSession get session => _inner.session;
-  String get protocolVersion => _inner.protocolVersion;
-  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
-}
-
-/// A wrapper around [HttpResponse] for the sole purpose of swallowing errors on
-/// [done].
-class _HttpResponseWrapper implements HttpResponse {
-  final HttpResponse _inner;
-  Future<HttpResponse> _done;
-
-  _HttpResponseWrapper(this._inner);
-
-  /// Swallows all errors from writing to the response.
-  Future<HttpResponse> get done {
-    if (_done == null) _done = _inner.done.catchError((_) {});
-    return _done;
-  }
-
-  int get contentLength => _inner.contentLength;
-  set contentLength(int value) {
-    _inner.contentLength = value;
-  }
-
-  int get statusCode => _inner.statusCode;
-  set statusCode(int value) {
-    _inner.statusCode = value;
-  }
-
-  String get reasonPhrase => _inner.reasonPhrase;
-  set reasonPhrase(String value) {
-    _inner.reasonPhrase = value;
-  }
-
-  bool get persistentConnection => _inner.persistentConnection;
-  set persistentConnection(bool value) {
-    _inner.persistentConnection = value;
-  }
-
-  Encoding get encoding => _inner.encoding;
-  set encoding(Encoding value) {
-    _inner.encoding = value;
-  }
-
-  HttpHeaders get headers => _inner.headers;
-  List<Cookie> get cookies => _inner.cookies;
-  Future<Socket> detachSocket() => _inner.detachSocket();
-  HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
-  void add(List<int> data) => _inner.add(data);
-  Future<HttpResponse> addStream(Stream<List<int>> stream) =>
-    _inner.addStream(stream);
-  Future close() => _inner.close();
-  Future flush() => _inner.flush();
-  void write(Object obj) => _inner.write(obj);
-  void writeAll(Iterable objects, [String separator = ""]) =>
-    _inner.writeAll(objects, separator);
-  void writeCharCode(int charCode) => _inner.writeCharCode(charCode);
-  void writeln([Object obj = ""]) => _inner.writeln(obj);
-  void addError(error, [StackTrace stackTrace]) =>
-      _inner.addError(error, stackTrace);
-
-  Duration get deadline => _inner.deadline;
-  set deadline(Duration value) {
-    _inner.deadline = value;
-  }
-
-  Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY}) =>
-      _inner.redirect(location, status: status);
-}
diff --git a/sdk/lib/_internal/pub/lib/src/utils.dart b/sdk/lib/_internal/pub/lib/src/utils.dart
index dc25e53..34cc6c1 100644
--- a/sdk/lib/_internal/pub/lib/src/utils.dart
+++ b/sdk/lib/_internal/pub/lib/src/utils.dart
@@ -202,6 +202,21 @@
   return '${name}s';
 }
 
+/// Escapes any regex metacharacters in [string] so that using as a [RegExp]
+/// pattern will match the string literally.
+// TODO(rnystrom): Remove when #4706 is fixed.
+String quoteRegExp(String string) {
+  // Note: make sure "\" is done first so that we don't escape the other
+  // escaped characters. We could do all of the replaces at once with a regexp
+  // but string literal for regex that matches all regex metacharacters would
+  // be a bit hard to read.
+  for (var metacharacter in r"\^$.*+?()[]{}|".split("")) {
+    string = string.replaceAll(metacharacter, "\\$metacharacter");
+  }
+
+  return string;
+}
+
 /// Creates a URL string for [address]:[port].
 ///
 /// Handles properly formatting IPv6 addresses.
diff --git a/sdk/lib/_internal/pub/lib/src/validator.dart b/sdk/lib/_internal/pub/lib/src/validator.dart
index 640c54f..e448058 100644
--- a/sdk/lib/_internal/pub/lib/src/validator.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator.dart
@@ -13,7 +13,6 @@
 import 'validator/dependency.dart';
 import 'validator/dependency_override.dart';
 import 'validator/directory.dart';
-import 'validator/lib.dart';
 import 'validator/license.dart';
 import 'validator/name.dart';
 import 'validator/pubspec_field.dart';
@@ -51,7 +50,6 @@
   static Future<Pair<List<String>, List<String>>> runAll(
       Entrypoint entrypoint, [Future<int> packageSize]) {
     var validators = [
-      new LibValidator(entrypoint),
       new LicenseValidator(entrypoint),
       new NameValidator(entrypoint),
       new PubspecFieldValidator(entrypoint),
diff --git a/sdk/lib/_internal/pub/lib/src/validator/lib.dart b/sdk/lib/_internal/pub/lib/src/validator/lib.dart
deleted file mode 100644
index 22ed406..0000000
--- a/sdk/lib/_internal/pub/lib/src/validator/lib.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 pub.validator.lib;
-
-import 'dart:async';
-
-import 'package:path/path.dart' as path;
-
-import '../entrypoint.dart';
-import '../io.dart';
-import '../utils.dart';
-import '../validator.dart';
-
-// TODO(nweiz): When issue 7196 is fixed, complain about non-Dart files in lib.
-/// A validator that checks that libraries in "lib/" (and not "lib/src/") exist
-/// and are well-formed.
-class LibValidator extends Validator {
-  LibValidator(Entrypoint entrypoint)
-    : super(entrypoint);
-
-  Future validate() {
-    return syncFuture(() {
-      var libDir = path.join(entrypoint.root.dir, "lib");
-
-      if (!dirExists(libDir)) {
-        errors.add('You must have a "lib" directory.\n'
-            "Without that, users cannot import any code from your package.");
-        return;
-      }
-
-      var files = listDir(libDir)
-          .map((file) => path.relative(file, from: libDir))
-          .toList();
-      if (files.isEmpty) {
-        errors.add('You must have a non-empty "lib" directory.\n'
-            "Without that, users cannot import any code from your package.");
-      } else if (files.length == 1 && files.first == "src") {
-        errors.add('The "lib" directory must contain something other than '
-            '"src".\n'
-            "Otherwise, users cannot import any code from your package.");
-      }
-    });
-  }
-}
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 2165264..4e7d2c0 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -7,9 +7,8 @@
 test/upgrade/hosted/upgrade_removed_constraints_test: Pass, Fail # Issue 15349
 
 [ $runtime == vm && $system == windows ]
-test/serve/watch_removed_file_test: Pass, Fail # Issue 13026
-test/serve/missing_file_test: Pass, Fail # Issue 15431
 test/serve/warns_on_assets_paths_test: Pass, Fail # Issue 15741
+test/serve/missing_file_test: Pass, Fail # Issue 16129
 
 # Pub only runs on the VM, so just rule out all compilers.
 [ $compiler == dart2js || $compiler == dart2dart ]
diff --git a/sdk/lib/_internal/pub/test/build/ignores_existing_compiled_js_files_test.dart b/sdk/lib/_internal/pub/test/build/ignores_existing_compiled_js_files_test.dart
new file mode 100644
index 0000000..7aecefe
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/build/ignores_existing_compiled_js_files_test.dart
@@ -0,0 +1,43 @@
+// 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:scheduled_test/scheduled_test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+
+main() {
+  initConfig();
+
+  integration("ignores existing JS files that were compiled to Dart", () {
+    // Dart2js can take a long time to compile dart code, so we increase the
+    // timeout to cope with that.
+    currentSchedule.timeout *= 3;
+
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir('web', [
+        d.file('file.dart', 'void main() => print("hello");'),
+        d.file('file.dart.js', 'some js code'),
+        d.dir('subdir', [
+          d.file('subfile.dart', 'void main() => print("ping");'),
+          d.file('subfile.dart.js', 'some js code')
+        ])
+      ])
+    ]).create();
+
+    schedulePub(args: ["build"],
+        output: new RegExp(r"Built 6 files!"),
+        exitCode: 0);
+
+    d.dir(appPath, [
+      d.dir('build', [
+        d.matcherFile('file.dart.js', isNot(equals('some js code'))),
+        d.dir('subdir', [
+          d.matcherFile('subfile.dart.js', isNot(equals('some js code')))
+        ])
+      ])
+    ]).validate();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/build/warns_on_assets_paths_test.dart b/sdk/lib/_internal/pub/test/build/warns_on_assets_paths_test.dart
index 90c69f0..c9a19c2 100644
--- a/sdk/lib/_internal/pub/test/build/warns_on_assets_paths_test.dart
+++ b/sdk/lib/_internal/pub/test/build/warns_on_assets_paths_test.dart
@@ -6,12 +6,13 @@
 
 import 'package:path/path.dart' as path;
 
+import '../../lib/src/utils.dart';
 import '../descriptor.dart' as d;
 import '../test_pub.dart';
 
 getWarningRegExp(String assetsPath) {
   // Escape backslashes since they are metacharacters in a regex.
-  assetsPath = assetsPath.replaceAll("\\", "\\\\");
+  assetsPath = quoteRegExp(assetsPath);
   return new RegExp(
       '^Warning: Pub reserves paths containing "assets" for using assets from '
       'packages\\. Please rename the path "$assetsPath"\\.\$');
diff --git a/sdk/lib/_internal/pub/test/pub_test.dart b/sdk/lib/_internal/pub/test/pub_test.dart
index 9651554..336e125 100644
--- a/sdk/lib/_internal/pub/test/pub_test.dart
+++ b/sdk/lib/_internal/pub/test/pub_test.dart
@@ -128,6 +128,10 @@
   });
 
   group('help', () {
+    integration('shows global help if no command is given', () {
+      schedulePub(args: ['help'], output: USAGE_STRING);
+    });
+
     integration('shows help for a command', () {
       schedulePub(args: ['help', 'get'],
           output: '''
diff --git a/sdk/lib/_internal/pub/test/serve/does_not_watch_compiled_js_files_test.dart b/sdk/lib/_internal/pub/test/serve/does_not_watch_compiled_js_files_test.dart
new file mode 100644
index 0000000..7459869
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/does_not_watch_compiled_js_files_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import 'utils.dart';
+
+main() {
+  initConfig();
+  integration("does not watch changes to compiled JS files in the package", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("web", [
+        d.file("index.html", "body")
+      ])
+    ]).create();
+
+    pubServe();
+    waitForBuildSuccess();
+    requestShouldSucceed("index.html", "body");
+
+    d.dir(appPath, [
+      d.dir("web", [
+        d.file('file.dart', 'void main() => print("hello");'),
+        d.file("other.dart.js", "should be ignored"),
+      ])
+    ]).create();
+
+    waitForBuildSuccess();
+    requestShouldSucceed("file.dart", 'void main() => print("hello");');
+    requestShould404("other.dart.js");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/serve/missing_file_test.dart b/sdk/lib/_internal/pub/test/serve/missing_file_test.dart
index 47956b9..3b593ec 100644
--- a/sdk/lib/_internal/pub/test/serve/missing_file_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/missing_file_test.dart
@@ -14,7 +14,7 @@
 
 main() {
   initConfig();
-  integration("responds with a 404 for missing files", () {
+  integration("responds with a 404 for missing source files", () {
     d.dir(appPath, [
       d.appPubspec(),
       d.dir("asset", [
@@ -32,13 +32,6 @@
     // assets for them.
     pubServe();
 
-    // TODO(rnystrom): When pub serve supports file watching, we'll have to do
-    // something here to specifically disable that so that we can get barback
-    // into the inconsistent state of thinking there is an asset but where the
-    // underlying file does not exist. One option would be configure barback
-    // with an insanely long delay between polling to ensure a poll doesn't
-    // happen.
-
     // Now delete them.
     schedule(() {
       deleteEntry(path.join(sandboxDir, appPath, "asset", "nope.png"));
@@ -46,6 +39,11 @@
       deleteEntry(path.join(sandboxDir, appPath, "web", "index.html"));
     }, "delete files");
 
+    // Now request them.
+    // TODO(rnystrom): It's possible for these requests to happen quickly
+    // enough that the file system hasn't notified for the deletions yet. If
+    // that happens, we can probably just add a short delay here.
+
     requestShould404("index.html");
     requestShould404("packages/myapp/nope.dart");
     requestShould404("assets/myapp/nope.png");
diff --git a/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart b/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart
index c4ae0c5..e77af93 100644
--- a/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/warns_on_assets_paths_test.dart
@@ -7,13 +7,14 @@
 import 'package:path/path.dart' as path;
 import 'package:scheduled_test/scheduled_test.dart';
 
+import '../../lib/src/utils.dart';
 import '../descriptor.dart' as d;
 import '../test_pub.dart';
 import 'utils.dart';
 
 getWarningRegExp(String assetsPath) {
   // Escape backslashes since they are metacharacters in a regex.
-  assetsPath = assetsPath.replaceAll("\\", "\\\\");
+  assetsPath = quoteRegExp(assetsPath);
   return new RegExp(
       '^Warning: Pub reserves paths containing "assets" for using assets from '
       'packages\\. Please rename the path "$assetsPath"\\.\$');
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 22c12b2..8a78713 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -31,7 +31,6 @@
 import '../lib/src/lock_file.dart';
 import '../lib/src/log.dart' as log;
 import '../lib/src/package.dart';
-import '../lib/src/safe_http_server.dart';
 import '../lib/src/source/hosted.dart';
 import '../lib/src/source/path.dart';
 import '../lib/src/source_registry.dart';
@@ -103,7 +102,7 @@
 
   schedule(() {
     return _closeServer().then((_) {
-      return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
+      return HttpServer.bind("127.0.0.1", 0).then((server) {
         _server = server;
         server.listen((request) {
           currentSchedule.heartbeat();
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart
new file mode 100644
index 0000000..c13a5a2
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_command_line_options_type_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+
+  integration("doesn't support invalid commandLineOptions type", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": [{
+          "\$dart2js": {
+            "commandLineOptions": "foo",
+          }
+        }]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", REWRITE_TRANSFORMER)
+      ])]),
+      d.dir("web", [d.file("main.dart", "void main() {}")])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    var server = pubServe();
+    expect(server.nextErrLine(), completion(equals('Build error:')));
+    expect(server.nextErrLine(), completion(equals(
+        'Transform Dart2JS on myapp|web/main.dart threw error: '
+            'FormatException: Invalid value for \$dart2js.commandLineOptions: '
+            '"foo" (expected list of strings).')));
+    requestShould404("main.dart.js");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart
new file mode 100644
index 0000000..4c882df
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_environment_type_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+
+  integration("doesn't support invalid environment type", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": [{
+          "\$dart2js": {
+            "environment": "foo",
+          }
+        }]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", REWRITE_TRANSFORMER)
+      ])]),
+      d.dir("web", [d.file("main.dart", "void main() {}")])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    var server = pubServe();
+    expect(server.nextErrLine(), completion(equals('Build error:')));
+    expect(server.nextErrLine(), completion(equals(
+        'Transform Dart2JS on myapp|web/main.dart threw error: '
+            'FormatException: Invalid value for \$dart2js.environment: "foo" '
+            '(expected map from strings to strings).')));
+    requestShould404("main.dart.js");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart
new file mode 100644
index 0000000..b683978
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/does_not_support_invalid_option_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+
+  integration("doesn't support an invalid dart2js option", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": [{
+          "\$dart2js": {"invalidOption": true}
+        }]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", REWRITE_TRANSFORMER)
+      ])])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    // TODO(nweiz): This should provide more context about how the option got
+    // passed to dart2js. See issue 16008.
+    var pub = startPubServe();
+    expect(pub.nextErrLine(), completion(
+        equals('Unrecognized dart2js option "invalidOption".')));
+    pub.shouldExit(1);
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart
new file mode 100644
index 0000000..4560fcb
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/doesnt_support_invalid_type_for_boolean_option_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+
+  integration("doesn't support invalid type for boolean option", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": [{
+          "\$dart2js": {
+            "checked": "foo",
+          }
+        }]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", REWRITE_TRANSFORMER)
+      ])]),
+      d.dir("web", [d.file("main.dart", "void main() {}")])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    var server = pubServe();
+    requestShould404("main.dart.js");
+    expect(server.nextErrLine(), completion(equals('Build error:')));
+    expect(server.nextErrLine(), completion(equals(
+        'Transform Dart2JS on myapp|web/main.dart threw error: '
+            'FormatException: Invalid value for \$dart2js.checked: "foo" '
+            '(expected true or false).')));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/minify_configuration_overrides_mode_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/minify_configuration_overrides_mode_test.dart
new file mode 100644
index 0000000..3931f5f
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/minify_configuration_overrides_mode_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+
+  integration("minify configuration overrides the mode", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": [{
+          "\$dart2js": {"minify": true}
+        }]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", REWRITE_TRANSFORMER)
+      ])])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    pubServe();
+    requestShouldSucceed("main.dart.js", isMinifiedDart2JSOutput);
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/output_can_be_consumed_by_successive_phases.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/output_can_be_consumed_by_successive_phases.dart
new file mode 100644
index 0000000..4bdd694
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/output_can_be_consumed_by_successive_phases.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+/// The code for a transformer that renames ".js" files to ".out".
+const JS_REWRITE_TRANSFORMER = """
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+
+class RewriteTransformer extends Transformer {
+  RewriteTransformer.asPlugin();
+
+  String get allowedExtensions => '.js';
+
+  Future apply(Transform transform) {
+    return transform.primaryInput.readAsString().then((contents) {
+      var id = transform.primaryInput.id.changeExtension(".out");
+      transform.addOutput(new Asset.fromString(id, contents));
+    });
+  }
+}
+""";
+
+main() {
+  initConfig();
+
+  integration("output can be consumed by successive phases", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": ["\$dart2js", "myapp/src/transformer"]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", JS_REWRITE_TRANSFORMER)
+      ])]),
+      d.dir("web", [d.file("main.dart", "void main() {}")])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    pubServe();
+    requestShouldSucceed("main.dart.out", isUnminifiedDart2JSOutput);
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart
new file mode 100644
index 0000000..ffdda13
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/supports_valid_options_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+
+  integration("supports most dart2js command-line options", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": [{
+          "\$dart2js": {
+            "commandLineOptions": ["--enable-diagnostic-colors"],
+            "checked": true,
+            "minify": true,
+            "verbose": true,
+            "environment": {"name": "value"},
+            "analyzeAll": true,
+            "suppressWarnings": true,
+            "suppressHints": true,
+            "terse": true
+          }
+        }]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", REWRITE_TRANSFORMER)
+      ])])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    // None of these options should be rejected, either by pub or by dart2js.
+    pubServe();
+    requestShouldSucceed("main.dart.js", isNot(isEmpty));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart
similarity index 80%
rename from sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart
rename to sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart
index 7394784..8eed7c4 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_config_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_pubspec_with_reserved_transformer_test.dart
@@ -13,11 +13,11 @@
 main() {
   initConfig();
 
-  integration("fails to load a pubspec with reserved transformer config", () {
+  integration("fails to load a pubspec with reserved transformer", () {
     d.dir(appPath, [
       d.pubspec({
         "name": "myapp",
-        "transformers": [{"myapp/src/transformer": {'include': 'something'}}]
+        "transformers": ["\$nonexistent"]
       }),
       d.dir("lib", [d.dir("src", [
         d.file("transformer.dart", REWRITE_TRANSFORMER)
@@ -30,8 +30,8 @@
     expect(pub.nextErrLine(), completion(equals('Error in pubspec for package '
         '"myapp" loaded from pubspec.yaml:')));
     expect(pub.nextErrLine(), completion(equals('Invalid transformer '
-       'identifier for "transformers.myapp/src/transformer": Transformer '
-       'configuration may not include reserved key "include".')));
+       'identifier for "transformers.\$nonexistent": Unsupported built-in '
+       'transformer \$nonexistent.')));
     pub.shouldExit(1);
   });
 }
diff --git a/sdk/lib/_internal/pub/test/validator/lib_test.dart b/sdk/lib/_internal/pub/test/validator/lib_test.dart
deleted file mode 100644
index c717e1f..0000000
--- a/sdk/lib/_internal/pub/test/validator/lib_test.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:path/path.dart' as path;
-import 'package:scheduled_test/scheduled_test.dart';
-
-import '../../lib/src/entrypoint.dart';
-import '../../lib/src/io.dart';
-import '../../lib/src/validator.dart';
-import '../../lib/src/validator/lib.dart';
-import '../descriptor.dart' as d;
-import '../test_pub.dart';
-import 'utils.dart';
-
-Validator lib(Entrypoint entrypoint) => new LibValidator(entrypoint);
-
-main() {
-  initConfig();
-
-  group('should consider a package valid if it', () {
-    setUp(d.validPackage.create);
-
-    integration('looks normal', () => expectNoValidationError(lib));
-
-    integration('has a non-Dart file in lib', () {
-      d.dir(appPath, [
-        d.libPubspec("test_pkg", "1.0.0"),
-        d.dir("lib", [
-          d.file("thing.txt", "woo hoo")
-        ])
-      ]).create();
-      expectNoValidationError(lib);
-    });
-  });
-
-  group('should consider a package invalid if it', () {
-    setUp(d.validPackage.create);
-
-    integration('has no lib directory', () {
-      schedule(() => deleteEntry(path.join(sandboxDir, appPath, "lib")));
-      expectValidationError(lib);
-    });
-
-    integration('has an empty lib directory', () {
-      schedule(() =>
-          deleteEntry(path.join(sandboxDir, appPath, "lib", "test_pkg.dart")));
-      expectValidationError(lib);
-    });
-
-    integration('has a lib directory containing only src', () {
-      schedule(() =>
-          deleteEntry(path.join(sandboxDir, appPath, "lib", "test_pkg.dart")));
-      d.dir(appPath, [
-        d.dir("lib", [
-          d.dir("src", [d.file("test_pkg.dart", "int i = 0;")])
-        ])
-      ]).create();
-      expectValidationError(lib);
-    });
-  });
-}
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index a565220..7de40e6 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -6,14 +6,71 @@
  * Support for asynchronous programming,
  * with classes such as Future and Stream.
  *
- * 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).
+ * Understanding [Future]s and [Stream]s is a prerequisite for
+ * writing just about any Dart program.
+ *
+ * To use this library in your code:
+ *
+ *     import 'dart:async';
+ *
+ * ## Future
+ *
+ * A Future object represents a computation whose return value
+ * might not yet be available.
+ * The Future returns the value of the computation
+ * when it completes at some time in the future.
+ * Futures are often used for potentially lengthy computations
+ * such as I/O and interaction with users.
+ *
+ * Many methods in the Dart libraries return Futures when
+ * performing tasks. For example, when binding an HttpServer
+ * to a host and port, the `bind()` method returns a Future.
+ *
+ *      HttpServer.bind('127.0.0.1', 4444)
+ *          .then((server) => print('${server.isBroadcast}'))
+ *          .catchError(print);
+ *
+ * [Future.then] registers a callback function that runs
+ * when the Future's operation, in this case the `bind()` method,
+ * completes successfully.
+ * The value returned by the operation
+ * is passed into the callback function.
+ * In this example, the `bind()` method returns the HttpServer
+ * object. The callback function prints one of its properties.
+ * [Future.catchError] registers a callback function that
+ * runs if an error occurs within the Future.
+ *
+ * ## Stream
+ *
+ * A Stream provides an asynchronous sequence of data.
+ * Examples of data sequences include user-generated events,
+ * such as mouse clicks, and a stream of bytes read from a file.
+ * The following example opens a file for reading.
+ * [Stream.listen] registers a callback function that runs
+ * each time more data is available.
+ *
+ *     Stream<List<int>> stream = new File('quotes.txt').openRead();
+ *     stream.transform(UTF8.decoder).listen(print);
+ *
+ * The stream emits a sequence of a list of bytes.
+ * The program must interpret the bytes or handle the raw byte data.
+ * Here, the code uses a UTF8 decoder (provided in the `dart:convert` library)
+ * to convert the sequence of bytes into a sequence
+ * of Dart strings.
+ *
+ * Another common use of streams is for user-generated events
+ * in a web app: The following code listens for mouse clicks on a button.
+ *
+ *     querySelector('#myButton').onClick.listen((_) => print('Click.'));
  *
  * ## Other resources
  *
- * * [Using Future Based APIs]
- * (https://www.dartlang.org/articles/using-future-based-apis/): A first look at
+ * * The [dart:async section of the library tour]
+ * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-asynchronous-programming):
+ * A brief overview of asynchronous programming.
+ *
+ * * [Use Future-Based APIs]
+ * (https://www.dartlang.org/docs/tutorials/futures/): A closer look at
  * Futures and how to use them to write asynchronous Dart code.
  *
  * * [Futures and Error Handling]
@@ -32,7 +89,7 @@
 library dart.async;
 
 import "dart:collection";
-import "dart:_collection-dev" show deprecated, printToZone, printToConsole;
+import "dart:_internal" show deprecated, printToZone, printToConsole;
 
 part 'async_error.dart';
 part 'broadcast_stream_controller.dart';
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index f18cb1dd..5c3e046 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -291,25 +291,36 @@
   }
 
   /**
-   * When this future completes with a value, then [onValue] is called with this
-   * value. If [this] future is already completed then the invocation of
-   * [onValue] is delayed until the next event-loop iteration.
+   * Register callbacks to be called when this future completes.
    *
-   * Returns a new [Future] `f` which is completed with the result of
-   * invoking [onValue] (if [this] completes with a value) or [onError] (if
-   * [this] completes with an error).
+   * When this future completes with a value,
+   * the [onValue] callback will be called with that value.
+   * If this future is already completed, the callback will not be called
+   * immediately, but will be scheduled in a later microtask.
    *
-   * If the invoked callback throws an exception, the returned future `f` is
-   * completed with the error.
+   * If [onError] is provided, and this future completes with an error,
+   * the `onError` callback is called with that error its stack trace.
+   * The `onError` callback must accept either one argument or two arguments.
+   * If `onError` accepts two arguments,
+   * it is called with both the error and the stack trace,
+   * otherwise it is called with just the error object.
    *
-   * If the invoked callback returns a [Future] `f2` then `f` and `f2` are
-   * chained. That is, `f` is completed with the completion value of `f2`.
+   * Returns a new [Future]
+   * which is completed with the result of the call to `onValue`
+   * (if this future completes with a value)
+   * or to `onError` (if this future completes with an error).
    *
-   * The [onError] callback must be of type `void onError(error)` or
-   * `void onError(error, StackTrace stackTrace)`. If [onError] accepts
-   * two arguments it is called with the stack trace (which could be `null` if
-   * the stream itself received an error without stack trace).
-   * Otherwise it is called with just the error object.
+   * If the invoked callback throws,
+   * the returned future is completed with the thrown error
+   * and a stack trace for the error.
+   * In the case of `onError`,
+   * if the exception thrown is the same as the argument to `onError`,
+   * the throw is considered a rethrow,
+   * and the original stack trace is used instead.
+   *
+   * If the callback returns a [Future],
+   * the future returned by `then` will be completed with
+   * the same result of the future returned by the callback.
    *
    * If [onError] is not given it forwards the error to `f`.
    *
@@ -322,20 +333,29 @@
   /**
    * Handles errors emitted by this [Future].
    *
-   * Returns a new [Future] `f`.
+   * This is the asynchronous equivalent of a "catch" block.
    *
-   * When [this] completes with a value, the value is forwarded to `f`
-   * unmodified. That is, `f` completes with the same value.
+   * Returns a new [Future] that will be completed with either the result of
+   * this future or the result of calling the `onError` callback.
    *
-   * When [this] completes with an error, [test] is called with the
-   * error's value. If the invocation returns [true], [onError] is called with
-   * the error. The result of [onError] is handled exactly the same as for
-   * [then]'s [onError].
+   * If this future completes with a value,
+   * the returned future completes with the same value.
    *
-   * If [test] returns false, the exception is not handled by [onError], but is
-   * thrown unmodified, thus forwarding it to `f`.
+   * If this future completes with an error,
+   * then [test] is first called with the error value.
    *
-   * If [test] is omitted, it defaults to a function that always returns true.
+   * If `test` returns false, the exception is not handled by this `catchError`,
+   * and the returned future completes with the same error and stack trace
+   * as this future.
+   *
+   * If `test` returns `true`,
+   * [onError] is called with the error and possibly stack trace,
+   * and the returned future is completed with the result of this call
+   * in exactly the same way as for [then]'s `onError`.
+   *
+   * If `test` is omitted, it defaults to a function that always returns true.
+   * The `test` function should not throw, but if it does, it is handled as
+   * if the the `onError` function had thrown.
    *
    * Example:
    *
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index b722e46..aca62a9 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1341,8 +1341,6 @@
  * This wraps a [Stream] and a subscription on the stream. It listens
  * on the stream, and completes the future returned by [moveNext] when the
  * next value becomes available.
- *
- * NOTICE: This is a tentative design. This class may change.
  */
 abstract class StreamIterator<T> {
 
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 3d7a2b3..78c4087 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -952,6 +952,7 @@
     }
     if (_state == _STATE_FOUND) {
       _state = _STATE_MOVING;
+      _current = null;
       _futureOrPrefetch = new _Future<bool>();
       return _futureOrPrefetch;
     } else {
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 54085f7..4620bc0 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -7,7 +7,7 @@
  */
 library dart.collection;
 
-import 'dart:_collection-dev';
+import 'dart:_internal';
 import 'dart:math' show Random;  // Used by ListMixin.shuffle.
 
 part 'collections.dart';
diff --git a/sdk/lib/convert/convert.dart b/sdk/lib/convert/convert.dart
index 8cdc936..e493ec0 100644
--- a/sdk/lib/convert/convert.dart
+++ b/sdk/lib/convert/convert.dart
@@ -3,8 +3,54 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * Converters for JSON and UTF-8, as well as support for creating additional
- * converters.
+ *
+ * Encoders and decoders for converting between different data representations,
+ * including JSON and UTF-8.
+ *
+ * In addition to converters for common data representations, this library
+ * provides support for implementing converters in a way which makes them easy to
+ * chain and to use with streams.
+ *
+ * The `dart:convert` library works in both web apps and command-line apps.
+ * To use it:
+ *
+ *     import 'dart:convert';
+ *
+ * Two commonly used converters are the top-level instances of
+ * [JsonCodec] and [Utf8Codec], named JSON and UTF8, respectively.
+ *
+ * JSON is a simple text format for representing
+ * structured objects and collections.
+ * The JSON encoder/decoder transforms between strings and
+ * object structures, such as lists and maps, using the JSON format.
+ *
+ * UTF-8 is a common variable-width encoding that can represent
+ * every character in the Unicode character set.
+ * The UTF-8 encoder/decoder transforms between Strings and bytes.
+ *
+ * Converters are often used with streams
+ * to transform the data that comes through the stream
+ * as it becomes available.
+ * The following code uses two converters.
+ * The first is a UTF-8 decoder, which converts the data from bytes to UTF-8
+ * as it's read from a file,
+ * The second is an instance of [LineSplitter],
+ * which splits the data on newline boundaries.
+ *
+ *     int lineNumber = 1;
+ *     Stream<List<int>> stream = new File('quotes.txt').openRead();
+ *
+ *     stream.transform(UTF8.decoder)
+ *           .transform(const LineSplitter())
+ *           .listen((line) {
+ *             if (showLineNumbers) {
+ *               stdout.write('${lineNumber++} ');
+ *             }
+ *             stdout.writeln(line);
+ *           });
+ *
+ * See the documentation for the [Codec] and [Converter] classes
+ * for information about creating your own converters.
  */
 library dart.convert;
 
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index efac7ac..16001e6 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -426,7 +426,7 @@
    */
   bool stringifyJsonValue(final object) {
     if (object is num) {
-      // TODO: use writeOn.
+      if (!object.isFinite) return false;
       sink.write(numberToString(object));
       return true;
     } else if (identical(object, true)) {
@@ -449,7 +449,6 @@
       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]);
diff --git a/sdk/lib/core/comparable.dart b/sdk/lib/core/comparable.dart
index 8896b25..7a22948 100644
--- a/sdk/lib/core/comparable.dart
+++ b/sdk/lib/core/comparable.dart
@@ -22,21 +22,71 @@
 
 /**
  * Interface used by types that have an intrinsic ordering.
+ *
+ * The [compareTo] operation defines a total ordering of objects,
+ * which can be used for ordering and sorting.
+ *
+ * The [Comparable] interface should be used for the natural ordering of a type.
+ * If a type can be ordered in more than one way,
+ * and none of them is the obvious natural ordering,
+ * then it might be better not to use the [Comparable] interface,
+ * and to provide separate [Comparator]s instead.
+ *
+ * It is recommended that the order of a [Comparable] agrees
+ * with its operator [==] equality (`a.compareTo(b) == 0` iff `a == b`),
+ * but this is not a requirement.
+ * For example, [double] and [DateTime] have `compareTo` methods
+ * that do not agree with operator [==].
+ * For doubles the [compareTo] method is more precise than the equality,
+ * and for [DateTime] it is less precise.
+ *
+ * Examples:
+ *
+ *      (0.0).compareTo(-0.0);  // => 1
+ *      0.0 == -0.0;            // => true
+ *      var dt = new DateTime.now();
+ *      var dt2 = dt.toUtc();
+ *      dt == dt2;              // => false
+ *      dt.compareTo(dt2);      // => 0
+ *
+ * The [Comparable] interface does not imply the existence
+ * of the comparison operators `<`, `<=`, `>` and `>=`.
+ * These should only be defined
+ * if the ordering is a less-than/greater-than ordering,
+ * that is, an ordering where you would naturally
+ * use the words "less than" about the order of two elements.
+ *
+ * If the equality operator and [compareTo] disagree,
+ * the comparison operators should follow the equality operator,
+ * and will likely also disagree with [compareTo].
+ * Otherwise they should match the [compareTo] method,
+ * so that `a < b` iff `a.compareTo(b) < 0`.
+ *
+ * The [double] class defines comparison operators
+ * that are compatible with equality.
+ * The operators differ from `double.compareTo` on -0.0 and NaN.
+ *
+ * The [DateTime] class has no comparison operators, instead it has the more
+ * precisely named [DateTime.isBefore] and [DateTime.isAfter].
  */
 abstract class Comparable<T> {
   /**
    * Compares this object to another [Comparable]
    *
-   * Returns a value like a [Comparator] when comparing [:this:] to [other].
+   * Returns a value like a [Comparator] when comparing `this` to [other].
+   * That is, it returns a negative integer if `this` is ordered before [other],
+   * a positive integer if `this` is ordered after [other],
+   * and zero if `this` and [other] are ordered together.
    *
-   * May throw an [ArgumentError] if [other] is of a type that
-   * is not comparable to [:this:].
+   * The [other] argument must be a value that is comparable to this object.
    */
   int compareTo(T other);
 
   /**
    * A [Comparator] that compares one comparable to another.
    *
+   * It returns the result of `a.compareTo(b)`.
+   *
    * This utility function is used as the default comparator
    * for ordering collections, for example in the [List] sort function.
    */
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 65f888e..f789987 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -153,8 +153,8 @@
 library dart.core;
 
 import "dart:collection";
-import "dart:_collection-dev" hide Symbol;
-import "dart:_collection-dev" as _collection_dev;
+import "dart:_internal" hide Symbol;
+import "dart:_internal" as internal show Symbol;
 import "dart:convert" show UTF8, LATIN1, Encoding;
 import "dart:math" show Random;  // Used by List.shuffle.
 
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 2bd120e..b9a4547 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -5,7 +5,7 @@
 part of dart.core;
 
 /**
- * An instant in time, such as July 20, 1969, 8:18pm PST.
+ * An instant in time, such as July 20, 1969, 8:18pm GMT.
  *
  * Create a DateTime object by using one of the constructors
  * or by parsing a correctly formatted string,
diff --git a/sdk/lib/core/double.dart b/sdk/lib/core/double.dart
index 53964e4..089bbd1 100644
--- a/sdk/lib/core/double.dart
+++ b/sdk/lib/core/double.dart
@@ -48,8 +48,8 @@
   /**
    * Truncating division operator.
    *
-   * The result of the truncating division [:a ~/ b:] is equivalent to
-   * [:(a / b).truncate():].
+   * The result of the truncating division `a ~/ b` is equivalent to
+   * `(a / b).truncate()`.
    */
   int operator ~/(num other);
 
@@ -72,7 +72,7 @@
    * Returns the integer closest to `this`.
    *
    * Rounds away from zero when there is no closest integer:
-   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *  `(3.5).round() == 4` and `(-3.5).round() == -4`.
    *
    * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
    */
@@ -101,32 +101,53 @@
   int truncate();
 
   /**
-   * Returns the integer value, as a double, closest to `this`.
+   * Returns the integer double value closest to `this`.
    *
    * Rounds away from zero when there is no closest integer:
-   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *  `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
+   *
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`,
+   * and `-0.0` is therefore considered closer to negative numbers than `0.0`.
+   * This means that for a value, `d` in the range `-0.5 < d < 0.0`,
+   * the result is `-0.0`.
    */
   double roundToDouble();
 
   /**
-   * Returns the greatest integer value no greater than `this`.
+   * Returns the greatest integer double value no greater than `this`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
    */
   double floorToDouble();
 
   /**
-   * Returns the least integer value no smaller than `this`.
+   * Returns the least integer double value no smaller than `this`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
    */
   double ceilToDouble();
 
   /**
-   * Returns the integer obtained by discarding any fractional
+   * Returns the integer double value obtained by discarding any fractional
    * digits from `this`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is not
+   * a finite value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
+   * in the range `0.0 < d < 1.0` it will return 0.0.
    */
   double truncateToDouble();
 
@@ -140,8 +161,8 @@
    * Returns "Infinity" and "-Infinity" for positive and negative Infinity.
    * Returns "-0.0" for negative zero.
    *
-   * It should always be the case that if [:d:] is a [double], then
-   * [:d == double.parse(d.toString()):].
+   * For all doubles, `d`, converting to a string and parsing the string back
+   * gives the same value again: `d == double.parse(d.toString())`.
    */
   String toString();
 
diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart
index 77633a6..d174012 100644
--- a/sdk/lib/core/duration.dart
+++ b/sdk/lib/core/duration.dart
@@ -23,7 +23,7 @@
  * Use one of the properties, such as [inDays],
  * to retrieve the integer value of the Duration in the specified time unit.
  * Note that the returned value is rounded down.
- * For example, 
+ * For example,
  *
  *     Duration aLongWeekend = new Duration(hours:88);
  *     assert(aLongWeekend.inDays == 3);
@@ -223,7 +223,7 @@
       if (n >= 10000) return "0$n";
       if (n >= 1000) return "00$n";
       if (n >= 100) return "000$n";
-      if (n > 10) return "0000$n";
+      if (n >= 10) return "0000$n";
       return "00000$n";
     }
     String twoDigits(int n) {
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index 9514951..3eebddc 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.dart
@@ -21,12 +21,14 @@
    * This includes giving the same errors if [function] isn't callable or
    * if it expects different parameters.
    *
-   * Example: [:
-   * Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
-   * namedArguments[const Symbol("f")] = 4;
-   * namedArguments[const Symbol("g")] = 5;
-   * Function.apply(foo, [1,2,3], namedArguments); :]
-   * gives exactly the same result as [: foo(1, 2, 3, f: 4, g: 5) :].
+   * Example:
+   *       Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
+   *       namedArguments[const Symbol("f")] = 4;
+   *       namedArguments[const Symbol("g")] = 5;
+   *       Function.apply(foo, [1,2,3], namedArguments);
+   *
+   * gives exactly the same result as
+   *       foo(1, 2, 3, f: 4, g: 5).
    *
    * If [positionalArguments] is null, it's considered an empty list.
    * If [namedArguments] is omitted or null, it is considered an empty map.
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 2db8b99..c6714a0 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -26,7 +26,7 @@
  * If you do, then an instance of your Iterable class
  * can be the right-hand side of a for-in construct.
  *
- * Some subclasss of `Iterable` can be modified. It is generally not allowed
+ * Some subclasss of [Iterable] can be modified. It is generally not allowed
  * to modify such collections while they are being iterated. Doing so will break
  * the iteration, which is typically signalled by throwing a
  * [ConcurrentModificationError] when it is detected.
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index cf4da42..578b4c6 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -48,7 +48,7 @@
  * elements) while an operation on the list is being performed,
  * for example during a call to [forEach] or [sort].
  * Changing the list's length while it is being iterated, either by iterating it
- * directly or through iterating an `Iterable` that is backed by the list, will
+ * directly or through iterating an [Iterable] that is backed by the list, will
  * break the iteration.
  */
 abstract class List<E> implements Iterable<E>, EfficientLength {
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index fc89d65..fd8ca9b 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -111,9 +111,9 @@
    * Truncating division operator.
    *
    * If either operand is a [double] then the result of the truncating division
-   * [:a ~/ b:] is equivalent to [:(a / b).truncate().toInt():].
+   * `a ~/ b` is equivalent to `(a / b).truncate().toInt()`.
    *
-   * If both operands are [int]s then [:a ~/ b:] performs the truncating
+   * If both operands are [int]s then `a ~/ b` performs the truncating
    * integer division.
    */
   int operator ~/(num other);
@@ -194,7 +194,7 @@
    * Returns the integer closest to `this`.
    *
    * Rounds away from zero when there is no closest integer:
-   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *  `(3.5).round() == 4` and `(-3.5).round() == -4`.
    *
    * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
    */
@@ -223,40 +223,75 @@
   int truncate();
 
   /**
-   * Returns the integer value closest to `this`.
+   * Returns the double integer value closest to `this`.
    *
    * Rounds away from zero when there is no closest integer:
-   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
+   *  `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`,
+   * and `-0.0` is therefore considered closer to negative numbers than `0.0`.
+   * This means that for a value, `d` in the range `-0.5 < d < 0.0`,
+   * the result is `-0.0`.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
    */
   double roundToDouble();
 
   /**
-   * Returns the greatest integer value no greater than `this`.
+   * Returns the greatest double integer value no greater than `this`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
    */
   double floorToDouble();
 
   /**
-   * Returns the least integer value no smaller than `this`.
+   * Returns the least double integer value no smaller than `this`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
    */
   double ceilToDouble();
 
   /**
-   * Returns the integer obtained by discarding any fractional
-   * digits from `this`.
+   * Returns the double integer value obtained by discarding any fractional
+   * digits from the double value of `this`.
    *
-   * The result is a double.
+   * If this is already an integer valued double, including `-0.0`, or it is a
+   * non-finite double value, the value is returned unmodified.
+   *
+   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
+   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
+   * in the range `0.0 < d < 1.0` it will return 0.0.
+   *
+   * The result is always a double.
+   * If this is a numerically large integer, the result may be an infinite
+   * double.
    */
   double truncateToDouble();
 
   /**
    * Clamps [this] to be in the range [lowerLimit]-[upperLimit]. The comparison
-   * is done using [compareTo] and therefore takes [:-0.0:] into account.
+   * is done using [compareTo] and therefore takes `-0.0` into account.
    * It also implies that [double.NAN] is treated as the maximal double value.
    */
   num clamp(num lowerLimit, num upperLimit);
@@ -286,7 +321,7 @@
    * point is omitted.
    *
    * The parameter [fractionDigits] must be an integer satisfying:
-   * [:0 <= fractionDigits <= 20:].
+   * `0 <= fractionDigits <= 20`.
    *
    * Examples:
    *
@@ -305,7 +340,7 @@
    * Converts `this` to a [double] before computing the string representation.
    *
    * If [fractionDigits] is given then it must be an integer satisfying:
-   * [:0 <= fractionDigits <= 20:]. In this case the string contains exactly
+   * `0 <= fractionDigits <= 20`. In this case the string contains exactly
    * [fractionDigits] after the decimal point. Otherwise, without the parameter,
    * the returned string uses the shortest number of digits that accurately
    * represent [this].
@@ -326,7 +361,7 @@
    * exactly [precision] significant digits.
    *
    * The parameter [precision] must be an integer satisfying:
-   * [:1 <= precision <= 21:].
+   * `1 <= precision <= 21`.
    *
    * Examples:
    *
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 41ff788..2951a73 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -94,4 +94,3 @@
    */
   external Type get runtimeType;
 }
-
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 059f320..4226dc2 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -13,8 +13,9 @@
  * Set implementations may consider some elements indistinguishable. These
  * elements are treated as being the same for any operation on the set.
  *
- * The default `Set` implementation, [LinkedHashSet], considers objects
- * indistinguishable if they are equal with regard to [Object.operator==].
+ * The default [Set] implementation, [LinkedHashSet], considers objects
+ * indistinguishable if they are equal with regard to 
+ * operator [Object.==].
  *
  * Sets may be either ordered or unordered. [HashSet] is unordered and
  * doesn't guarantee anything about the order that elements are accessed in by
@@ -23,15 +24,15 @@
  * It is generally not allowed to modify the set (add or remove elements) while
  * an operation on the set is being performed, for example during a call to
  * [forEach] or [containsAll]. Nor is it allowed to modify the set while
- * iterating either the set itself or any `Iterable` that is backed by the set,
+ * iterating either the set itself or any [Iterable] that is backed by the set,
  * such as the ones returned by methods like [where] and [map].
  */
 abstract class Set<E> extends IterableBase<E> implements EfficientLength {
   /**
    * Creates an empty [Set].
    *
-   * The created `Set` is a [LinkedHashSet]. As such, it considers elements that
-   * are equal (using `==`) to be indistinguishable, and requires them to
+   * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
+   * are equal (using [==]) to be indistinguishable, and requires them to
    * have a compatible [Object.hashCode] implementation.
    */
   factory Set() = LinkedHashSet<E>;
@@ -39,7 +40,7 @@
   /**
    * Creates an empty identity [Set].
    *
-   * The created `Set` is a [LinkedHashSet] that uses identity as equality
+   * The created [Set] is a [LinkedHashSet] that uses identity as equality
    * relation.
    */
   factory Set.identity() = LinkedHashSet<E>.identity;
@@ -47,8 +48,8 @@
   /**
    * Creates a [Set] that contains all elements of [other].
    *
-   * The created `Set` is a [LinkedHashSet]. As such, it considers elements that
-   * are equal (using `==`) to be undistinguishable, and requires them to
+   * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
+   * are equal (using [==]) to be undistinguishable, and requires them to
    * have a compatible [Object.hashCode] implementation.
    */
   factory Set.from(Iterable<E> other) = LinkedHashSet<E>.from;
@@ -121,15 +122,15 @@
   /**
    * Returns a new set which is the intersection between this set and [other].
    *
-   * That is, the returned set contains all the elements of this `Set` that
-   * are also elements of `other` according to `other.contains`.
+   * That is, the returned set contains all the elements of this [Set] that
+   * are also elements of [other] according to `other.contains`.
    */
   Set<E> intersection(Set<Object> other);
 
   /**
    * Returns a new set which contains all the elements of this set and [other].
    *
-   * That is, the returned set contains all the elements of this `Set` and
+   * That is, the returned set contains all the elements of this [Set] and
    * all the elements of [other].
    */
   Set<E> union(Set<E> other);
@@ -137,7 +138,7 @@
   /**
    * Returns a new set with the the elements of this that are not in [other].
    *
-   * That is, the returned set contains all the elements of this `Set` that
+   * That is, the returned set contains all the elements of this [Set] that
    * are not elements of [other] according to `other.contains`.
    */
   Set<E> difference(Set<E> other);
diff --git a/sdk/lib/core/string_sink.dart b/sdk/lib/core/string_sink.dart
index 16c9f4f..5fdd0f2 100644
--- a/sdk/lib/core/string_sink.dart
+++ b/sdk/lib/core/string_sink.dart
@@ -7,8 +7,8 @@
 abstract class StringSink {
 
   /**
-   * Converts [obj] to a String by invoking `toString` and adds the result to
-   * `this`.
+   * Converts [obj] to a String by invoking [Object.toString] and 
+   * adds the result to `this`.
    */
   void write(Object obj);
 
@@ -18,8 +18,8 @@
   void writeAll(Iterable objects, [String separator = ""]);
 
   /**
-   * Converts [obj] to a String by invoking `toString` and adds the result to
-   * `this`. Then adds a new line.
+   * Converts [obj] to a String by invoking [Object.toString] and 
+   * adds the result to `this`, followed by a newline.
    */
   void writeln([Object obj = ""]);
 
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index c45fcf5..c92001a 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -20,5 +20,5 @@
    * possible, use [MirrorsUsed] in "dart:mirrors" to specify which names might
    * be passed to this constructor.
    */
-  const factory Symbol(String name) = _collection_dev.Symbol;
+  const factory Symbol(String name) = internal.Symbol;
 }
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 5bbd141..d228722 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -26,7 +26,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide Symbol, deprecated;
+import 'dart:_internal' hide Symbol, deprecated;
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -34,6 +34,7 @@
 import 'dart:math';
 import 'dart:typed_data';
 import 'dart:svg' as svg;
+import 'dart:svg' show Matrix;
 import 'dart:web_audio' as web_audio;
 import 'dart:web_gl' as gl;
 import 'dart:web_sql';
@@ -186,7 +187,7 @@
 
 @DocsEditable()
 @DomName('HTMLAnchorElement')
-class AnchorElement extends HtmlElement native "HTMLAnchorElement" {
+class AnchorElement extends HtmlElement implements UrlUtils native "HTMLAnchorElement" {
   // To suppress missing implicit constructor warnings.
   factory AnchorElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -208,6 +209,24 @@
   @DocsEditable()
   String download;
 
+  @DomName('HTMLAnchorElement.hreflang')
+  @DocsEditable()
+  String hreflang;
+
+  @DomName('HTMLAnchorElement.rel')
+  @DocsEditable()
+  String rel;
+
+  @DomName('HTMLAnchorElement.target')
+  @DocsEditable()
+  String target;
+
+  @DomName('HTMLAnchorElement.type')
+  @DocsEditable()
+  String type;
+
+  // From URLUtils
+
   @DomName('HTMLAnchorElement.hash')
   @DocsEditable()
   String hash;
@@ -224,9 +243,10 @@
   @DocsEditable()
   String href;
 
-  @DomName('HTMLAnchorElement.hreflang')
+  @DomName('HTMLAnchorElement.password')
   @DocsEditable()
-  String hreflang;
+  @Experimental() // untriaged
+  String password;
 
   @DomName('HTMLAnchorElement.pathname')
   @DocsEditable()
@@ -240,21 +260,14 @@
   @DocsEditable()
   String protocol;
 
-  @DomName('HTMLAnchorElement.rel')
-  @DocsEditable()
-  String rel;
-
   @DomName('HTMLAnchorElement.search')
   @DocsEditable()
   String search;
 
-  @DomName('HTMLAnchorElement.target')
+  @DomName('HTMLAnchorElement.username')
   @DocsEditable()
-  String target;
-
-  @DomName('HTMLAnchorElement.type')
-  @DocsEditable()
-  String type;
+  @Experimental() // untriaged
+  String username;
 
   @DomName('HTMLAnchorElement.toString')
   @DocsEditable()
@@ -479,7 +492,7 @@
  * on MDN.
  */
 @DomName('HTMLAreaElement')
-class AreaElement extends HtmlElement native "HTMLAreaElement" {
+class AreaElement extends HtmlElement implements UrlUtils native "HTMLAreaElement" {
   // To suppress missing implicit constructor warnings.
   factory AreaElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -501,38 +514,6 @@
   @DocsEditable()
   String coords;
 
-  @DomName('HTMLAreaElement.hash')
-  @DocsEditable()
-  final String hash;
-
-  @DomName('HTMLAreaElement.host')
-  @DocsEditable()
-  final String host;
-
-  @DomName('HTMLAreaElement.hostname')
-  @DocsEditable()
-  final String hostname;
-
-  @DomName('HTMLAreaElement.href')
-  @DocsEditable()
-  String href;
-
-  @DomName('HTMLAreaElement.pathname')
-  @DocsEditable()
-  final String pathname;
-
-  @DomName('HTMLAreaElement.port')
-  @DocsEditable()
-  final String port;
-
-  @DomName('HTMLAreaElement.protocol')
-  @DocsEditable()
-  final String protocol;
-
-  @DomName('HTMLAreaElement.search')
-  @DocsEditable()
-  final String search;
-
   @DomName('HTMLAreaElement.shape')
   @DocsEditable()
   String shape;
@@ -540,6 +521,60 @@
   @DomName('HTMLAreaElement.target')
   @DocsEditable()
   String target;
+
+  // From URLUtils
+
+  @DomName('HTMLAreaElement.hash')
+  @DocsEditable()
+  String hash;
+
+  @DomName('HTMLAreaElement.host')
+  @DocsEditable()
+  String host;
+
+  @DomName('HTMLAreaElement.hostname')
+  @DocsEditable()
+  String hostname;
+
+  @DomName('HTMLAreaElement.href')
+  @DocsEditable()
+  String href;
+
+  @DomName('HTMLAreaElement.origin')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final String origin;
+
+  @DomName('HTMLAreaElement.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String password;
+
+  @DomName('HTMLAreaElement.pathname')
+  @DocsEditable()
+  String pathname;
+
+  @DomName('HTMLAreaElement.port')
+  @DocsEditable()
+  String port;
+
+  @DomName('HTMLAreaElement.protocol')
+  @DocsEditable()
+  String protocol;
+
+  @DomName('HTMLAreaElement.search')
+  @DocsEditable()
+  String search;
+
+  @DomName('HTMLAreaElement.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String username;
+
+  @DomName('HTMLAreaElement.toString')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String toString() native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -736,7 +771,7 @@
 
 @DocsEditable()
 @DomName('HTMLBodyElement')
-class BodyElement extends HtmlElement native "HTMLBodyElement" {
+class BodyElement extends HtmlElement implements WindowEventHandlers native "HTMLBodyElement" {
   // To suppress missing implicit constructor warnings.
   factory BodyElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -840,6 +875,11 @@
   @DocsEditable()
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
+  @DomName('HTMLBodyElement.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
   /**
    * Static factory designed to expose `storage` events to event
    * handlers that are not necessarily instances of [BodyElement].
@@ -920,6 +960,11 @@
   @DocsEditable()
   ElementStream<Event> get onResize => resizeEvent.forElement(this);
 
+  @DomName('HTMLBodyElement.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
   /// Stream of `storage` events handled by this [BodyElement].
   @DomName('HTMLBodyElement.onstorage')
   @DocsEditable()
@@ -1039,6 +1084,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// WARNING: Do not edit - generated code.
+
+
+@DomName('CSSVariablesMapForEachCallback')
+@Experimental() // untriaged
+typedef void CssVariablesMapForEachCallback(String value, String name, CssVariablesMap map);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('Canvas2DContextAttributes')
@@ -1357,6 +1412,11 @@
   @Experimental()
   Path currentPath;
 
+  @DomName('CanvasRenderingContext2D.currentTransform')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Matrix currentTransform;
+
   @DomName('CanvasRenderingContext2D.fillStyle')
   @DocsEditable()
   @Creates('String|CanvasGradient|CanvasPattern')
@@ -2059,9 +2119,9 @@
   // To suppress missing implicit constructor warnings.
   factory ChildNode._() { throw new UnsupportedError("Not supported"); }
 
-  Element nextElementSibling;
+  final Element nextElementSibling;
 
-  Element previousElementSibling;
+  final Element previousElementSibling;
 
   void remove();
 }
@@ -6150,7 +6210,7 @@
 
   @DomName('CSSStyleSheet.insertRule')
   @DocsEditable()
-  int insertRule(String rule, int index) native;
+  int insertRule(String rule, [int index]) native;
 
   @DomName('CSSStyleSheet.removeRule')
   @DocsEditable()
@@ -6213,6 +6273,11 @@
   @Experimental() // untriaged
   bool delete(String name) native;
 
+  @DomName('CSSVariablesMap.forEach')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void forEach(CssVariablesMapForEachCallback callback, [Object thisArg]) native;
+
   @DomName('CSSVariablesMap.get')
   @DocsEditable()
   @Experimental() // untriaged
@@ -6391,7 +6456,7 @@
 
   @DomName('Clipboard.types')
   @DocsEditable()
-  final List types;
+  final List<String> types;
 
   @DomName('Clipboard.clearData')
   @DocsEditable()
@@ -9256,7 +9321,7 @@
  * An abstract class, which all HTML elements extend.
  */
 @DomName('Element')
-abstract class Element extends Node implements ParentNode, ChildNode native "Element" {
+abstract class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode native "Element" {
 
   /**
    * Creates an HTML element from a valid fragment of HTML.
@@ -10836,11 +10901,6 @@
   @DocsEditable()
   bool hidden;
 
-  @JSName('innerHTML')
-  @DomName('Element.innerHTML')
-  @DocsEditable()
-  String _innerHtml;
-
   /**
    * The current state of IME composition.
    *
@@ -10862,11 +10922,6 @@
   @DocsEditable()
   String lang;
 
-  @JSName('outerHTML')
-  @DomName('Element.outerHTML')
-  @DocsEditable()
-  final String outerHtml;
-
   @DomName('Element.spellcheck')
   @DocsEditable()
   // http://blog.whatwg.org/the-road-to-html-5-spellchecking
@@ -10953,6 +11008,11 @@
   @DocsEditable()
   String id;
 
+  @JSName('innerHTML')
+  @DomName('Element.innerHTML')
+  @DocsEditable()
+  String _innerHtml;
+
   // Use implementation from Node.
   // final String _localName;
 
@@ -10979,6 +11039,11 @@
   @DocsEditable()
   final int offsetWidth;
 
+  @JSName('outerHTML')
+  @DomName('Element.outerHTML')
+  @DocsEditable()
+  final String outerHtml;
+
   /**
    * The name of this element's custom pseudo-element.
    *
@@ -13479,6 +13544,348 @@
 
 
 @DocsEditable()
+@DomName('GlobalEventHandlers')
+@Experimental() // untriaged
+abstract class GlobalEventHandlers extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('GlobalEventHandlers.abortEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
+
+  @DomName('GlobalEventHandlers.blurEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
+
+  @DomName('GlobalEventHandlers.changeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
+
+  @DomName('GlobalEventHandlers.clickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
+
+  @DomName('GlobalEventHandlers.contextmenuEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('GlobalEventHandlers.dblclickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
+
+  @DomName('GlobalEventHandlers.dragEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
+
+  @DomName('GlobalEventHandlers.dragendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
+
+  @DomName('GlobalEventHandlers.dragenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
+
+  @DomName('GlobalEventHandlers.dragleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
+
+  @DomName('GlobalEventHandlers.dragoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
+
+  @DomName('GlobalEventHandlers.dragstartEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
+
+  @DomName('GlobalEventHandlers.dropEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
+
+  @DomName('GlobalEventHandlers.errorEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('GlobalEventHandlers.focusEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
+
+  @DomName('GlobalEventHandlers.inputEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
+
+  @DomName('GlobalEventHandlers.invalidEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
+
+  @DomName('GlobalEventHandlers.keydownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
+
+  @DomName('GlobalEventHandlers.keypressEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
+
+  @DomName('GlobalEventHandlers.keyupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
+
+  @DomName('GlobalEventHandlers.loadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('GlobalEventHandlers.mousedownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
+
+  @DomName('GlobalEventHandlers.mouseenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');
+
+  @DomName('GlobalEventHandlers.mouseleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');
+
+  @DomName('GlobalEventHandlers.mousemoveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
+
+  @DomName('GlobalEventHandlers.mouseoutEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
+
+  @DomName('GlobalEventHandlers.mouseoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
+
+  @DomName('GlobalEventHandlers.mouseupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
+
+  @DomName('GlobalEventHandlers.mousewheelEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
+
+  @DomName('GlobalEventHandlers.resetEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
+
+  @DomName('GlobalEventHandlers.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
+  @DomName('GlobalEventHandlers.selectEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
+
+  @DomName('GlobalEventHandlers.submitEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
+
+  @DomName('GlobalEventHandlers.onabort')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onAbort => abortEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onblur')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onBlur => blurEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.oncontextmenu')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondblclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondrag')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragstart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondrop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onerror')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onfocus')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onFocus => focusEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.oninput')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onInput => inputEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.oninvalid')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onInvalid => invalidEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onkeydown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onkeypress')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onkeyup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onLoad => loadEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmousedown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmousemove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseout')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmousewheel')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onreset')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onReset => resetEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onScroll => scrollEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onselect')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onSelect => selectEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onsubmit')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onSubmit => submitEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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()
 /**
  * An `<hr>` tag.
  */
@@ -15997,7 +16404,7 @@
 @DomName('InputMethodContext')
 // http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext
 @Experimental()
-class InputMethodContext extends Interceptor native "InputMethodContext" {
+class InputMethodContext extends EventTarget native "InputMethodContext" {
   // To suppress missing implicit constructor warnings.
   factory InputMethodContext._() { throw new UnsupportedError("Not supported"); }
 
@@ -16021,10 +16428,6 @@
   @DomName('InputMethodContext.setCaretRectangle')
   @DocsEditable()
   void setCaretRectangle(Node anchor, int x, int y, int w, int h) native;
-
-  @DomName('InputMethodContext.setExclusionRectangle')
-  @DocsEditable()
-  void setExclusionRectangle(Node anchor, int x, int y, int w, int h) 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
@@ -16170,6 +16573,11 @@
   @DocsEditable()
   final bool metaKey;
 
+  @DomName('KeyboardEvent.repeat')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final bool repeat;
+
   @DomName('KeyboardEvent.shiftKey')
   @DocsEditable()
   final bool shiftKey;
@@ -16399,7 +16807,7 @@
 
   @DomName('HTMLLinkElement.sizes')
   @DocsEditable()
-  DomSettableTokenList sizes;
+  final DomSettableTokenList sizes;
 
   @DomName('HTMLLinkElement.type')
   @DocsEditable()
@@ -16972,12 +17380,6 @@
   @DocsEditable()
   final MediaError error;
 
-  @DomName('HTMLMediaElement.initialTime')
-  @DocsEditable()
-  // http://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-media-initialtime
-  @Experimental()
-  final double initialTime;
-
   @DomName('HTMLMediaElement.loop')
   @DocsEditable()
   bool loop;
@@ -17032,11 +17434,6 @@
   @DocsEditable()
   String src;
 
-  @DomName('HTMLMediaElement.startTime')
-  @DocsEditable()
-  @Experimental() // non-standard
-  final double startTime;
-
   @DomName('HTMLMediaElement.textTracks')
   @DocsEditable()
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-texttracks
@@ -17056,33 +17453,6 @@
   @Experimental() // nonstandard
   final int audioDecodedByteCount;
 
-  @JSName('webkitClosedCaptionsVisible')
-  @DomName('HTMLMediaElement.webkitClosedCaptionsVisible')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  bool closedCaptionsVisible;
-
-  @JSName('webkitHasClosedCaptions')
-  @DomName('HTMLMediaElement.webkitHasClosedCaptions')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  final bool hasClosedCaptions;
-
-  @JSName('webkitPreservesPitch')
-  @DomName('HTMLMediaElement.webkitPreservesPitch')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  bool preservesPitch;
-
   @JSName('webkitVideoDecodedByteCount')
   @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
   @DocsEditable()
@@ -17918,6 +18288,11 @@
     return completer.future;
   }
 
+  @DomName('MediaStreamTrack.stop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void stop() native;
+
   /// Stream of `ended` events handled by this [MediaStreamTrack].
   @DomName('MediaStreamTrack.onended')
   @DocsEditable()
@@ -19109,6 +19484,11 @@
   @Unstable()
   final Geolocation geolocation;
 
+  @DomName('Navigator.maxTouchPoints')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int maxTouchPoints;
+
   @DomName('Navigator.mimeTypes')
   @DocsEditable()
   @Experimental() // nonstandard
@@ -19238,17 +19618,17 @@
   // To suppress missing implicit constructor warnings.
   factory NavigatorID._() { throw new UnsupportedError("Not supported"); }
 
-  String appCodeName;
+  final String appCodeName;
 
-  String appName;
+  final String appName;
 
-  String appVersion;
+  final String appVersion;
 
-  String platform;
+  final String platform;
 
-  String product;
+  final String product;
 
-  String userAgent;
+  final String userAgent;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -19262,7 +19642,7 @@
   // To suppress missing implicit constructor warnings.
   factory NavigatorOnLine._() { throw new UnsupportedError("Not supported"); }
 
-  bool onLine;
+  final bool onLine;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -20635,13 +21015,13 @@
   // To suppress missing implicit constructor warnings.
   factory ParentNode._() { throw new UnsupportedError("Not supported"); }
 
-  int _childElementCount;
+  final int _childElementCount;
 
-  HtmlCollection _children;
+  final HtmlCollection _children;
 
-  Element _firstElementChild;
+  final Element _firstElementChild;
 
-  Element _lastElementChild;
+  final Element _lastElementChild;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -21389,15 +21769,20 @@
   // To suppress missing implicit constructor warnings.
   factory Promise._() { throw new UnsupportedError("Not supported"); }
 
-  @DomName('Promise._any')
+  @DomName('Promise.all')
   @DocsEditable()
   @Experimental() // untriaged
-  static Promise _any(Object values) native;
+  static Promise all(Object iterable) native;
 
-  @DomName('Promise.every')
+  @DomName('Promise.cast')
   @DocsEditable()
   @Experimental() // untriaged
-  static Promise every(Object values) native;
+  static Promise cast(Object value) native;
+
+  @DomName('Promise.race')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static Promise race(Object iterable) native;
 
   @DomName('Promise.reject')
   @DocsEditable()
@@ -23008,6 +23393,13 @@
   @DomName('HTMLShadowElement.resetStyleInheritance')
   @DocsEditable()
   bool resetStyleInheritance;
+
+  @DomName('HTMLShadowElement.getDistributedNodes')
+  @DocsEditable()
+  @Experimental() // untriaged
+  @Returns('NodeList')
+  @Creates('NodeList')
+  List<Node> getDistributedNodes() 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
@@ -23032,6 +23424,11 @@
   @DocsEditable()
   bool applyAuthorStyles;
 
+  @DomName('ShadowRoot.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final Element host;
+
   @JSName('innerHTML')
   @DomName('ShadowRoot.innerHTML')
   @DocsEditable()
@@ -23046,6 +23443,13 @@
   @DocsEditable()
   bool resetStyleInheritance;
 
+  @DomName('ShadowRoot.styleSheets')
+  @DocsEditable()
+  @Experimental() // untriaged
+  @Returns('_StyleSheetList')
+  @Creates('_StyleSheetList')
+  final List<StyleSheet> styleSheets;
+
   @JSName('cloneNode')
   @DomName('ShadowRoot.cloneNode')
   @DocsEditable()
@@ -23801,7 +24205,7 @@
 @DomName('SpeechSynthesis')
 // https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
 @Experimental()
-class SpeechSynthesis extends Interceptor native "SpeechSynthesis" {
+class SpeechSynthesis extends EventTarget native "SpeechSynthesis" {
   // To suppress missing implicit constructor warnings.
   factory SpeechSynthesis._() { throw new UnsupportedError("Not supported"); }
 
@@ -25123,14 +25527,29 @@
   @DocsEditable()
   String mode;
 
+  @DomName('TextTrack.regions')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final VttRegionList regions;
+
   @DomName('TextTrack.addCue')
   @DocsEditable()
   void addCue(TextTrackCue cue) native;
 
+  @DomName('TextTrack.addRegion')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void addRegion(VttRegion region) native;
+
   @DomName('TextTrack.removeCue')
   @DocsEditable()
   void removeCue(TextTrackCue cue) native;
 
+  @DomName('TextTrack.removeRegion')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void removeRegion(VttRegion region) native;
+
   /// Stream of `cuechange` events handled by this [TextTrack].
   @DomName('TextTrack.oncuechange')
   @DocsEditable()
@@ -25203,6 +25622,11 @@
   @Experimental() // nonstandard
   int position;
 
+  @DomName('TextTrackCue.regionId')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String regionId;
+
   @DomName('TextTrackCue.size')
   @DocsEditable()
   @Experimental() // nonstandard
@@ -25619,12 +26043,7 @@
    * Note that touch events are only supported if the user is using a touch
    * device.
    */
-  static bool get supported {
-    if (JS('bool', '"ontouchstart" in window')) {
-      return Device.isEventTypeSupported('TouchEvent');
-    }
-    return false;
-  }
+  static bool get supported => Device.isEventTypeSupported('TouchEvent');
 }
 // 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
@@ -26019,7 +26438,7 @@
 
 
 @DomName('URL')
-class Url extends Interceptor native "URL" {
+class Url extends Interceptor implements UrlUtils native "URL" {
 
   static String createObjectUrl(blob_OR_source_OR_stream) =>
       JS('String',
@@ -26046,6 +26465,129 @@
   @DocsEditable()
   static String _createObjectUrlFromWebKitSource(_WebKitMediaSource source) native;
 
+  // From URLUtils
+
+  @DomName('URL.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String hash;
+
+  @DomName('URL.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String host;
+
+  @DomName('URL.hostname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String hostname;
+
+  @DomName('URL.href')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String href;
+
+  @DomName('URL.origin')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final String origin;
+
+  @DomName('URL.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String password;
+
+  @DomName('URL.pathname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String pathname;
+
+  @DomName('URL.port')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String port;
+
+  @DomName('URL.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String protocol;
+
+  @DomName('URL.search')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String search;
+
+  @DomName('URL.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String username;
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('URLUtils')
+@Experimental() // untriaged
+abstract class UrlUtils extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UrlUtils._() { throw new UnsupportedError("Not supported"); }
+
+  String hash;
+
+  String host;
+
+  String hostname;
+
+  String href;
+
+  final String origin;
+
+  String password;
+
+  String pathname;
+
+  String port;
+
+  String protocol;
+
+  String search;
+
+  String username;
+
+  String toString();
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('URLUtilsReadOnly')
+@Experimental() // untriaged
+abstract class UrlUtilsReadOnly extends Interceptor {
+  // To suppress missing implicit constructor warnings.
+  factory UrlUtilsReadOnly._() { throw new UnsupportedError("Not supported"); }
+
+  final String hash;
+
+  final String host;
+
+  final String hostname;
+
+  final String href;
+
+  final String pathname;
+
+  final String port;
+
+  final String protocol;
+
+  final String search;
+
+  String toString();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -26154,6 +26696,11 @@
   @DocsEditable()
   int width;
 
+  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VideoPlaybackQuality getVideoPlaybackQuality() native;
+
   @JSName('webkitEnterFullscreen')
   @DomName('HTMLVideoElement.webkitEnterFullscreen')
   @DocsEditable()
@@ -26177,6 +26724,38 @@
 // for 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('VideoPlaybackQuality')
+@Experimental() // untriaged
+class VideoPlaybackQuality extends Interceptor native "VideoPlaybackQuality" {
+  // To suppress missing implicit constructor warnings.
+  factory VideoPlaybackQuality._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int corruptedVideoFrames;
+
+  @DomName('VideoPlaybackQuality.creationTime')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final double creationTime;
+
+  @DomName('VideoPlaybackQuality.droppedVideoFrames')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int droppedVideoFrames;
+
+  @DomName('VideoPlaybackQuality.totalVideoFrames')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int totalVideoFrames;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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.
 
 
@@ -26190,6 +26769,97 @@
 
 
 @DocsEditable()
+@DomName('VTTRegion')
+@Experimental() // untriaged
+class VttRegion extends Interceptor native "VTTRegion" {
+  // To suppress missing implicit constructor warnings.
+  factory VttRegion._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('VTTRegion.VTTRegion')
+  @DocsEditable()
+  factory VttRegion() {
+    return VttRegion._create_1();
+  }
+  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');
+
+  @DomName('VTTRegion.height')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int height;
+
+  @DomName('VTTRegion.id')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String id;
+
+  @DomName('VTTRegion.regionAnchorX')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num regionAnchorX;
+
+  @DomName('VTTRegion.regionAnchorY')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num regionAnchorY;
+
+  @DomName('VTTRegion.scroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String scroll;
+
+  @DomName('VTTRegion.track')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final TextTrack track;
+
+  @DomName('VTTRegion.viewportAnchorX')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num viewportAnchorX;
+
+  @DomName('VTTRegion.viewportAnchorY')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num viewportAnchorY;
+
+  @DomName('VTTRegion.width')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num width;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable()
+@DomName('VTTRegionList')
+@Experimental() // untriaged
+class VttRegionList extends Interceptor native "VTTRegionList" {
+  // To suppress missing implicit constructor warnings.
+  factory VttRegionList._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('VTTRegionList.length')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int length;
+
+  @DomName('VTTRegionList.getRegionById')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VttRegion getRegionById(String id) native;
+
+  @DomName('VTTRegionList.item')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VttRegion 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()
 /**
  * Use the WebSocket interface to connect to a WebSocket,
  * and to send and receive data on that WebSocket.
@@ -26715,7 +27385,7 @@
  * * [Window](http://www.w3.org/TR/Window/) from the W3C.
  */
 @DomName('Window')
-class Window extends EventTarget implements WindowBase, _WindowTimers, WindowBase64 native "Window,DOMWindow" {
+class Window extends EventTarget implements WindowEventHandlers, WindowBase, GlobalEventHandlers, _WindowTimers, WindowBase64 native "Window,DOMWindow" {
 
   /**
    * Returns a Future that completes just before the window is about to
@@ -26733,7 +27403,7 @@
    * [animationFrame] again for the animation to continue.
    */
   Future<num> get animationFrame {
-    var completer = new Completer<num>();
+    var completer = new Completer<num>.sync();
     requestAnimationFrame((time) {
       completer.complete(time);
     });
@@ -27386,6 +28056,10 @@
   @Returns('Window|=Object')
   final dynamic _get_opener;
 
+  void set opener(Window value) {
+    JS("void", "#.opener = #", this, value);
+  }
+
   /**
    * The height of this window including all user interface elements.
    *
@@ -28485,6 +29159,108 @@
 
 
 @DocsEditable()
+@DomName('WindowEventHandlers')
+@Experimental() // untriaged
+abstract class WindowEventHandlers extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory WindowEventHandlers._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('WindowEventHandlers.beforeunloadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> beforeUnloadEvent = const EventStreamProvider<Event>('beforeunload');
+
+  @DomName('WindowEventHandlers.hashchangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');
+
+  @DomName('WindowEventHandlers.messageEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
+
+  @DomName('WindowEventHandlers.offlineEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');
+
+  @DomName('WindowEventHandlers.onlineEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');
+
+  @DomName('WindowEventHandlers.popstateEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');
+
+  @DomName('WindowEventHandlers.resizeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
+
+  @DomName('WindowEventHandlers.storageEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');
+
+  @DomName('WindowEventHandlers.unloadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
+
+  @DomName('WindowEventHandlers.onbeforeunload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onhashchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onmessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onoffline')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onOffline => offlineEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.ononline')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onOnline => onlineEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onpopstate')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onresize')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onResize => resizeEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onstorage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onunload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onUnload => unloadEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('Worker')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -29803,7 +30579,7 @@
 @DomName('HTMLFrameSetElement')
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
 @deprecated // deprecated
-abstract class _HTMLFrameSetElement extends HtmlElement native "HTMLFrameSetElement" {
+abstract class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers native "HTMLFrameSetElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
   /**
@@ -30406,9 +31182,11 @@
 @DomName('WorkerLocation')
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
 @Experimental()
-abstract class _WorkerLocation extends Interceptor native "WorkerLocation" {
+abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly native "WorkerLocation" {
   // To suppress missing implicit constructor warnings.
   factory _WorkerLocation._() { throw new UnsupportedError("Not supported"); }
+
+  // From URLUtilsReadOnly
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index be4fb4f..a8f6e56 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -26,7 +26,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide Symbol, deprecated;
+import 'dart:_internal' hide Symbol, deprecated;
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -38,6 +38,7 @@
 import 'dart:web_gl' as gl;
 import 'dart:web_sql';
 import 'dart:svg' as svg;
+import 'dart:svg' show Matrix;
 import 'dart:web_audio' as web_audio;
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -188,7 +189,7 @@
 
 @DocsEditable()
 @DomName('HTMLAnchorElement')
-class AnchorElement extends HtmlElement {
+class AnchorElement extends HtmlElement implements UrlUtils {
   // To suppress missing implicit constructor warnings.
   factory AnchorElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -214,6 +215,38 @@
   @DocsEditable()
   void set download(String value) native "HTMLAnchorElement_download_Setter";
 
+  @DomName('HTMLAnchorElement.hreflang')
+  @DocsEditable()
+  String get hreflang native "HTMLAnchorElement_hreflang_Getter";
+
+  @DomName('HTMLAnchorElement.hreflang')
+  @DocsEditable()
+  void set hreflang(String value) native "HTMLAnchorElement_hreflang_Setter";
+
+  @DomName('HTMLAnchorElement.rel')
+  @DocsEditable()
+  String get rel native "HTMLAnchorElement_rel_Getter";
+
+  @DomName('HTMLAnchorElement.rel')
+  @DocsEditable()
+  void set rel(String value) native "HTMLAnchorElement_rel_Setter";
+
+  @DomName('HTMLAnchorElement.target')
+  @DocsEditable()
+  String get target native "HTMLAnchorElement_target_Getter";
+
+  @DomName('HTMLAnchorElement.target')
+  @DocsEditable()
+  void set target(String value) native "HTMLAnchorElement_target_Setter";
+
+  @DomName('HTMLAnchorElement.type')
+  @DocsEditable()
+  String get type native "HTMLAnchorElement_type_Getter";
+
+  @DomName('HTMLAnchorElement.type')
+  @DocsEditable()
+  void set type(String value) native "HTMLAnchorElement_type_Setter";
+
   @DomName('HTMLAnchorElement.hash')
   @DocsEditable()
   String get hash native "HTMLAnchorElement_hash_Getter";
@@ -246,13 +279,15 @@
   @DocsEditable()
   void set href(String value) native "HTMLAnchorElement_href_Setter";
 
-  @DomName('HTMLAnchorElement.hreflang')
+  @DomName('HTMLAnchorElement.password')
   @DocsEditable()
-  String get hreflang native "HTMLAnchorElement_hreflang_Getter";
+  @Experimental() // untriaged
+  String get password native "HTMLAnchorElement_password_Getter";
 
-  @DomName('HTMLAnchorElement.hreflang')
+  @DomName('HTMLAnchorElement.password')
   @DocsEditable()
-  void set hreflang(String value) native "HTMLAnchorElement_hreflang_Setter";
+  @Experimental() // untriaged
+  void set password(String value) native "HTMLAnchorElement_password_Setter";
 
   @DomName('HTMLAnchorElement.pathname')
   @DocsEditable()
@@ -278,14 +313,6 @@
   @DocsEditable()
   void set protocol(String value) native "HTMLAnchorElement_protocol_Setter";
 
-  @DomName('HTMLAnchorElement.rel')
-  @DocsEditable()
-  String get rel native "HTMLAnchorElement_rel_Getter";
-
-  @DomName('HTMLAnchorElement.rel')
-  @DocsEditable()
-  void set rel(String value) native "HTMLAnchorElement_rel_Setter";
-
   @DomName('HTMLAnchorElement.search')
   @DocsEditable()
   String get search native "HTMLAnchorElement_search_Getter";
@@ -294,21 +321,15 @@
   @DocsEditable()
   void set search(String value) native "HTMLAnchorElement_search_Setter";
 
-  @DomName('HTMLAnchorElement.target')
+  @DomName('HTMLAnchorElement.username')
   @DocsEditable()
-  String get target native "HTMLAnchorElement_target_Getter";
+  @Experimental() // untriaged
+  String get username native "HTMLAnchorElement_username_Getter";
 
-  @DomName('HTMLAnchorElement.target')
+  @DomName('HTMLAnchorElement.username')
   @DocsEditable()
-  void set target(String value) native "HTMLAnchorElement_target_Setter";
-
-  @DomName('HTMLAnchorElement.type')
-  @DocsEditable()
-  String get type native "HTMLAnchorElement_type_Getter";
-
-  @DomName('HTMLAnchorElement.type')
-  @DocsEditable()
-  void set type(String value) native "HTMLAnchorElement_type_Setter";
+  @Experimental() // untriaged
+  void set username(String value) native "HTMLAnchorElement_username_Setter";
 
   @DomName('HTMLAnchorElement.toString')
   @DocsEditable()
@@ -554,7 +575,7 @@
  * on MDN.
  */
 @DomName('HTMLAreaElement')
-class AreaElement extends HtmlElement {
+class AreaElement extends HtmlElement implements UrlUtils {
   // To suppress missing implicit constructor warnings.
   factory AreaElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -584,42 +605,6 @@
   @DocsEditable()
   void set coords(String value) native "HTMLAreaElement_coords_Setter";
 
-  @DomName('HTMLAreaElement.hash')
-  @DocsEditable()
-  String get hash native "HTMLAreaElement_hash_Getter";
-
-  @DomName('HTMLAreaElement.host')
-  @DocsEditable()
-  String get host native "HTMLAreaElement_host_Getter";
-
-  @DomName('HTMLAreaElement.hostname')
-  @DocsEditable()
-  String get hostname native "HTMLAreaElement_hostname_Getter";
-
-  @DomName('HTMLAreaElement.href')
-  @DocsEditable()
-  String get href native "HTMLAreaElement_href_Getter";
-
-  @DomName('HTMLAreaElement.href')
-  @DocsEditable()
-  void set href(String value) native "HTMLAreaElement_href_Setter";
-
-  @DomName('HTMLAreaElement.pathname')
-  @DocsEditable()
-  String get pathname native "HTMLAreaElement_pathname_Getter";
-
-  @DomName('HTMLAreaElement.port')
-  @DocsEditable()
-  String get port native "HTMLAreaElement_port_Getter";
-
-  @DomName('HTMLAreaElement.protocol')
-  @DocsEditable()
-  String get protocol native "HTMLAreaElement_protocol_Getter";
-
-  @DomName('HTMLAreaElement.search')
-  @DocsEditable()
-  String get search native "HTMLAreaElement_search_Getter";
-
   @DomName('HTMLAreaElement.shape')
   @DocsEditable()
   String get shape native "HTMLAreaElement_shape_Getter";
@@ -636,6 +621,100 @@
   @DocsEditable()
   void set target(String value) native "HTMLAreaElement_target_Setter";
 
+  @DomName('HTMLAreaElement.hash')
+  @DocsEditable()
+  String get hash native "HTMLAreaElement_hash_Getter";
+
+  @DomName('HTMLAreaElement.hash')
+  @DocsEditable()
+  void set hash(String value) native "HTMLAreaElement_hash_Setter";
+
+  @DomName('HTMLAreaElement.host')
+  @DocsEditable()
+  String get host native "HTMLAreaElement_host_Getter";
+
+  @DomName('HTMLAreaElement.host')
+  @DocsEditable()
+  void set host(String value) native "HTMLAreaElement_host_Setter";
+
+  @DomName('HTMLAreaElement.hostname')
+  @DocsEditable()
+  String get hostname native "HTMLAreaElement_hostname_Getter";
+
+  @DomName('HTMLAreaElement.hostname')
+  @DocsEditable()
+  void set hostname(String value) native "HTMLAreaElement_hostname_Setter";
+
+  @DomName('HTMLAreaElement.href')
+  @DocsEditable()
+  String get href native "HTMLAreaElement_href_Getter";
+
+  @DomName('HTMLAreaElement.href')
+  @DocsEditable()
+  void set href(String value) native "HTMLAreaElement_href_Setter";
+
+  @DomName('HTMLAreaElement.origin')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get origin native "HTMLAreaElement_origin_Getter";
+
+  @DomName('HTMLAreaElement.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get password native "HTMLAreaElement_password_Getter";
+
+  @DomName('HTMLAreaElement.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set password(String value) native "HTMLAreaElement_password_Setter";
+
+  @DomName('HTMLAreaElement.pathname')
+  @DocsEditable()
+  String get pathname native "HTMLAreaElement_pathname_Getter";
+
+  @DomName('HTMLAreaElement.pathname')
+  @DocsEditable()
+  void set pathname(String value) native "HTMLAreaElement_pathname_Setter";
+
+  @DomName('HTMLAreaElement.port')
+  @DocsEditable()
+  String get port native "HTMLAreaElement_port_Getter";
+
+  @DomName('HTMLAreaElement.port')
+  @DocsEditable()
+  void set port(String value) native "HTMLAreaElement_port_Setter";
+
+  @DomName('HTMLAreaElement.protocol')
+  @DocsEditable()
+  String get protocol native "HTMLAreaElement_protocol_Getter";
+
+  @DomName('HTMLAreaElement.protocol')
+  @DocsEditable()
+  void set protocol(String value) native "HTMLAreaElement_protocol_Setter";
+
+  @DomName('HTMLAreaElement.search')
+  @DocsEditable()
+  String get search native "HTMLAreaElement_search_Getter";
+
+  @DomName('HTMLAreaElement.search')
+  @DocsEditable()
+  void set search(String value) native "HTMLAreaElement_search_Setter";
+
+  @DomName('HTMLAreaElement.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get username native "HTMLAreaElement_username_Getter";
+
+  @DomName('HTMLAreaElement.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set username(String value) native "HTMLAreaElement_username_Setter";
+
+  @DomName('HTMLAreaElement.toString')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String toString() native "HTMLAreaElement_toString_Callback";
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -868,7 +947,7 @@
 
 @DocsEditable()
 @DomName('HTMLBodyElement')
-class BodyElement extends HtmlElement {
+class BodyElement extends HtmlElement implements WindowEventHandlers {
   // To suppress missing implicit constructor warnings.
   factory BodyElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -972,6 +1051,11 @@
   @DocsEditable()
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
+  @DomName('HTMLBodyElement.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
   /**
    * Static factory designed to expose `storage` events to event
    * handlers that are not necessarily instances of [BodyElement].
@@ -1052,6 +1136,11 @@
   @DocsEditable()
   ElementStream<Event> get onResize => resizeEvent.forElement(this);
 
+  @DomName('HTMLBodyElement.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
   /// Stream of `storage` events handled by this [BodyElement].
   @DomName('HTMLBodyElement.onstorage')
   @DocsEditable()
@@ -1219,6 +1308,16 @@
 // WARNING: Do not edit - generated code.
 
 
+@DomName('CSSVariablesMapForEachCallback')
+@Experimental() // untriaged
+typedef void CssVariablesMapForEachCallback(String value, String name, CssVariablesMap map);
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('Canvas2DContextAttributes')
 // http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
@@ -1559,6 +1658,16 @@
   @Experimental()
   void set currentPath(Path value) native "CanvasRenderingContext2D_currentPath_Setter";
 
+  @DomName('CanvasRenderingContext2D.currentTransform')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Matrix get currentTransform native "CanvasRenderingContext2D_currentTransform_Getter";
+
+  @DomName('CanvasRenderingContext2D.currentTransform')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set currentTransform(Matrix value) native "CanvasRenderingContext2D_currentTransform_Setter";
+
   @DomName('CanvasRenderingContext2D.fillStyle')
   @DocsEditable()
   dynamic get fillStyle native "CanvasRenderingContext2D_fillStyle_Getter";
@@ -6558,9 +6667,16 @@
   @DocsEditable()
   void deleteRule(int index) native "CSSStyleSheet_deleteRule_Callback";
 
-  @DomName('CSSStyleSheet.insertRule')
-  @DocsEditable()
-  int insertRule(String rule, int index) native "CSSStyleSheet_insertRule_Callback";
+  int insertRule(String rule, [int index]) {
+    if (index != null) {
+      return _insertRule_1(rule, index);
+    }
+    return _insertRule_2(rule);
+  }
+
+  int _insertRule_1(rule, index) native "CSSStyleSheet__insertRule_1_Callback";
+
+  int _insertRule_2(rule) native "CSSStyleSheet__insertRule_2_Callback";
 
   @DomName('CSSStyleSheet.removeRule')
   @DocsEditable()
@@ -6627,6 +6743,19 @@
   @Experimental() // untriaged
   bool delete(String name) native "CSSVariablesMap_delete_Callback";
 
+  void forEach(CssVariablesMapForEachCallback callback, [Object thisArg]) {
+    if (thisArg != null) {
+      _forEach_1(callback, thisArg);
+      return;
+    }
+    _forEach_2(callback);
+    return;
+  }
+
+  void _forEach_1(callback, thisArg) native "CSSVariablesMap__forEach_1_Callback";
+
+  void _forEach_2(callback) native "CSSVariablesMap__forEach_2_Callback";
+
   @DomName('CSSVariablesMap.get')
   @DocsEditable()
   @Experimental() // untriaged
@@ -6813,11 +6942,20 @@
 
   @DomName('Clipboard.types')
   @DocsEditable()
-  List get types native "Clipboard_types_Getter";
+  List<String> get types native "Clipboard_types_Getter";
 
-  @DomName('Clipboard.clearData')
-  @DocsEditable()
-  void clearData([String type]) native "Clipboard_clearData_Callback";
+  void clearData([String type]) {
+    if (type != null) {
+      _clearData_1(type);
+      return;
+    }
+    _clearData_2();
+    return;
+  }
+
+  void _clearData_1(type) native "Clipboard__clearData_1_Callback";
+
+  void _clearData_2() native "Clipboard__clearData_2_Callback";
 
   /**
    * Gets the data for the specified type.
@@ -9663,7 +9801,7 @@
  * An abstract class, which all HTML elements extend.
  */
 @DomName('Element')
-abstract class Element extends Node implements ParentNode, ChildNode {
+abstract class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode {
 
   /**
    * Creates an HTML element from a valid fragment of HTML.
@@ -11025,16 +11163,12 @@
 
   bool hidden;
 
-  String _innerHtml;
-
   InputMethodContext get inputMethodContext;
 
   bool get isContentEditable;
 
   String lang;
 
-  String get outerHtml;
-
   bool spellcheck;
 
   int tabIndex;
@@ -11089,6 +11223,14 @@
   @DocsEditable()
   void set id(String value) native "Element_id_Setter";
 
+  @DomName('Element.innerHTML')
+  @DocsEditable()
+  String get _innerHtml native "Element_innerHTML_Getter";
+
+  @DomName('Element.innerHTML')
+  @DocsEditable()
+  void set _innerHtml(String value) native "Element_innerHTML_Setter";
+
   @DomName('Element.localName')
   @DocsEditable()
   @Experimental() // untriaged
@@ -11119,6 +11261,10 @@
   @DocsEditable()
   int get offsetWidth native "Element_offsetWidth_Getter";
 
+  @DomName('Element.outerHTML')
+  @DocsEditable()
+  String get outerHtml native "Element_outerHTML_Getter";
+
   /**
    * The name of this element's custom pseudo-element.
    *
@@ -13792,6 +13938,348 @@
 // for 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('GlobalEventHandlers')
+@Experimental() // untriaged
+abstract class GlobalEventHandlers extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('GlobalEventHandlers.abortEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
+
+  @DomName('GlobalEventHandlers.blurEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
+
+  @DomName('GlobalEventHandlers.changeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
+
+  @DomName('GlobalEventHandlers.clickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
+
+  @DomName('GlobalEventHandlers.contextmenuEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('GlobalEventHandlers.dblclickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
+
+  @DomName('GlobalEventHandlers.dragEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
+
+  @DomName('GlobalEventHandlers.dragendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
+
+  @DomName('GlobalEventHandlers.dragenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
+
+  @DomName('GlobalEventHandlers.dragleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
+
+  @DomName('GlobalEventHandlers.dragoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
+
+  @DomName('GlobalEventHandlers.dragstartEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
+
+  @DomName('GlobalEventHandlers.dropEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
+
+  @DomName('GlobalEventHandlers.errorEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('GlobalEventHandlers.focusEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
+
+  @DomName('GlobalEventHandlers.inputEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
+
+  @DomName('GlobalEventHandlers.invalidEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
+
+  @DomName('GlobalEventHandlers.keydownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
+
+  @DomName('GlobalEventHandlers.keypressEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
+
+  @DomName('GlobalEventHandlers.keyupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
+
+  @DomName('GlobalEventHandlers.loadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('GlobalEventHandlers.mousedownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
+
+  @DomName('GlobalEventHandlers.mouseenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');
+
+  @DomName('GlobalEventHandlers.mouseleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');
+
+  @DomName('GlobalEventHandlers.mousemoveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
+
+  @DomName('GlobalEventHandlers.mouseoutEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
+
+  @DomName('GlobalEventHandlers.mouseoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
+
+  @DomName('GlobalEventHandlers.mouseupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
+
+  @DomName('GlobalEventHandlers.mousewheelEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
+
+  @DomName('GlobalEventHandlers.resetEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
+
+  @DomName('GlobalEventHandlers.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
+  @DomName('GlobalEventHandlers.selectEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
+
+  @DomName('GlobalEventHandlers.submitEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
+
+  @DomName('GlobalEventHandlers.onabort')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onAbort => abortEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onblur')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onBlur => blurEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onChange => changeEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.oncontextmenu')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondblclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondrag')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondragstart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.ondrop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onerror')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onfocus')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onFocus => focusEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.oninput')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onInput => inputEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.oninvalid')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onInvalid => invalidEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onkeydown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onkeypress')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onkeyup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onLoad => loadEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmousedown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmousemove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseout')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmouseup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onmousewheel')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onreset')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onReset => resetEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onScroll => scrollEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onselect')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onSelect => selectEvent.forTarget(this);
+
+  @DomName('GlobalEventHandlers.onsubmit')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onSubmit => submitEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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.
 
 
@@ -14400,9 +14888,264 @@
 
 @DocsEditable()
 @DomName('HTMLElement')
-class HtmlElement extends Element {
+class HtmlElement extends Element implements GlobalEventHandlers {
   // To suppress missing implicit constructor warnings.
   factory HtmlElement._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('HTMLElement.abortEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
+
+  @DomName('HTMLElement.blurEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
+
+  @DomName('HTMLElement.canplayEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');
+
+  @DomName('HTMLElement.canplaythroughEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');
+
+  @DomName('HTMLElement.changeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
+
+  @DomName('HTMLElement.clickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
+
+  @DomName('HTMLElement.contextmenuEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('HTMLElement.dblclickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
+
+  @DomName('HTMLElement.dragEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
+
+  @DomName('HTMLElement.dragendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
+
+  @DomName('HTMLElement.dragenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
+
+  @DomName('HTMLElement.dragleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
+
+  @DomName('HTMLElement.dragoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
+
+  @DomName('HTMLElement.dragstartEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
+
+  @DomName('HTMLElement.dropEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
+
+  @DomName('HTMLElement.durationchangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');
+
+  @DomName('HTMLElement.emptiedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');
+
+  @DomName('HTMLElement.endedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
+
+  @DomName('HTMLElement.errorEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('HTMLElement.focusEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
+
+  @DomName('HTMLElement.inputEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
+
+  @DomName('HTMLElement.invalidEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
+
+  @DomName('HTMLElement.keydownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
+
+  @DomName('HTMLElement.keypressEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
+
+  @DomName('HTMLElement.keyupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
+
+  @DomName('HTMLElement.loadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('HTMLElement.loadeddataEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');
+
+  @DomName('HTMLElement.loadedmetadataEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');
+
+  @DomName('HTMLElement.mousedownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
+
+  @DomName('HTMLElement.mouseenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');
+
+  @DomName('HTMLElement.mouseleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');
+
+  @DomName('HTMLElement.mousemoveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
+
+  @DomName('HTMLElement.mouseoutEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
+
+  @DomName('HTMLElement.mouseoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
+
+  @DomName('HTMLElement.mouseupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
+
+  @DomName('HTMLElement.mousewheelEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
+
+  @DomName('HTMLElement.pauseEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');
+
+  @DomName('HTMLElement.playEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');
+
+  @DomName('HTMLElement.playingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');
+
+  @DomName('HTMLElement.ratechangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');
+
+  @DomName('HTMLElement.resetEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
+
+  @DomName('HTMLElement.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
+  @DomName('HTMLElement.seekedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');
+
+  @DomName('HTMLElement.seekingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');
+
+  @DomName('HTMLElement.selectEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
+
+  @DomName('HTMLElement.stalledEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');
+
+  @DomName('HTMLElement.submitEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
+
+  @DomName('HTMLElement.suspendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');
+
+  @DomName('HTMLElement.timeupdateEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');
+
+  @DomName('HTMLElement.volumechangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');
+
+  @DomName('HTMLElement.waitingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');
   /**
    * Constructor instantiated by the DOM when a custom element has been created.
    *
@@ -14442,14 +15185,6 @@
   @DocsEditable()
   void set hidden(bool value) native "HTMLElement_hidden_Setter";
 
-  @DomName('HTMLElement.innerHTML')
-  @DocsEditable()
-  String get _innerHtml native "HTMLElement_innerHTML_Getter";
-
-  @DomName('HTMLElement.innerHTML')
-  @DocsEditable()
-  void set _innerHtml(String value) native "HTMLElement_innerHTML_Setter";
-
   @DomName('HTMLElement.inputMethodContext')
   @DocsEditable()
   @Experimental() // untriaged
@@ -14467,10 +15202,6 @@
   @DocsEditable()
   void set lang(String value) native "HTMLElement_lang_Setter";
 
-  @DomName('HTMLElement.outerHTML')
-  @DocsEditable()
-  String get outerHtml native "HTMLElement_outerHTML_Getter";
-
   @DomName('HTMLElement.spellcheck')
   @DocsEditable()
   // http://blog.whatwg.org/the-road-to-html-5-spellchecking
@@ -14541,6 +15272,261 @@
   @Experimental() // non-standard
   void insertAdjacentText(String where, String text) native "HTMLElement_insertAdjacentText_Callback";
 
+  @DomName('HTMLElement.onabort')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onAbort => abortEvent.forElement(this);
+
+  @DomName('HTMLElement.onblur')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onBlur => blurEvent.forElement(this);
+
+  @DomName('HTMLElement.oncanplay')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);
+
+  @DomName('HTMLElement.oncanplaythrough')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);
+
+  @DomName('HTMLElement.onchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onChange => changeEvent.forElement(this);
+
+  @DomName('HTMLElement.onclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);
+
+  @DomName('HTMLElement.oncontextmenu')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);
+
+  @DomName('HTMLElement.ondblclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
+
+  @DomName('HTMLElement.ondrag')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);
+
+  @DomName('HTMLElement.ondragend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);
+
+  @DomName('HTMLElement.ondragenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);
+
+  @DomName('HTMLElement.ondragleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);
+
+  @DomName('HTMLElement.ondragover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);
+
+  @DomName('HTMLElement.ondragstart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);
+
+  @DomName('HTMLElement.ondrop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);
+
+  @DomName('HTMLElement.ondurationchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);
+
+  @DomName('HTMLElement.onemptied')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);
+
+  @DomName('HTMLElement.onended')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onEnded => endedEvent.forElement(this);
+
+  @DomName('HTMLElement.onerror')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onError => errorEvent.forElement(this);
+
+  @DomName('HTMLElement.onfocus')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onFocus => focusEvent.forElement(this);
+
+  @DomName('HTMLElement.oninput')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onInput => inputEvent.forElement(this);
+
+  @DomName('HTMLElement.oninvalid')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);
+
+  @DomName('HTMLElement.onkeydown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);
+
+  @DomName('HTMLElement.onkeypress')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);
+
+  @DomName('HTMLElement.onkeyup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);
+
+  @DomName('HTMLElement.onload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoad => loadEvent.forElement(this);
+
+  @DomName('HTMLElement.onloadeddata')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);
+
+  @DomName('HTMLElement.onloadedmetadata')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);
+
+  @DomName('HTMLElement.onmousedown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);
+
+  @DomName('HTMLElement.onmouseenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);
+
+  @DomName('HTMLElement.onmouseleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);
+
+  @DomName('HTMLElement.onmousemove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);
+
+  @DomName('HTMLElement.onmouseout')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);
+
+  @DomName('HTMLElement.onmouseover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);
+
+  @DomName('HTMLElement.onmouseup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);
+
+  @DomName('HTMLElement.onmousewheel')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);
+
+  @DomName('HTMLElement.onpause')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPause => pauseEvent.forElement(this);
+
+  @DomName('HTMLElement.onplay')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPlay => playEvent.forElement(this);
+
+  @DomName('HTMLElement.onplaying')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPlaying => playingEvent.forElement(this);
+
+  @DomName('HTMLElement.onratechange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);
+
+  @DomName('HTMLElement.onreset')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onReset => resetEvent.forElement(this);
+
+  @DomName('HTMLElement.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
+  @DomName('HTMLElement.onseeked')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);
+
+  @DomName('HTMLElement.onseeking')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);
+
+  @DomName('HTMLElement.onselect')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSelect => selectEvent.forElement(this);
+
+  @DomName('HTMLElement.onstalled')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onStalled => stalledEvent.forElement(this);
+
+  @DomName('HTMLElement.onsubmit')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSubmit => submitEvent.forElement(this);
+
+  @DomName('HTMLElement.onsuspend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);
+
+  @DomName('HTMLElement.ontimeupdate')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);
+
+  @DomName('HTMLElement.onvolumechange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);
+
+  @DomName('HTMLElement.onwaiting')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -16763,7 +17749,7 @@
 @DomName('InputMethodContext')
 // http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext
 @Experimental()
-class InputMethodContext extends NativeFieldWrapperClass2 {
+class InputMethodContext extends EventTarget {
   // To suppress missing implicit constructor warnings.
   factory InputMethodContext._() { throw new UnsupportedError("Not supported"); }
 
@@ -16788,9 +17774,20 @@
   @DocsEditable()
   void setCaretRectangle(Node anchor, int x, int y, int w, int h) native "InputMethodContext_setCaretRectangle_Callback";
 
-  @DomName('InputMethodContext.setExclusionRectangle')
+  @DomName('InputMethodContext.addEventListener')
   @DocsEditable()
-  void setExclusionRectangle(Node anchor, int x, int y, int w, int h) native "InputMethodContext_setExclusionRectangle_Callback";
+  @Experimental() // untriaged
+  void addEventListener(String type, EventListener listener, [bool useCapture]) native "InputMethodContext_addEventListener_Callback";
+
+  @DomName('InputMethodContext.dispatchEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool dispatchEvent(Event event) native "InputMethodContext_dispatchEvent_Callback";
+
+  @DomName('InputMethodContext.removeEventListener')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void removeEventListener(String type, EventListener listener, [bool useCapture]) native "InputMethodContext_removeEventListener_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -16900,6 +17897,11 @@
   @DocsEditable()
   bool get metaKey native "KeyboardEvent_metaKey_Getter";
 
+  @DomName('KeyboardEvent.repeat')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool get repeat native "KeyboardEvent_repeat_Getter";
+
   @DomName('KeyboardEvent.shiftKey')
   @DocsEditable()
   bool get shiftKey native "KeyboardEvent_shiftKey_Getter";
@@ -17195,10 +18197,6 @@
   @DocsEditable()
   DomSettableTokenList get sizes native "HTMLLinkElement_sizes_Getter";
 
-  @DomName('HTMLLinkElement.sizes')
-  @DocsEditable()
-  void set sizes(DomSettableTokenList value) native "HTMLLinkElement_sizes_Setter";
-
   @DomName('HTMLLinkElement.type')
   @DocsEditable()
   String get type native "HTMLLinkElement_type_Getter";
@@ -17874,12 +18872,6 @@
   @DocsEditable()
   MediaError get error native "HTMLMediaElement_error_Getter";
 
-  @DomName('HTMLMediaElement.initialTime')
-  @DocsEditable()
-  // http://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-media-initialtime
-  @Experimental()
-  double get initialTime native "HTMLMediaElement_initialTime_Getter";
-
   @DomName('HTMLMediaElement.loop')
   @DocsEditable()
   bool get loop native "HTMLMediaElement_loop_Getter";
@@ -17964,11 +18956,6 @@
   @DocsEditable()
   void set src(String value) native "HTMLMediaElement_src_Setter";
 
-  @DomName('HTMLMediaElement.startTime')
-  @DocsEditable()
-  @Experimental() // non-standard
-  double get startTime native "HTMLMediaElement_startTime_Getter";
-
   @DomName('HTMLMediaElement.textTracks')
   @DocsEditable()
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-texttracks
@@ -17991,46 +18978,6 @@
   @Experimental() // nonstandard
   int get audioDecodedByteCount native "HTMLMediaElement_webkitAudioDecodedByteCount_Getter";
 
-  @DomName('HTMLMediaElement.webkitClosedCaptionsVisible')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  bool get closedCaptionsVisible native "HTMLMediaElement_webkitClosedCaptionsVisible_Getter";
-
-  @DomName('HTMLMediaElement.webkitClosedCaptionsVisible')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  void set closedCaptionsVisible(bool value) native "HTMLMediaElement_webkitClosedCaptionsVisible_Setter";
-
-  @DomName('HTMLMediaElement.webkitHasClosedCaptions')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  bool get hasClosedCaptions native "HTMLMediaElement_webkitHasClosedCaptions_Getter";
-
-  @DomName('HTMLMediaElement.webkitPreservesPitch')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  bool get preservesPitch native "HTMLMediaElement_webkitPreservesPitch_Getter";
-
-  @DomName('HTMLMediaElement.webkitPreservesPitch')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  @Experimental() // nonstandard
-  void set preservesPitch(bool value) native "HTMLMediaElement_webkitPreservesPitch_Setter";
-
   @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18964,6 +19911,11 @@
     return completer.future;
   }
 
+  @DomName('MediaStreamTrack.stop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void stop() native "MediaStreamTrack_stop_Callback";
+
   @DomName('MediaStreamTrack.addEventListener')
   @DocsEditable()
   void addEventListener(String type, EventListener listener, [bool useCapture]) native "MediaStreamTrack_addEventListener_Callback";
@@ -20259,6 +21211,11 @@
   @DocsEditable()
   String get language native "Navigator_language_Getter";
 
+  @DomName('Navigator.maxTouchPoints')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get maxTouchPoints native "Navigator_maxTouchPoints_Getter";
+
   @DomName('Navigator.mimeTypes')
   @DocsEditable()
   @Experimental() // nonstandard
@@ -22766,15 +23723,20 @@
   // To suppress missing implicit constructor warnings.
   factory Promise._() { throw new UnsupportedError("Not supported"); }
 
-  @DomName('Promise._any')
+  @DomName('Promise.all')
   @DocsEditable()
   @Experimental() // untriaged
-  static Promise _any(Object values) native "Promise__any_Callback";
+  static Promise all(Object iterable) native "Promise_all_Callback";
 
-  @DomName('Promise.every')
+  @DomName('Promise.cast')
   @DocsEditable()
   @Experimental() // untriaged
-  static Promise every(Object values) native "Promise_every_Callback";
+  static Promise cast(Object value) native "Promise_cast_Callback";
+
+  @DomName('Promise.race')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static Promise race(Object iterable) native "Promise_race_Callback";
 
   @DomName('Promise.reject')
   @DocsEditable()
@@ -23758,12 +24720,12 @@
 
   @DomName('RTCSessionDescription.RTCSessionDescription')
   @DocsEditable()
-  factory RtcSessionDescription(Map dictionary) {
-    return RtcSessionDescription._create_1(dictionary);
+  factory RtcSessionDescription([Map descriptionInitDict]) {
+    return RtcSessionDescription._create_1(descriptionInitDict);
   }
 
   @DocsEditable()
-  static RtcSessionDescription _create_1(dictionary) native "RTCSessionDescription__create_1constructorCallback";
+  static RtcSessionDescription _create_1(descriptionInitDict) native "RTCSessionDescription__create_1constructorCallback";
 
   @DomName('RTCSessionDescription.sdp')
   @DocsEditable()
@@ -24467,6 +25429,11 @@
   @DocsEditable()
   void set resetStyleInheritance(bool value) native "HTMLShadowElement_resetStyleInheritance_Setter";
 
+  @DomName('HTMLShadowElement.getDistributedNodes')
+  @DocsEditable()
+  @Experimental() // untriaged
+  List<Node> getDistributedNodes() native "HTMLShadowElement_getDistributedNodes_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
@@ -24495,6 +25462,11 @@
   @DocsEditable()
   void set applyAuthorStyles(bool value) native "ShadowRoot_applyAuthorStyles_Setter";
 
+  @DomName('ShadowRoot.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Element get host native "ShadowRoot_host_Getter";
+
   @DomName('ShadowRoot.innerHTML')
   @DocsEditable()
   String get innerHtml native "ShadowRoot_innerHTML_Getter";
@@ -24516,6 +25488,11 @@
   @DocsEditable()
   void set resetStyleInheritance(bool value) native "ShadowRoot_resetStyleInheritance_Setter";
 
+  @DomName('ShadowRoot.styleSheets')
+  @DocsEditable()
+  @Experimental() // untriaged
+  List<StyleSheet> get styleSheets native "ShadowRoot_styleSheets_Getter";
+
   @DomName('ShadowRoot.cloneNode')
   @DocsEditable()
   Node clone(bool deep) native "ShadowRoot_cloneNode_Callback";
@@ -25437,7 +26414,7 @@
 @DomName('SpeechSynthesis')
 // https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
 @Experimental()
-class SpeechSynthesis extends NativeFieldWrapperClass2 {
+class SpeechSynthesis extends EventTarget {
   // To suppress missing implicit constructor warnings.
   factory SpeechSynthesis._() { throw new UnsupportedError("Not supported"); }
 
@@ -25473,6 +26450,21 @@
   @DocsEditable()
   void speak(SpeechSynthesisUtterance utterance) native "SpeechSynthesis_speak_Callback";
 
+  @DomName('SpeechSynthesis.addEventListener')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void addEventListener(String type, EventListener listener, [bool useCapture]) native "SpeechSynthesis_addEventListener_Callback";
+
+  @DomName('SpeechSynthesis.dispatchEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool dispatchEvent(Event event) native "SpeechSynthesis_dispatchEvent_Callback";
+
+  @DomName('SpeechSynthesis.removeEventListener')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void removeEventListener(String type, EventListener listener, [bool useCapture]) native "SpeechSynthesis_removeEventListener_Callback";
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -26926,14 +27918,29 @@
   @DocsEditable()
   void set mode(String value) native "TextTrack_mode_Setter";
 
+  @DomName('TextTrack.regions')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VttRegionList get regions native "TextTrack_regions_Getter";
+
   @DomName('TextTrack.addCue')
   @DocsEditable()
   void addCue(TextTrackCue cue) native "TextTrack_addCue_Callback";
 
+  @DomName('TextTrack.addRegion')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void addRegion(VttRegion region) native "TextTrack_addRegion_Callback";
+
   @DomName('TextTrack.removeCue')
   @DocsEditable()
   void removeCue(TextTrackCue cue) native "TextTrack_removeCue_Callback";
 
+  @DomName('TextTrack.removeRegion')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void removeRegion(VttRegion region) native "TextTrack_removeRegion_Callback";
+
   @DomName('TextTrack.addEventListener')
   @DocsEditable()
   void addEventListener(String type, EventListener listener, [bool useCapture]) native "TextTrack_addEventListener_Callback";
@@ -27050,6 +28057,16 @@
   @Experimental() // nonstandard
   void set position(int value) native "TextTrackCue_position_Setter";
 
+  @DomName('TextTrackCue.regionId')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get regionId native "TextTrackCue_regionId_Getter";
+
+  @DomName('TextTrackCue.regionId')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set regionId(String value) native "TextTrackCue_regionId_Setter";
+
   @DomName('TextTrackCue.size')
   @DocsEditable()
   @Experimental() // nonstandard
@@ -27511,12 +28528,7 @@
    * Note that touch events are only supported if the user is using a touch
    * device.
    */
-  static bool get supported {
-    // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
-    // Basically, this is a fairly common check and it'd be great if it did not
-    // throw exceptions.
-    return Device.isEventTypeSupported('TouchEvent');
-  }
+  static bool get supported => Device.isEventTypeSupported('TouchEvent');
 }
 // 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
@@ -27939,7 +28951,7 @@
 
 @DocsEditable()
 @DomName('URL')
-class Url extends NativeFieldWrapperClass2 {
+class Url extends NativeFieldWrapperClass2 implements UrlUtils {
   // To suppress missing implicit constructor warnings.
   factory Url._() { throw new UnsupportedError("Not supported"); }
 
@@ -27952,13 +28964,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");
@@ -27988,6 +29000,301 @@
   @DocsEditable()
   static void revokeObjectUrl(String url) native "URL_revokeObjectURL_Callback";
 
+  @DomName('URL.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get hash native "URL_hash_Getter";
+
+  @DomName('URL.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set hash(String value) native "URL_hash_Setter";
+
+  @DomName('URL.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get host native "URL_host_Getter";
+
+  @DomName('URL.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set host(String value) native "URL_host_Setter";
+
+  @DomName('URL.hostname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get hostname native "URL_hostname_Getter";
+
+  @DomName('URL.hostname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set hostname(String value) native "URL_hostname_Setter";
+
+  @DomName('URL.href')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get href native "URL_href_Getter";
+
+  @DomName('URL.href')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set href(String value) native "URL_href_Setter";
+
+  @DomName('URL.origin')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get origin native "URL_origin_Getter";
+
+  @DomName('URL.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get password native "URL_password_Getter";
+
+  @DomName('URL.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set password(String value) native "URL_password_Setter";
+
+  @DomName('URL.pathname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get pathname native "URL_pathname_Getter";
+
+  @DomName('URL.pathname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set pathname(String value) native "URL_pathname_Setter";
+
+  @DomName('URL.port')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get port native "URL_port_Getter";
+
+  @DomName('URL.port')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set port(String value) native "URL_port_Setter";
+
+  @DomName('URL.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get protocol native "URL_protocol_Getter";
+
+  @DomName('URL.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set protocol(String value) native "URL_protocol_Setter";
+
+  @DomName('URL.search')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get search native "URL_search_Getter";
+
+  @DomName('URL.search')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set search(String value) native "URL_search_Setter";
+
+  @DomName('URL.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get username native "URL_username_Getter";
+
+  @DomName('URL.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set username(String value) native "URL_username_Setter";
+
+  @DomName('URL.toString')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String toString() native "URL_toString_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
+@DomName('URLUtils')
+@Experimental() // untriaged
+abstract class UrlUtils extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory UrlUtils._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('URLUtils.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get hash native "URLUtils_hash_Getter";
+
+  @DomName('URLUtils.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set hash(String value) native "URLUtils_hash_Setter";
+
+  @DomName('URLUtils.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get host native "URLUtils_host_Getter";
+
+  @DomName('URLUtils.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set host(String value) native "URLUtils_host_Setter";
+
+  @DomName('URLUtils.hostname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get hostname native "URLUtils_hostname_Getter";
+
+  @DomName('URLUtils.hostname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set hostname(String value) native "URLUtils_hostname_Setter";
+
+  @DomName('URLUtils.href')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get href native "URLUtils_href_Getter";
+
+  @DomName('URLUtils.href')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set href(String value) native "URLUtils_href_Setter";
+
+  @DomName('URLUtils.origin')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get origin native "URLUtils_origin_Getter";
+
+  @DomName('URLUtils.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get password native "URLUtils_password_Getter";
+
+  @DomName('URLUtils.password')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set password(String value) native "URLUtils_password_Setter";
+
+  @DomName('URLUtils.pathname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get pathname native "URLUtils_pathname_Getter";
+
+  @DomName('URLUtils.pathname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set pathname(String value) native "URLUtils_pathname_Setter";
+
+  @DomName('URLUtils.port')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get port native "URLUtils_port_Getter";
+
+  @DomName('URLUtils.port')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set port(String value) native "URLUtils_port_Setter";
+
+  @DomName('URLUtils.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get protocol native "URLUtils_protocol_Getter";
+
+  @DomName('URLUtils.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set protocol(String value) native "URLUtils_protocol_Setter";
+
+  @DomName('URLUtils.search')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get search native "URLUtils_search_Getter";
+
+  @DomName('URLUtils.search')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set search(String value) native "URLUtils_search_Setter";
+
+  @DomName('URLUtils.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get username native "URLUtils_username_Getter";
+
+  @DomName('URLUtils.username')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set username(String value) native "URLUtils_username_Setter";
+
+  @DomName('URLUtils.toString')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String toString() native "URLUtils_toString_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
+@DomName('URLUtilsReadOnly')
+@Experimental() // untriaged
+abstract class UrlUtilsReadOnly extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory UrlUtilsReadOnly._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('URLUtilsReadOnly.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get hash native "URLUtilsReadOnly_hash_Getter";
+
+  @DomName('URLUtilsReadOnly.host')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get host native "URLUtilsReadOnly_host_Getter";
+
+  @DomName('URLUtilsReadOnly.hostname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get hostname native "URLUtilsReadOnly_hostname_Getter";
+
+  @DomName('URLUtilsReadOnly.href')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get href native "URLUtilsReadOnly_href_Getter";
+
+  @DomName('URLUtilsReadOnly.pathname')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get pathname native "URLUtilsReadOnly_pathname_Getter";
+
+  @DomName('URLUtilsReadOnly.port')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get port native "URLUtilsReadOnly_port_Getter";
+
+  @DomName('URLUtilsReadOnly.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get protocol native "URLUtilsReadOnly_protocol_Getter";
+
+  @DomName('URLUtilsReadOnly.search')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get search native "URLUtilsReadOnly_search_Getter";
+
+  @DomName('URLUtilsReadOnly.toString')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String toString() native "URLUtilsReadOnly_toString_Callback";
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -28109,6 +29416,11 @@
   @DocsEditable()
   void set width(int value) native "HTMLVideoElement_width_Setter";
 
+  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VideoPlaybackQuality getVideoPlaybackQuality() native "HTMLVideoElement_getVideoPlaybackQuality_Callback";
+
   @DomName('HTMLVideoElement.webkitEnterFullscreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -28133,6 +29445,41 @@
 // WARNING: Do not edit - generated code.
 
 
+@DocsEditable()
+@DomName('VideoPlaybackQuality')
+@Experimental() // untriaged
+class VideoPlaybackQuality extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory VideoPlaybackQuality._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get corruptedVideoFrames native "VideoPlaybackQuality_corruptedVideoFrames_Getter";
+
+  @DomName('VideoPlaybackQuality.creationTime')
+  @DocsEditable()
+  @Experimental() // untriaged
+  double get creationTime native "VideoPlaybackQuality_creationTime_Getter";
+
+  @DomName('VideoPlaybackQuality.droppedVideoFrames')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get droppedVideoFrames native "VideoPlaybackQuality_droppedVideoFrames_Getter";
+
+  @DomName('VideoPlaybackQuality.totalVideoFrames')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get totalVideoFrames native "VideoPlaybackQuality_totalVideoFrames_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
 @DomName('VoidCallback')
 // http://www.w3.org/TR/file-system-api/#the-voidcallback-interface
 @Experimental()
@@ -28145,6 +29492,145 @@
 
 
 @DocsEditable()
+@DomName('VTTRegion')
+@Experimental() // untriaged
+class VttRegion extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory VttRegion._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('VTTRegion.VTTRegion')
+  @DocsEditable()
+  factory VttRegion() {
+    return VttRegion._create_1();
+  }
+
+  @DocsEditable()
+  static VttRegion _create_1() native "VTTRegion__create_1constructorCallback";
+
+  @DomName('VTTRegion.height')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get height native "VTTRegion_height_Getter";
+
+  @DomName('VTTRegion.height')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set height(int value) native "VTTRegion_height_Setter";
+
+  @DomName('VTTRegion.id')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get id native "VTTRegion_id_Getter";
+
+  @DomName('VTTRegion.id')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set id(String value) native "VTTRegion_id_Setter";
+
+  @DomName('VTTRegion.regionAnchorX')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get regionAnchorX native "VTTRegion_regionAnchorX_Getter";
+
+  @DomName('VTTRegion.regionAnchorX')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set regionAnchorX(num value) native "VTTRegion_regionAnchorX_Setter";
+
+  @DomName('VTTRegion.regionAnchorY')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get regionAnchorY native "VTTRegion_regionAnchorY_Getter";
+
+  @DomName('VTTRegion.regionAnchorY')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set regionAnchorY(num value) native "VTTRegion_regionAnchorY_Setter";
+
+  @DomName('VTTRegion.scroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get scroll native "VTTRegion_scroll_Getter";
+
+  @DomName('VTTRegion.scroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set scroll(String value) native "VTTRegion_scroll_Setter";
+
+  @DomName('VTTRegion.track')
+  @DocsEditable()
+  @Experimental() // untriaged
+  TextTrack get track native "VTTRegion_track_Getter";
+
+  @DomName('VTTRegion.viewportAnchorX')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get viewportAnchorX native "VTTRegion_viewportAnchorX_Getter";
+
+  @DomName('VTTRegion.viewportAnchorX')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set viewportAnchorX(num value) native "VTTRegion_viewportAnchorX_Setter";
+
+  @DomName('VTTRegion.viewportAnchorY')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get viewportAnchorY native "VTTRegion_viewportAnchorY_Getter";
+
+  @DomName('VTTRegion.viewportAnchorY')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set viewportAnchorY(num value) native "VTTRegion_viewportAnchorY_Setter";
+
+  @DomName('VTTRegion.width')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get width native "VTTRegion_width_Getter";
+
+  @DomName('VTTRegion.width')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set width(num value) native "VTTRegion_width_Setter";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
+@DomName('VTTRegionList')
+@Experimental() // untriaged
+class VttRegionList extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory VttRegionList._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('VTTRegionList.length')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get length native "VTTRegionList_length_Getter";
+
+  @DomName('VTTRegionList.getRegionById')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VttRegion getRegionById(String id) native "VTTRegionList_getRegionById_Callback";
+
+  @DomName('VTTRegionList.item')
+  @DocsEditable()
+  @Experimental() // untriaged
+  VttRegion item(int index) native "VTTRegionList_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()
 /**
  * Use the WebSocket interface to connect to a WebSocket,
  * and to send and receive data on that WebSocket.
@@ -28537,7 +30023,7 @@
  * * [Window](http://www.w3.org/TR/Window/) from the W3C.
  */
 @DomName('Window')
-class Window extends EventTarget implements WindowBase, _WindowTimers, WindowBase64 {
+class Window extends EventTarget implements WindowEventHandlers, WindowBase, GlobalEventHandlers, _WindowTimers, WindowBase64 {
 
   /**
    * Returns a Future that completes just before the window is about to
@@ -28555,7 +30041,7 @@
    * [animationFrame] again for the animation to continue.
    */
   Future<num> get animationFrame {
-    var completer = new Completer<num>();
+    var completer = new Completer<num>.sync();
     requestAnimationFrame((time) {
       completer.complete(time);
     });
@@ -29091,6 +30577,10 @@
   @DocsEditable()
   WindowBase get opener native "Window_opener_Getter";
 
+  @DomName('Window.opener')
+  @DocsEditable()
+  void set opener(Window value) native "Window_opener_Setter";
+
   /**
    * The height of this window including all user interface elements.
    *
@@ -30076,6 +31566,108 @@
 // for 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('WindowEventHandlers')
+@Experimental() // untriaged
+abstract class WindowEventHandlers extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory WindowEventHandlers._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('WindowEventHandlers.beforeunloadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> beforeUnloadEvent = const EventStreamProvider<Event>('beforeunload');
+
+  @DomName('WindowEventHandlers.hashchangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');
+
+  @DomName('WindowEventHandlers.messageEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
+
+  @DomName('WindowEventHandlers.offlineEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');
+
+  @DomName('WindowEventHandlers.onlineEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');
+
+  @DomName('WindowEventHandlers.popstateEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');
+
+  @DomName('WindowEventHandlers.resizeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
+
+  @DomName('WindowEventHandlers.storageEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');
+
+  @DomName('WindowEventHandlers.unloadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
+
+  @DomName('WindowEventHandlers.onbeforeunload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onhashchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onmessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onoffline')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onOffline => offlineEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.ononline')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onOnline => onlineEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onpopstate')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onresize')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onResize => resizeEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onstorage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
+
+  @DomName('WindowEventHandlers.onunload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Stream<Event> get onUnload => unloadEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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.
 
 
@@ -31541,7 +33133,7 @@
 @DomName('HTMLFrameSetElement')
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
 @deprecated // deprecated
-abstract class _HTMLFrameSetElement extends HtmlElement {
+abstract class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
   /**
@@ -32222,7 +33814,7 @@
 @DomName('WorkerLocation')
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
 @Experimental()
-abstract class _WorkerLocation extends NativeFieldWrapperClass2 {
+abstract class _WorkerLocation extends NativeFieldWrapperClass2 implements UrlUtilsReadOnly {
   // To suppress missing implicit constructor warnings.
   factory _WorkerLocation._() { throw new UnsupportedError("Not supported"); }
 
@@ -37055,26 +38647,26 @@
 };
 
 class _Timer implements Timer {
-  const int _STATE_TIMEOUT = 0;
-  const int _STATE_INTERVAL = 1;
-  var _state;
+  static const int _STATE_TIMEOUT = 0;
+  static const int _STATE_INTERVAL = 1;
+  int _state;
 
   _Timer(int milliSeconds, void callback(Timer timer), bool repeating) {
     if (repeating) {
-      _state = window._setInterval(() {
+      _state = (window._setInterval(() {
         callback(this);
-      }, milliSeconds) * 2 + _STATE_INTERVAL;
+      }, milliSeconds) << 1) | _STATE_INTERVAL;
     } else {
-      _state = window._setTimeout(() {
+      _state = (window._setTimeout(() {
         _state = null;
         callback(this);
-      }, milliSeconds) * 2 + _STATE_TIMEOUT;
+      }, milliSeconds) << 1) | _STATE_TIMEOUT;
     }
   }
 
   void cancel() {
     if (_state == null) return;
-    int id = _state ~/ 2;
+    int id = _state >> 1;
     if ((_state & 1) == _STATE_TIMEOUT) {
       window._clearTimeout(id);
     } else {
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 3bd2973..d2d3a45 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -341,15 +341,30 @@
 
 ImageData convertNativeToDart_ImageData(nativeImageData) {
 
-  // None of the native getters that return ImageData have the type ImageData
-  // since that is incorrect for FireFox (which returns a plain Object).  So we
-  // need something that tells the compiler that the ImageData class has been
-  // instantiated.
+  // None of the native getters that return ImageData are declared as returning
+  // [ImageData] since that is incorrect for FireFox, which returns a plain
+  // Object.  So we need something that tells the compiler that the ImageData
+  // class has been instantiated.
   // TODO(sra): Remove this when all the ImageData returning APIs have been
   // annotated as returning the union ImageData + Object.
   JS('ImageData', '0');
 
-  if (nativeImageData is ImageData) return nativeImageData;
+  if (nativeImageData is ImageData) {
+
+    // Fix for Issue 16069: on IE, the `data` field is a CanvasPixelArray which
+    // has Array as the constructor property.  This interferes with finding the
+    // correct interceptor.  Fix it by overwriting the constructor property.
+    var data = nativeImageData.data;
+    if (JS('bool', '#.constructor === Array', data)) {
+      if (JS('bool', 'typeof CanvasPixelArray !== "undefined"')) {
+        JS('void', '#.constructor = CanvasPixelArray', data);
+        // This TypedArray property is missing from CanvasPixelArray.
+        JS('void', '#.BYTES_PER_ELEMENT = 1', data);
+      }
+    }
+
+    return nativeImageData;
+  }
 
   // On Firefox the above test fails because [nativeImageData] is a plain
   // object.  So we create a _TypedImageData.
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 1068f9c..a54fde34 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1122,6 +1122,11 @@
   @Creates('Cursor')
   Request _openCursor(Object key, [String direction]) native;
 
+  @DomName('IDBObjectStore.openKeyCursor')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Request openKeyCursor(Object range, String direction) native;
+
   @DomName('IDBObjectStore.put')
   @DocsEditable()
   @Returns('Request')
@@ -1412,6 +1417,11 @@
   @Experimental() // untriaged
   final String dataLoss;
 
+  @DomName('IDBVersionChangeEvent.dataLossMessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final String dataLossMessage;
+
   @DomName('IDBVersionChangeEvent.newVersion')
   @DocsEditable()
   @Creates('int|String|Null')
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index ae72ed0..b2dbd4c 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -823,6 +823,11 @@
   @DocsEditable()
   Request _openCursor(Object key, [String direction]) native "IDBObjectStore_openCursor_Callback";
 
+  @DomName('IDBObjectStore.openKeyCursor')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Request openKeyCursor(Object range, String direction) native "IDBObjectStore_openKeyCursor_Callback";
+
   @DomName('IDBObjectStore.put')
   @DocsEditable()
   Request _put(Object value, [Object key]) native "IDBObjectStore_put_Callback";
@@ -1114,6 +1119,11 @@
   @Experimental() // untriaged
   String get dataLoss native "IDBVersionChangeEvent_dataLoss_Getter";
 
+  @DomName('IDBVersionChangeEvent.dataLossMessage')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get dataLossMessage native "IDBVersionChangeEvent_dataLossMessage_Getter";
+
   @DomName('IDBVersionChangeEvent.newVersion')
   @DocsEditable()
   dynamic get newVersion native "IDBVersionChangeEvent_newVersion_Getter";
diff --git a/sdk/lib/_collection_dev/collection_dev.dart b/sdk/lib/internal/internal.dart
similarity index 93%
rename from sdk/lib/_collection_dev/collection_dev.dart
rename to sdk/lib/internal/internal.dart
index 9902b0e..2d41870 100644
--- a/sdk/lib/_collection_dev/collection_dev.dart
+++ b/sdk/lib/internal/internal.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library dart._collection.dev;
+library dart._internal;
 
 import 'dart:collection';
 
diff --git a/sdk/lib/_collection_dev/collection_dev_sources.gypi b/sdk/lib/internal/internal_sources.gypi
similarity index 80%
rename from sdk/lib/_collection_dev/collection_dev_sources.gypi
rename to sdk/lib/internal/internal_sources.gypi
index bb25742..17cc287 100644
--- a/sdk/lib/_collection_dev/collection_dev_sources.gypi
+++ b/sdk/lib/internal/internal_sources.gypi
@@ -2,10 +2,10 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# This file contains all sources for the dart:collection-dev library.
+# This file contains all sources for the dart:_internal library.
 {
   'sources': [
-    'collection_dev.dart',
+    'internal.dart',
     # The above file needs to be first as it lists the parts below.
     'iterable.dart',
     'list.dart',
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/internal/iterable.dart
similarity index 99%
rename from sdk/lib/_collection_dev/iterable.dart
rename to sdk/lib/internal/iterable.dart
index 4bcc7b8..85c505c 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/internal/iterable.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.
 
-part of dart._collection.dev;
+part of dart._internal;
 
 /**
  * Marker interface for [Iterable] subclasses that have an efficient
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/internal/list.dart
similarity index 99%
rename from sdk/lib/_collection_dev/list.dart
rename to sdk/lib/internal/list.dart
index e8929de..14eeb13 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/internal/list.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.
 
-part of dart._collection.dev;
+part of dart._internal;
 
 /**
  * Mixin that throws on the length changing operations of [List].
diff --git a/sdk/lib/_collection_dev/lists.dart b/sdk/lib/internal/lists.dart
similarity index 98%
rename from sdk/lib/_collection_dev/lists.dart
rename to sdk/lib/internal/lists.dart
index eed1df5..f821616 100644
--- a/sdk/lib/_collection_dev/lists.dart
+++ b/sdk/lib/internal/lists.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.
 
-part of dart._collection.dev;
+part of dart._internal;
 
 class Lists {
   static void copy(List src, int srcStart,
diff --git a/sdk/lib/_collection_dev/print.dart b/sdk/lib/internal/print.dart
similarity index 94%
rename from sdk/lib/_collection_dev/print.dart
rename to sdk/lib/internal/print.dart
index 0c7182e..c3e23b8 100644
--- a/sdk/lib/_collection_dev/print.dart
+++ b/sdk/lib/internal/print.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.
 
-part of dart._collection.dev;
+part of dart._internal;
 
 /**
  * This function is set by the first allocation of a Zone.
diff --git a/sdk/lib/_collection_dev/sort.dart b/sdk/lib/internal/sort.dart
similarity index 99%
rename from sdk/lib/_collection_dev/sort.dart
rename to sdk/lib/internal/sort.dart
index 9bc7c9a..562d8b8 100644
--- a/sdk/lib/_collection_dev/sort.dart
+++ b/sdk/lib/internal/sort.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.
 
-part of dart._collection.dev;
+part of dart._internal;
 
 /**
  * Dual-Pivot Quicksort algorithm.
diff --git a/sdk/lib/_collection_dev/symbol.dart b/sdk/lib/internal/symbol.dart
similarity index 98%
rename from sdk/lib/_collection_dev/symbol.dart
rename to sdk/lib/internal/symbol.dart
index 87517ba..7a0369a 100644
--- a/sdk/lib/_collection_dev/symbol.dart
+++ b/sdk/lib/internal/symbol.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.
 
-part of dart._collection.dev;
+part of dart._internal;
 
 /**
  * Implementation of [core.Symbol].  This class uses the same name as
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 94b932a..ea35580 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -16,9 +16,8 @@
 const int _OSERROR_RESPONSE_MESSAGE = 2;
 
 // Functions used to receive exceptions from native ports.
-bool _isErrorResponse(response) {
-  return response is List && response[0] != _SUCCESS_RESPONSE;
-}
+bool _isErrorResponse(response) =>
+    response is List && response[0] != _SUCCESS_RESPONSE;
 
 /**
  * Returns an Exception or an Error
@@ -54,27 +53,6 @@
   /** Constant used to indicate that no OS error code is available. */
   static const int noErrorCode = -1;
 
-  /** Creates an OSError object from a message and an errorCode. */
-  const OSError([String this.message = "", int this.errorCode = noErrorCode]);
-
-  /** Converts an OSError object to a string representation. */
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write("OS Error");
-    if (!message.isEmpty) {
-      sb.write(": ");
-      sb.write(message);
-      if (errorCode != noErrorCode) {
-        sb.write(", errno = ");
-        sb.write(errorCode.toString());
-      }
-    } else if (errorCode != noErrorCode) {
-      sb.write(": errno = ");
-      sb.write(errorCode.toString());
-    }
-    return sb.toString();
-  }
-
   /**
     * Error message supplied by the operating system. null if no message is
     * associated with the error.
@@ -86,14 +64,35 @@
     * [noErrorCode] if there is no error code associated with the error.
     */
   final int errorCode;
+
+  /** Creates an OSError object from a message and an errorCode. */
+  const OSError([this.message = "", this.errorCode = noErrorCode]);
+
+  /** Converts an OSError object to a string representation. */
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("OS Error");
+    if (!message.isEmpty) {
+      sb..write(": ")
+        ..write(message);
+      if (errorCode != noErrorCode) {
+        sb..write(", errno = ")
+          ..write(errorCode.toString());
+      }
+    } else if (errorCode != noErrorCode) {
+      sb..write(": errno = ")
+        ..write(errorCode.toString());
+    }
+    return sb.toString();
+  }
 }
 
 
 // Object for holding a buffer and an offset.
 class _BufferAndStart {
-  _BufferAndStart(List this.buffer, int this.start);
   List buffer;
   int start;
+  _BufferAndStart(this.buffer, this.start);
 }
 
 // Ensure that the input List can be serialized through a native port.
diff --git a/sdk/lib/io/crypto.dart b/sdk/lib/io/crypto.dart
index 35bd01c..82cff5e 100644
--- a/sdk/lib/io/crypto.dart
+++ b/sdk/lib/io/crypto.dart
@@ -5,14 +5,6 @@
 part of dart.io;
 
 class _CryptoUtils {
-  static String bytesToHex(List<int> bytes) {
-    var result = new StringBuffer();
-    for (var part in bytes) {
-      result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
-    }
-    return result.toString();
-  }
-
   static const int PAD = 61; // '='
   static const int CR = 13;  // '\r'
   static const int LF = 10;  // '\n'
@@ -47,6 +39,14 @@
               -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
               -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 ];
 
+  static String bytesToHex(List<int> bytes) {
+    var result = new StringBuffer();
+    for (var part in bytes) {
+      result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
+    }
+    return result.toString();
+  }
+
   static String bytesToBase64(List<int> bytes,
                               [bool urlSafe = false,
                                bool addLineSeparator = false]) {
@@ -169,9 +169,19 @@
 // Base class encapsulating common behavior for cryptographic hash
 // functions.
 abstract class _HashBase {
-  _HashBase(int this._chunkSizeInWords,
-            int this._digestSizeInWords,
-            bool this._bigEndianWords)
+  // Hasher state.
+  final int _chunkSizeInWords;
+  final int _digestSizeInWords;
+  final bool _bigEndianWords;
+  int _lengthInBytes = 0;
+  List<int> _pendingData;
+  List<int> _currentChunk;
+  List<int> _h;
+  bool _digestCalled = false;
+
+  _HashBase(this._chunkSizeInWords,
+            this._digestSizeInWords,
+            this._bigEndianWords)
       : _pendingData = [] {
     _currentChunk = new List(_chunkSizeInWords);
     _h = new List(_digestSizeInWords);
@@ -296,16 +306,6 @@
       _pendingData.addAll(_wordToBytes(0));
     }
   }
-
-  // Hasher state.
-  final int _chunkSizeInWords;
-  final int _digestSizeInWords;
-  final bool _bigEndianWords;
-  int _lengthInBytes = 0;
-  List<int> _pendingData;
-  List<int> _currentChunk;
-  List<int> _h;
-  bool _digestCalled = false;
 }
 
 // The MD5 hasher is used to compute an MD5 message digest.
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index fee6dc9..e1fb143 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -9,6 +9,11 @@
  */
 abstract class Directory implements FileSystemEntity {
   /**
+   * Gets the path of this directory.
+   */
+  final String path;
+
+  /**
    * Creates a directory object. The path is either an absolute path,
    * or it is a relative path which is interpreted relative to the directory
    * in which the Dart VM was started.
@@ -188,9 +193,4 @@
    * Returns a human readable string for this Directory instance.
    */
   String toString();
-
-  /**
-   * Gets the path of this directory.
-   */
-  final String path;
 }
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 9cbd1b9..dd789c7 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -7,7 +7,7 @@
 class _Directory extends FileSystemEntity implements Directory {
   final String path;
 
-  _Directory(String this.path) {
+  _Directory(this.path) {
     if (path is! String) {
       throw new ArgumentError('${Error.safeToString(path)} '
                               'is not a String');
@@ -213,7 +213,7 @@
   Stream<FileSystemEntity> list({bool recursive: false,
                                  bool followLinks: true}) {
     return new _AsyncDirectoryLister(
-        FileSystemEntity._trimTrailingPathSeparators(path),
+        FileSystemEntity._ensureTrailingPathSeparators(path),
         recursive,
         followLinks).stream;
   }
@@ -223,16 +223,15 @@
       throw new ArgumentError();
     }
     return _list(
-        FileSystemEntity._trimTrailingPathSeparators(path),
+        FileSystemEntity._ensureTrailingPathSeparators(path),
         recursive,
         followLinks);
   }
 
   String toString() => "Directory: '$path'";
 
-  bool _isErrorResponse(response) {
-    return response is List && response[0] != _SUCCESS_RESPONSE;
-  }
+  bool _isErrorResponse(response) =>
+      response is List && response[0] != _SUCCESS_RESPONSE;
 
   _exceptionOrErrorFromResponse(response, String message) {
     assert(_isErrorResponse(response));
@@ -272,9 +271,7 @@
   bool closed = false;
   Completer closeCompleter = new Completer();
 
-  _AsyncDirectoryLister(String this.path,
-                        bool this.recursive,
-                        bool this.followLinks) {
+  _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) {
     controller = new StreamController(onListen: onListen,
                                       onResume: onResume,
                                       onCancel: onCancel,
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 7369640..9bba4be 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -16,8 +16,9 @@
   /// The [FileMode] for opening a file for reading a file and writing to the
   /// end of it. If the file does not exist, it will be created.
   static const APPEND = const FileMode._internal(2);
-  const FileMode._internal(int this._mode);
   final int _mode;
+
+  const FileMode._internal(this._mode);
 }
 
 /// The [FileMode] for opening a file only for reading.
@@ -560,13 +561,35 @@
 }
 
 
+/**
+ * Exception thrown when a file operation fails.
+ */
 class FileSystemException implements IOException {
+  /**
+   * Message describing the error. This does not include any detailed
+   * information form the underlying OS error. Check [osError] for
+   * that information.
+   */
   final String message;
+
+  /**
+   * The file system path on which the error occurred. Can be `null`
+   * if the exception does not relate directly to a file system path.
+   */
   final String path;
+
+  /**
+   * The underlying OS error. Can be `null` if the exception is not
+   * raised due to an OS error.
+   */
   final OSError osError;
-  const FileSystemException([String this.message = "",
-                             String this.path = "",
-                             OSError this.osError]);
+
+  /**
+   * Creates a new FileSystemException with an optional error message
+   * [message], optional file system path [path] and optional OS error
+   * [osError].
+   */
+  const FileSystemException([this.message = "", this.path = "", this.osError]);
 
   String toString() {
     StringBuffer sb = new StringBuffer();
@@ -574,16 +597,18 @@
     if (!message.isEmpty) {
       sb.write(": $message");
       if (path != null) {
-        sb.write(", path = $path");
+        sb.write(", path = '$path'");
       }
       if (osError != null) {
         sb.write(" ($osError)");
       }
     } else if (osError != null) {
-      sb.write(": osError");
+      sb.write(": $osError");
       if (path != null) {
-        sb.write(", path = $path");
+        sb.write(", path = '$path'");
       }
+    } else if (path != null) {
+      sb.write(": $path");
     }
     return sb.toString();
   }
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index fcf2f5e..c30d8ae 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -30,7 +30,7 @@
   // Block read but not yet send because stream is paused.
   List<int> _currentBlock;
 
-  _FileStream(String this._path, this._position, this._end) {
+  _FileStream(this._path, this._position, this._end) {
     _setupController();
   }
 
@@ -215,9 +215,8 @@
     return completer.future;
   }
 
-  Future<File> close() {
-    return _openFuture.then((openedFile) => openedFile.close());
-  }
+  Future<File> close() =>
+      _openFuture.then((openedFile) => openedFile.close());
 }
 
 
@@ -226,7 +225,7 @@
   final String path;
 
   // Constructor for file.
-  _File(String this.path) {
+  _File(this.path) {
     if (path is! String) {
       throw new ArgumentError('${Error.safeToString(path)} '
                               'is not a String');
@@ -473,11 +472,8 @@
     }
   }
 
-  Future<String> readAsString({Encoding encoding: UTF8}) {
-    return readAsBytes().then((bytes) {
-      return _tryDecode(bytes, encoding);
-    });
-  }
+  Future<String> readAsString({Encoding encoding: UTF8}) =>
+    readAsBytes().then((bytes) => _tryDecode(bytes, encoding));
 
   String readAsStringSync({Encoding encoding: UTF8}) {
     List<int> bytes = readAsBytesSync();
@@ -508,9 +504,8 @@
     });
   }
 
-  List<String> readAsLinesSync({Encoding encoding: UTF8}) {
-    return _decodeLines(readAsBytesSync(), encoding);
-  }
+  List<String> readAsLinesSync({Encoding encoding: UTF8}) =>
+      _decodeLines(readAsBytesSync(), encoding);
 
   Future<File> writeAsBytes(List<int> bytes,
                             {FileMode mode: FileMode.WRITE,
@@ -572,7 +567,7 @@
   bool _asyncDispatched = false;
   SendPort _fileService;
 
-  _RandomAccessFile(int this._id, String this.path);
+  _RandomAccessFile(this._id, this.path);
 
   Future<RandomAccessFile> close() {
     return _dispatch(_FILE_CLOSE, [_id], markClosed: true).then((result) {
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 0a8d230..1912d61 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -13,12 +13,12 @@
                                   FileSystemEntityType.DIRECTORY,
                                   FileSystemEntityType.LINK,
                                   FileSystemEntityType.NOT_FOUND];
-  const FileSystemEntityType._internal(int this._type);
+  final int _type;
+
+  const FileSystemEntityType._internal(this._type);
 
   static FileSystemEntityType _lookup(int type) => _typeList[type];
   String toString() => const ['FILE', 'DIRECTORY', 'LINK', 'NOT_FOUND'][_type];
-
-  final int _type;
 }
 
 /**
@@ -35,6 +35,37 @@
   static const _MODE = 4;
   static const _SIZE = 5;
 
+  /**
+   * The time of the last change to the data or metadata of the file system
+   * object.  On Windows platforms, this is instead the file creation time.
+   */
+  final DateTime changed;
+  /**
+   * The time of the last change to the data of the file system
+   * object.
+   */
+  final DateTime modified;
+  /**
+   * The time of the last access to the data of the file system
+   * object.  On Windows platforms, this may have 1 day granularity, and be
+   * out of date by an hour.
+   */
+  final DateTime accessed;
+  /**
+   * The type of the object (file, directory, or link).  If the call to
+   * stat() fails, the type of the returned object is NOT_FOUND.
+   */
+  final FileSystemEntityType type;
+  /**
+   * The mode of the file system object.  Permissions are encoded in the lower
+   * 16 bits of this number, and can be decoded using the [modeString] getter.
+   */
+  final int mode;
+  /**
+   * The size of the file system object.
+   */
+  final int size;
+
   FileStat._internal(this.changed,
                      this.modified,
                      this.accessed,
@@ -52,8 +83,12 @@
    * FileSystemEntityType.NOT_FOUND and the other fields invalid.
    */
   static FileStat statSync(String path) {
+    // Trailing path is not supported on Windows.
+    if (Platform.isWindows) {
+      path = FileSystemEntity._trimTrailingPathSeparators(path);
+    }
     var data = _statSync(path);
-    if (data is Error) throw data;
+    if (data is OSError) throw data;
     return new FileStat._internal(
         new DateTime.fromMillisecondsSinceEpoch(data[_CHANGED_TIME] * 1000),
         new DateTime.fromMillisecondsSinceEpoch(data[_MODIFIED_TIME] * 1000),
@@ -71,6 +106,10 @@
    * .type set to FileSystemEntityType.NOT_FOUND and the other fields invalid.
    */
   static Future<FileStat> stat(String path) {
+    // Trailing path is not supported on Windows.
+    if (Platform.isWindows) {
+      path = FileSystemEntity._trimTrailingPathSeparators(path);
+    }
     return _IOService.dispatch(_FILE_STAT, [path]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response,
@@ -111,42 +150,12 @@
     if ((permissions & 0x800) != 0) result.add("(suid) ");
     if ((permissions & 0x400) != 0) result.add("(guid) ");
     if ((permissions & 0x200) != 0) result.add("(sticky) ");
-    result.add(codes[(permissions >> 6) & 0x7]);
-    result.add(codes[(permissions >> 3) & 0x7]);
-    result.add(codes[permissions & 0x7]);
+    result
+        ..add(codes[(permissions >> 6) & 0x7])
+        ..add(codes[(permissions >> 3) & 0x7])
+        ..add(codes[permissions & 0x7]);
     return result.join();
   }
-
-  /**
-   * The time of the last change to the data or metadata of the file system
-   * object.  On Windows platforms, this is instead the file creation time.
-   */
-  final DateTime changed;
-  /**
-   * The time of the last change to the data of the file system
-   * object.
-   */
-  final DateTime modified;
-  /**
-   * The time of the last access to the data of the file system
-   * object.  On Windows platforms, this may have 1 day granularity, and be
-   * out of date by an hour.
-   */
-  final DateTime accessed;
-  /**
-   * The type of the object (file, directory, or link).  If the call to
-   * stat() fails, the type of the returned object is NOT_FOUND.
-   */
-  final FileSystemEntityType type;
-  /**
-   * The mode of the file system object.  Permissions are encoded in the lower
-   * 16 bits of this number, and can be decoded using the [modeString] getter.
-   */
-  final int mode;
-  /**
-   * The size of the file system object.
-   */
-  final int size;
 }
 
 
@@ -621,6 +630,22 @@
     }
     return path;
   }
+
+  static String _ensureTrailingPathSeparators(String path) {
+    // Don't handle argument errors here.
+    if (path is! String) return path;
+    if (path.isEmpty) path = '.';
+    if (Platform.operatingSystem == 'windows') {
+      while (!path.endsWith(Platform.pathSeparator) && !path.endsWith('/')) {
+        path = "$path${Platform.pathSeparator}";
+      }
+    } else {
+      while (!path.endsWith(Platform.pathSeparator)) {
+        path = "$path${Platform.pathSeparator}";
+      }
+    }
+    return path;
+  }
 }
 
 
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 8598037..228aeae 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -83,6 +83,27 @@
  */
 abstract class HttpServer implements Stream<HttpRequest> {
   /**
+   * Set and get the default value of the `Server` header for all responses
+   * generated by this [HttpServer]. The default value is
+   * `Dart/<version> (dart:io)`.
+   *
+   * If the serverHeader is set to `null`, no default `Server` header will be
+   * added to each response.
+   */
+  String serverHeader;
+
+  /**
+   * Get or set the timeout used for idle keep-alive connections. If no further
+   * request is seen within [idleTimeout] after the previous request was
+   * completed, the connection is dropped.
+   *
+   * Default is 120 seconds.
+   *
+   * To disable, set [idleTimeout] to `null`.
+   */
+  Duration idleTimeout;
+
+  /**
    * Starts listening for HTTP requests on the specified [address] and
    * [port].
    *
@@ -205,27 +226,6 @@
    * current connections handled by the server.
    */
   HttpConnectionsInfo connectionsInfo();
-
-  /**
-   * Set and get the default value of the `Server` header for all responses
-   * generated by this [HttpServer]. The default value is
-   * `Dart/<version> (dart:io)`.
-   *
-   * If the serverHeader is set to `null`, no default `Server` header will be
-   * added to each response.
-   */
-  String serverHeader;
-
-  /**
-   * Get or set the timeout used for idle keep-alive connections. If no further
-   * request is seen within [idleTimeout] after the previous request was
-   * completed, the connection is droped.
-   *
-   * Default is 120 seconds.
-   *
-   * To disable, set [idleTimeout] to `null`.
-   */
-  Duration idleTimeout;
 }
 
 
@@ -372,6 +372,59 @@
                                         USER_AGENT];
 
   /**
+   * Gets and sets the date. The value of this property will
+   * reflect the 'date' header.
+   */
+  DateTime date;
+
+  /**
+   * Gets and sets the expiry date. The value of this property will
+   * reflect the 'expires' header.
+   */
+  DateTime expires;
+
+  /**
+   * Gets and sets the "if-modified-since" date. The value of this property will
+   * reflect the "if-modified-since" header.
+   */
+  DateTime ifModifiedSince;
+
+  /**
+   * Gets and sets the host part of the 'host' header for the
+   * connection.
+   */
+  String host;
+
+  /**
+   * Gets and sets the port part of the 'host' header for the
+   * connection.
+   */
+  int port;
+
+  /**
+   * Gets and sets the content type. Note that the content type in the
+   * header will only be updated if this field is set
+   * directly. Mutating the returned current value will have no
+   * effect.
+   */
+  ContentType contentType;
+
+  /**
+   * Gets and sets the content length header value.
+   */
+  int contentLength;
+
+  /**
+   * Gets and sets the persistent connection header value.
+   */
+  bool persistentConnection;
+
+  /**
+   * Gets and sets the chunked transfer encoding header value.
+   */
+  bool chunkedTransferEncoding;
+
+  /**
    * Returns the list of values for the header named [name]. If there
    * is no header with the provided name, [:null:] will be returned.
    */
@@ -431,59 +484,6 @@
    * 'set-cookie' header has folding disabled by default.
    */
   void noFolding(String name);
-
-  /**
-   * Gets and sets the date. The value of this property will
-   * reflect the 'date' header.
-   */
-  DateTime date;
-
-  /**
-   * Gets and sets the expiry date. The value of this property will
-   * reflect the 'expires' header.
-   */
-  DateTime expires;
-
-  /**
-   * Gets and sets the "if-modified-since" date. The value of this property will
-   * reflect the "if-modified-since" header.
-   */
-  DateTime ifModifiedSince;
-
-  /**
-   * Gets and sets the host part of the 'host' header for the
-   * connection.
-   */
-  String host;
-
-  /**
-   * Gets and sets the port part of the 'host' header for the
-   * connection.
-   */
-  int port;
-
-  /**
-   * Gets and sets the content type. Note that the content type in the
-   * header will only be updated if this field is set
-   * directly. Mutating the returned current value will have no
-   * effect.
-   */
-  ContentType contentType;
-
-  /**
-   * Gets and sets the content length header value.
-   */
-  int contentLength;
-
-  /**
-   * Gets and sets the persistent connection header value.
-   */
-  bool persistentConnection;
-
-  /**
-   * Gets and sets the chunked transfer encoding header value.
-   */
-  bool chunkedTransferEncoding;
 }
 
 
@@ -647,19 +647,6 @@
  */
 abstract class Cookie {
   /**
-   * Creates a new cookie optionally setting the name and value.
-   */
-  factory Cookie([String name, String value]) => new _Cookie(name, value);
-
-  /**
-   * Creates a new cookie by parsing a header value from a 'set-cookie'
-   * header.
-   */
-  factory Cookie.fromSetCookieValue(String value) {
-    return new _Cookie.fromSetCookieValue(value);
-  }
-
-  /**
    * Gets and sets the name.
    */
   String name;
@@ -701,6 +688,19 @@
   bool httpOnly;
 
   /**
+   * Creates a new cookie optionally setting the name and value.
+   */
+  factory Cookie([String name, String value]) => new _Cookie(name, value);
+
+  /**
+   * Creates a new cookie by parsing a header value from a 'set-cookie'
+   * header.
+   */
+  factory Cookie.fromSetCookieValue(String value) {
+    return new _Cookie.fromSetCookieValue(value);
+  }
+
+  /**
    * Returns the formatted string representation of the cookie. The
    * string representation can be used for for setting the Cookie or
    * 'set-cookie' headers
@@ -738,16 +738,16 @@
  *     HttpServer.bind(HOST, PORT).then((_server) {
  *       _server.listen((HttpRequest request) {
  *         switch (request.method) {
- *           case 'GET': 
+ *           case 'GET':
  *             handleGetRequest(request);
  *             break;
- *           case 'POST': 
+ *           case 'POST':
  *             ...
  *         }
  *       },
  *       onError: handleError);    // listen() failed.
  *     }).catchError(handleError);
- *   
+ *
  * Listen to the HttpRequest stream to handle the
  * data and be notified once the entire body is received.
  * An HttpRequest object contains an [HttpResponse] object,
@@ -790,6 +790,20 @@
   Uri get uri;
 
   /**
+   * The requested URI for the request (read-only).
+   *
+   * The returend URI is reconstructed by using http-header fields, to access
+   * otherwise lost information, e.g. host and scheme.
+   *
+   * To reconstruct the scheme, first 'X-Forwarded-Proto' is checked, and then
+   * falling back to server type.
+   *
+   * To reconstruct the host, fisrt 'X-Forwarded-Host' is checked, then 'Host'
+   * and finally calling back to server.
+   */
+  Uri get requestedUri;
+
+  /**
    * The request headers (read-only).
    */
   HttpHeaders get headers;
@@ -824,7 +838,7 @@
   HttpSession get session;
 
   /**
-   * The HTTP protocol version used in the request, 
+   * The HTTP protocol version used in the request,
    * either "1.0" or "1.1" (read-only).
    */
   String get protocolVersion;
@@ -1330,51 +1344,12 @@
  */
 abstract class HttpClientRequest implements IOSink {
   /**
-   * The method of the request.
-   */
-  String get method;
-
-  /**
-   * The uri of the request.
-   */
-  Uri get uri;
-
-  /**
-   * Gets and sets the content length of the request. If the size of
-   * the request is not known in advance set content length to -1,
-   * which is also the default.
-   */
-  int contentLength;
-
-  /**
-   * Returns the request headers.
-   */
-  HttpHeaders get headers;
-
-  /**
-   * Cookies to present to the server (in the 'cookie' header).
-   */
-  List<Cookie> get cookies;
-
-  /**
    * Gets and sets the requested persistent connection state.
    * The default value is [:true:].
    */
   bool persistentConnection;
 
   /**
-   * A [HttpClientResponse] future that will complete once the response is
-   * available. If an error occurs before the response is available, this
-   * future will complete with an error.
-   */
-  Future<HttpClientResponse> get done;
-
-  /**
-   * Close the request for input. Returns the value of [done].
-   */
-  Future<HttpClientResponse> close();
-
-  /**
    * Set this property to [:true:] if this request should
    * automatically follow redirects. The default is [:true:].
    *
@@ -1404,6 +1379,45 @@
   int maxRedirects;
 
   /**
+   * The method of the request.
+   */
+  String get method;
+
+  /**
+   * The uri of the request.
+   */
+  Uri get uri;
+
+  /**
+   * Gets and sets the content length of the request. If the size of
+   * the request is not known in advance set content length to -1,
+   * which is also the default.
+   */
+  int contentLength;
+
+  /**
+   * Returns the request headers.
+   */
+  HttpHeaders get headers;
+
+  /**
+   * Cookies to present to the server (in the 'cookie' header).
+   */
+  List<Cookie> get cookies;
+
+  /**
+   * A [HttpClientResponse] future that will complete once the response is
+   * available. If an error occurs before the response is available, this
+   * future will complete with an error.
+   */
+  Future<HttpClientResponse> get done;
+
+  /**
+   * Close the request for input. Returns the value of [done].
+   */
+  Future<HttpClientResponse> close();
+
+  /**
    * Get information about the client connection. Returns [null] if the socket
    * is not available.
    */
@@ -1584,9 +1598,9 @@
   const HttpException(String this.message, {Uri this.uri});
 
   String toString() {
-    var b = new StringBuffer();
-    b.write('HttpException: ');
-    b.write(message);
+    var b = new StringBuffer()
+        ..write('HttpException: ')
+        ..write(message);
     if (uri != null) {
       b.write(', uri = $uri');
     }
@@ -1599,8 +1613,7 @@
   final String message;
   final List<RedirectInfo> redirects;
 
-  const RedirectException(String this.message,
-                          List<RedirectInfo> this.redirects);
+  const RedirectException(this.message, this.redirects);
 
   String toString() => "RedirectException: $message";
 
diff --git a/sdk/lib/io/http_date.dart b/sdk/lib/io/http_date.dart
index 1fdd609..9720426 100644
--- a/sdk/lib/io/http_date.dart
+++ b/sdk/lib/io/http_date.dart
@@ -43,21 +43,21 @@
                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
 
     DateTime d = date.toUtc();
-    StringBuffer sb = new StringBuffer();
-    sb.write(wkday[d.weekday - 1]);
-    sb.write(", ");
-    sb.write(d.day.toString());
-    sb.write(" ");
-    sb.write(month[d.month - 1]);
-    sb.write(" ");
-    sb.write(d.year.toString());
-    sb.write(d.hour < 9 ? " 0" : " ");
-    sb.write(d.hour.toString());
-    sb.write(d.minute < 9 ? ":0" : ":");
-    sb.write(d.minute.toString());
-    sb.write(d.second < 9 ? ":0" : ":");
-    sb.write(d.second.toString());
-    sb.write(" GMT");
+    StringBuffer sb = new StringBuffer()
+        ..write(wkday[d.weekday - 1])
+        ..write(", ")
+        ..write(d.day.toString())
+        ..write(" ")
+        ..write(month[d.month - 1])
+        ..write(" ")
+        ..write(d.year.toString())
+        ..write(d.hour < 9 ? " 0" : " ")
+        ..write(d.hour.toString())
+        ..write(d.minute < 9 ? ":0" : ":")
+        ..write(d.minute.toString())
+        ..write(d.second < 9 ? ":0" : ":")
+        ..write(d.second.toString())
+        ..write(" GMT");
     return sb.toString();
   }
 
@@ -215,9 +215,7 @@
       throw new HttpException("Invalid cookie date $date");
     }
 
-    bool isEnd() {
-      return position == date.length;
-    }
+    bool isEnd() => position == date.length;
 
     bool isDelimiter(String s) {
       int char = s.codeUnitAt(0);
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index cff9d37..1d7e9b5 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -17,17 +17,14 @@
   String _host;
   int _port;
 
-  _HttpHeaders(String this.protocolVersion)
+  _HttpHeaders(this.protocolVersion)
       : _headers = new HashMap<String, List<String>>() {
     if (protocolVersion == "1.0") {
       _persistentConnection = false;
     }
   }
 
-  List<String> operator[](String name) {
-    name = name.toLowerCase();
-    return _headers[name];
-  }
+  List<String> operator[](String name) => _headers[name.toLowerCase()];
 
   String value(String name) {
     name = name.toLowerCase();
@@ -46,9 +43,7 @@
 
   void _addAll(String name, value) {
     if (value is List) {
-      for (int i = 0; i < value.length; i++) {
-        _add(name, value[i]);
-      }
+      value.forEach((v) => _add(name, v));
     } else {
       _add(name, value);
     }
@@ -252,82 +247,99 @@
   // [name] must be a lower-case version of the name.
   void _add(String name, value) {
     // TODO(sgjesse): Add immutable state throw HttpException is immutable.
-    if (name == HttpHeaders.CONTENT_LENGTH) {
-      if (value is int) {
-        contentLength = value;
-      } else if (value is String) {
-        contentLength = int.parse(value);
-      } else {
-        throw new HttpException("Unexpected type for header named $name");
-      }
-    } else if (name == HttpHeaders.TRANSFER_ENCODING) {
-      if (value == "chunked") {
-        chunkedTransferEncoding = true;
-      } else {
-        _addValue(name, value);
-      }
-    } else if (name == HttpHeaders.DATE) {
-      if (value is DateTime) {
-        date = value;
-      } else if (value is String) {
-        _set(HttpHeaders.DATE, value);
-      } else {
-        throw new HttpException("Unexpected type for header named $name");
-      }
-    } else if (name == HttpHeaders.EXPIRES) {
-      if (value is DateTime) {
-        expires = value;
-      } else if (value is String) {
-        _set(HttpHeaders.EXPIRES, value);
-      } else {
-        throw new HttpException("Unexpected type for header named $name");
-      }
-    } else if (name == HttpHeaders.IF_MODIFIED_SINCE) {
-      if (value is DateTime) {
-        ifModifiedSince = value;
-      } else if (value is String) {
-        _set(HttpHeaders.IF_MODIFIED_SINCE, value);
-      } else {
-        throw new HttpException("Unexpected type for header named $name");
-      }
-    } else if (name == HttpHeaders.HOST) {
-      if (value is String) {
-        int pos = value.indexOf(":");
-        if (pos == -1) {
-          _host = value;
-          _port = HttpClient.DEFAULT_HTTP_PORT;
+    switch (name) {
+      case  HttpHeaders.CONTENT_LENGTH:
+        if (value is int) {
+          contentLength = value;
+        } else if (value is String) {
+          contentLength = int.parse(value);
         } else {
-          if (pos > 0) {
-            _host = value.substring(0, pos);
-          } else {
-            _host = null;
-          }
-          if (pos + 1 == value.length) {
+          throw new HttpException("Unexpected type for header named $name");
+        }
+        break;
+
+      case HttpHeaders.TRANSFER_ENCODING:
+        if (value == "chunked") {
+          chunkedTransferEncoding = true;
+        } else {
+          _addValue(name, value);
+        }
+        break;
+
+      case HttpHeaders.DATE:
+        if (value is DateTime) {
+          date = value;
+        } else if (value is String) {
+          _set(HttpHeaders.DATE, value);
+        } else {
+          throw new HttpException("Unexpected type for header named $name");
+        }
+        break;
+
+      case HttpHeaders.EXPIRES:
+        if (value is DateTime) {
+          expires = value;
+        } else if (value is String) {
+          _set(HttpHeaders.EXPIRES, value);
+        } else {
+          throw new HttpException("Unexpected type for header named $name");
+        }
+        break;
+
+      case HttpHeaders.IF_MODIFIED_SINCE:
+        if (value is DateTime) {
+          ifModifiedSince = value;
+        } else if (value is String) {
+          _set(HttpHeaders.IF_MODIFIED_SINCE, value);
+        } else {
+          throw new HttpException("Unexpected type for header named $name");
+        }
+        break;
+
+      case HttpHeaders.HOST:
+        if (value is String) {
+          int pos = value.indexOf(":");
+          if (pos == -1) {
+            _host = value;
             _port = HttpClient.DEFAULT_HTTP_PORT;
           } else {
-            try {
-              _port = int.parse(value.substring(pos + 1));
-            } on FormatException catch (e) {
-              _port = null;
+            if (pos > 0) {
+              _host = value.substring(0, pos);
+            } else {
+              _host = null;
+            }
+            if (pos + 1 == value.length) {
+              _port = HttpClient.DEFAULT_HTTP_PORT;
+            } else {
+              try {
+                _port = int.parse(value.substring(pos + 1));
+              } on FormatException catch (e) {
+                _port = null;
+              }
             }
           }
+          _set(HttpHeaders.HOST, value);
+        } else {
+          throw new HttpException("Unexpected type for header named $name");
         }
-        _set(HttpHeaders.HOST, value);
-      } else {
-        throw new HttpException("Unexpected type for header named $name");
-      }
-    } else if (name == HttpHeaders.CONNECTION) {
-      var lowerCaseValue = value.toLowerCase();
-      if (lowerCaseValue == 'close') {
-        _persistentConnection = false;
-      } else if (lowerCaseValue == 'keep-alive') {
-        _persistentConnection = true;
-      }
-      _addValue(name, value);
-    } else if (name == HttpHeaders.CONTENT_TYPE) {
-      _set(HttpHeaders.CONTENT_TYPE, value);
-    } else {
-      _addValue(name, value);
+        break;
+
+      case HttpHeaders.CONNECTION:
+        var lowerCaseValue = value.toLowerCase();
+        if (lowerCaseValue == 'close') {
+          _persistentConnection = false;
+        } else if (lowerCaseValue == 'keep-alive') {
+          _persistentConnection = true;
+        }
+        _addValue(name, value);
+        break;
+
+      case HttpHeaders.CONTENT_TYPE:
+        _set(HttpHeaders.CONTENT_TYPE, value);
+        break;
+
+      default:
+        _addValue(name, value);
     }
   }
 
@@ -409,17 +421,14 @@
   String toString() {
     StringBuffer sb = new StringBuffer();
     _headers.forEach((String name, List<String> values) {
-      sb.write(name);
-      sb.write(": ");
+      sb..write(name)..write(": ");
       bool fold = _foldHeader(name);
       for (int i = 0; i < values.length; i++) {
         if (i > 0) {
           if (fold) {
             sb.write(", ");
           } else {
-            sb.write("\n");
-            sb.write(name);
-            sb.write(": ");
+            sb..write("\n")..write(name)..write(": ");
           }
         }
         sb.write(values[i]);
@@ -533,10 +542,7 @@
     sb.write(_value);
     if (parameters != null && parameters.length > 0) {
       _parameters.forEach((String name, String value) {
-        sb.write("; ");
-        sb.write(name);
-        sb.write("=");
-        sb.write(value);
+        sb..write("; ")..write(name)..write("=")..write(value);
       });
     }
     return sb.toString();
@@ -694,7 +700,16 @@
 
 
 class _Cookie implements Cookie {
-  _Cookie([String this.name, String this.value]);
+  String name;
+  String value;
+  DateTime expires;
+  int maxAge;
+  String domain;
+  String path;
+  bool httpOnly = false;
+  bool secure = false;
+
+  _Cookie([this.name, this.value]);
 
   _Cookie.fromSetCookieValue(String value) {
     // Parse the 'set-cookie' header value.
@@ -789,38 +804,23 @@
 
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.write(name);
-    sb.write("=");
-    sb.write(value);
+    sb..write(name)..write("=")..write(value);
     if (expires != null) {
-      sb.write("; Expires=");
-      sb.write(HttpDate.format(expires));
+      sb..write("; Expires=")..write(HttpDate.format(expires));
     }
     if (maxAge != null) {
-      sb.write("; Max-Age=");
-      sb.write(maxAge);
+      sb..write("; Max-Age=")..write(maxAge);
     }
     if (domain != null) {
-      sb.write("; Domain=");
-      sb.write(domain);
+      sb..write("; Domain=")..write(domain);
     }
     if (path != null) {
-      sb.write("; Path=");
-      sb.write(path);
+      sb..write("; Path=")..write(path);
     }
     if (secure) sb.write("; Secure");
     if (httpOnly) sb.write("; HttpOnly");
     return sb.toString();
   }
-
-  String name;
-  String value;
-  DateTime expires;
-  int maxAge;
-  String domain;
-  String path;
-  bool httpOnly = false;
-  bool secure = false;
 }
 
 
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 4c6e74b..2f852dc 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -33,10 +33,7 @@
   // codings.
   int get transferLength => _transferLength;
 
-  _HttpIncoming(_HttpHeaders this.headers,
-                int this._transferLength,
-                Stream<List<int>> this._stream) {
-  }
+  _HttpIncoming(this.headers, this._transferLength, this._stream);
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
                                        {Function onError,
@@ -67,7 +64,7 @@
   final _HttpIncoming _incoming;
   List<Cookie> _cookies;
 
-  _HttpInboundMessage(_HttpIncoming this._incoming);
+  _HttpInboundMessage(this._incoming);
 
   List<Cookie> get cookies {
     if (_cookies != null) return _cookies;
@@ -90,14 +87,14 @@
 
   _HttpSession _session;
 
-  _HttpRequest(_HttpResponse this.response,
-               _HttpIncoming _incoming,
-               _HttpServer this._httpServer,
-               _HttpConnection this._httpConnection)
-      : super(_incoming) {
+  Uri _requestedUri;
+
+  _HttpRequest(this.response, _HttpIncoming _incoming, this._httpServer,
+               this._httpConnection) : super(_incoming) {
     if (headers.protocolVersion == "1.1") {
-      response.headers.chunkedTransferEncoding = true;
-      response.headers.persistentConnection = headers.persistentConnection;
+      response.headers
+          ..chunkedTransferEncoding = true
+          ..persistentConnection = headers.persistentConnection;
     }
 
     if (_httpServer._sessionManagerInstance != null) {
@@ -127,6 +124,27 @@
 
   Uri get uri => _incoming.uri;
 
+  Uri get requestedUri {
+    if (_requestedUri == null) {
+      var proto = headers['x-forwarded-proto'];
+      var scheme = proto != null ? proto.first :
+          _httpConnection._socket is SecureSocket ? "https" : "http";
+      var host = headers['x-forwarded-host'];
+      if (host != null) {
+        host = host.first;
+      } else {
+        host = headers['host'];
+        if (host != null) {
+          host = host.first;
+        } else {
+          host = "${_httpServer.address.host}:${_httpServer.port}";
+        }
+      }
+      _requestedUri = Uri.parse("$scheme://$host$uri");
+    }
+    return _requestedUri;
+  }
+
   String get method => _incoming.method;
 
   HttpSession get session {
@@ -166,10 +184,8 @@
 
   List<Cookie> _cookies;
 
-  _HttpClientResponse(_HttpIncoming _incoming,
-                      _HttpClientRequest this._httpRequest,
-                      _HttpClient this._httpClient)
-      : super(_incoming) {
+  _HttpClientResponse(_HttpIncoming _incoming, this._httpRequest,
+                      this._httpClient) : super(_incoming) {
     // Set uri for potential exceptions.
     _incoming.uri = _httpRequest.uri;
   }
@@ -178,6 +194,7 @@
   String get reasonPhrase => _incoming.reasonPhrase;
 
   X509Certificate get certificate {
+    // The peerCertificate isn't on a plain socket, so cast to dynamic.
     var socket = _httpRequest._httpClientConnection._socket;
     return socket.peerCertificate;
   }
@@ -234,10 +251,9 @@
     }
     return _httpClient._openUrlFromRequest(method, url, _httpRequest)
         .then((request) {
-          request._responseRedirects.addAll(this.redirects);
-          request._responseRedirects.add(new _RedirectInfo(statusCode,
-                                                           method,
-                                                           url));
+          request._responseRedirects
+              ..addAll(this.redirects)
+              ..add(new _RedirectInfo(statusCode, method, url));
           return request.close();
         });
   }
@@ -289,19 +305,13 @@
     }
 
     List<String> authChallenge() {
-      if (proxyAuth) {
-        return headers[HttpHeaders.PROXY_AUTHENTICATE];
-      } else {
-        return headers[HttpHeaders.WWW_AUTHENTICATE];
-      }
+      return proxyAuth ? headers[HttpHeaders.PROXY_AUTHENTICATE]
+                       : headers[HttpHeaders.WWW_AUTHENTICATE];
     }
 
     _Credentials findCredentials(_AuthenticationScheme scheme) {
-      if (proxyAuth) {
-        return  _httpClient._findProxyCredentials(_httpRequest._proxy, scheme);
-      } else {
-        return _httpClient._findCredentials(_httpRequest.uri, scheme);
-      }
+      return proxyAuth ? _httpClient._findProxyCredentials(_httpRequest._proxy, scheme)
+                       : _httpClient._findCredentials(_httpRequest.uri, scheme);
     }
 
     void removeCredentials(_Credentials cr) {
@@ -359,10 +369,10 @@
           // If the nonce is not set then this is the first authenticate
           // response for these credentials. Set up authentication state.
           if (cr.nonce == null) {
-            cr.nonce = header.parameters["nonce"];
-            cr.algorithm = "MD5";
-            cr.qop = header.parameters["qop"];
-            cr.nonceCount = 0;
+            cr..nonce = header.parameters["nonce"]
+              ..algorithm = "MD5"
+              ..qop = header.parameters["qop"]
+              ..nonceCount = 0;
           }
           // Credentials where found, prepare for retrying the request.
           return retry();
@@ -411,7 +421,7 @@
 
   final _HttpHeaders headers;
 
-  _HttpOutboundMessage(Uri this._uri,
+  _HttpOutboundMessage(this._uri,
                        String protocolVersion,
                        _HttpOutgoing outgoing)
       : _outgoing = outgoing,
@@ -445,18 +455,22 @@
   }
 
   void write(Object obj) {
+    if (!_headersWritten) _dataSink.encoding = encoding;
     _dataSink.write(obj);
   }
 
   void writeAll(Iterable objects, [String separator = ""]) {
+    if (!_headersWritten) _dataSink.encoding = encoding;
     _dataSink.writeAll(objects, separator);
   }
 
   void writeln([Object obj = ""]) {
+    if (!_headersWritten) _dataSink.encoding = encoding;
     _dataSink.writeln(obj);
   }
 
   void writeCharCode(int charCode) {
+    if (!_headersWritten) _dataSink.encoding = encoding;
     _dataSink.writeCharCode(charCode);
   }
 
@@ -465,21 +479,14 @@
     _dataSink.add(data);
   }
 
-  void addError(error, [StackTrace stackTrace]) {
-    _dataSink.addError(error, stackTrace);
-  }
+  void addError(error, [StackTrace stackTrace]) =>
+      _dataSink.addError(error, stackTrace);
 
-  Future<T> addStream(Stream<List<int>> stream) {
-    return _dataSink.addStream(stream);
-  }
+  Future<T> addStream(Stream<List<int>> stream) => _dataSink.addStream(stream);
 
-  Future flush() {
-    return _dataSink.flush();
-  }
+  Future flush() => _dataSink.flush();
 
-  Future close() {
-    return _dataSink.close();
-  }
+  Future close() => _dataSink.close();
 
   Future<T> get done => _dataSink.done;
 
@@ -575,7 +582,7 @@
   Completer _completer;
   bool _socketError = false;
 
-  _HttpOutboundConsumer(_HttpOutboundMessage this._outbound);
+  _HttpOutboundConsumer(this._outbound);
 
   void _cancel() {
     if (_subscription != null) {
@@ -813,17 +820,18 @@
       bool found = false;
       for (int i = 0; i < cookies.length; i++) {
         if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
-          cookies[i].value = session.id;
-          cookies[i].httpOnly = true;
-          cookies[i].path = "/";
+          cookies[i]
+              ..value = session.id
+              ..httpOnly = true
+              ..path = "/";
           found = true;
         }
       }
       if (!found) {
         var cookie = new Cookie(_DART_SESSION_ID, session.id);
-        cookie.httpOnly = true;
-        cookie.path = "/";
-        cookies.add(cookie);
+        cookies.add(cookie
+            ..httpOnly = true
+            ..path = "/");
       }
     }
     // Add all the cookies set to the headers.
@@ -923,12 +931,8 @@
 
   List<RedirectInfo> _responseRedirects = [];
 
-  _HttpClientRequest(_HttpOutgoing outgoing,
-                     Uri uri,
-                     String this.method,
-                     _Proxy this._proxy,
-                     _HttpClient this._httpClient,
-                     _HttpClientConnection this._httpClientConnection)
+  _HttpClientRequest(_HttpOutgoing outgoing, Uri uri, this.method, this._proxy,
+                     this._httpClient, this._httpClientConnection)
       : super(uri, "1.1", outgoing),
         uri = uri {
     // GET and HEAD have 'content-length: 0' by default.
@@ -968,15 +972,12 @@
   HttpConnectionInfo get connectionInfo => _httpClientConnection.connectionInfo;
 
   void _onIncoming(_HttpIncoming incoming) {
-    var response = new _HttpClientResponse(incoming,
-                                           this,
-                                          _httpClient);
+    var response = new _HttpClientResponse(incoming, this, _httpClient);
     Future<HttpClientResponse> future;
     if (followRedirects && response.isRedirect) {
       if (response.redirects.length < maxRedirects) {
         // Redirect and drain response.
-        future = response.drain()
-          .then((_) => response.redirect());
+        future = response.drain().then((_) => response.redirect());
       } else {
         // End with exception, too many redirects.
         future = response.drain()
@@ -1062,9 +1063,7 @@
       StringBuffer sb = new StringBuffer();
       for (int i = 0; i < cookies.length; i++) {
         if (i > 0) sb.write("; ");
-        sb.write(cookies[i].name);
-        sb.write("=");
-        sb.write(cookies[i].value);
+        sb..write(cookies[i].name)..write("=")..write(cookies[i].value);
       }
       headers.add(HttpHeaders.COOKIE, sb.toString());
     }
@@ -1159,7 +1158,7 @@
 
   EventSink<List<int>> _outSink;
 
-  _ContentLengthValidator(int this.expectedContentLength, Uri this.uri);
+  _ContentLengthValidator(this.expectedContentLength, this.uri);
 
   Stream<List<int>> bind(Stream<List<int>> stream) {
     return new Stream.eventTransformed(
@@ -1210,7 +1209,7 @@
   final Completer _doneCompleter = new Completer();
   final Socket socket;
 
-  _HttpOutgoing(Socket this.socket);
+  _HttpOutgoing(this.socket);
 
   Future addStream(Stream<List<int>> stream) {
     return socket.addStream(stream)
@@ -1244,9 +1243,7 @@
   Completer<_HttpIncoming> _nextResponseCompleter;
   Future _streamFuture;
 
-  _HttpClientConnection(String this.key,
-                        Socket this._socket,
-                        _HttpClient this._httpClient,
+  _HttpClientConnection(this.key, this._socket, this._httpClient,
                         [this._proxyTunnel = false])
       : _httpParser = new _HttpParser.responseParser() {
     _socket.pipe(_httpParser);
@@ -1302,9 +1299,10 @@
                                          proxy,
                                          _httpClient,
                                          this);
-    request.headers.host = uri.host;
-    request.headers.port = port;
-    request.headers._add(HttpHeaders.ACCEPT_ENCODING, "gzip");
+    request.headers
+        ..host = uri.host
+        ..port = port
+        .._add(HttpHeaders.ACCEPT_ENCODING, "gzip");
     if (_httpClient.userAgent != null) {
       request.headers._add('user-agent', _httpClient.userAgent);
     }
@@ -1480,9 +1478,10 @@
 }
 
 class _ConnnectionInfo {
-  _ConnnectionInfo(_HttpClientConnection this.connection, _Proxy this.proxy);
   final _HttpClientConnection connection;
   final _Proxy proxy;
+
+  _ConnnectionInfo(this.connection, this.proxy);
 }
 
 
@@ -1586,9 +1585,8 @@
     _authenticate = f;
   }
 
-  void addCredentials(Uri url, String realm, HttpClientCredentials cr) {
-    _credentials.add(new _SiteCredentials(url, realm, cr));
-  }
+  void addCredentials(Uri url, String realm, HttpClientCredentials cr) =>
+      _credentials.add(new _SiteCredentials(url, realm, cr));
 
   set authenticateProxy(
       Future<bool> f(String host, int port, String scheme, String realm)) {
@@ -1598,9 +1596,8 @@
   void addProxyCredentials(String host,
                            int port,
                            String realm,
-                           HttpClientCredentials cr) {
-    _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr));
-  }
+                           HttpClientCredentials cr) =>
+      _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr));
 
   set findProxy(String f(Uri uri)) => _findProxy = f;
 
@@ -1660,19 +1657,21 @@
     // construct a full URI from the previous one.
     Uri resolved = previous.uri.resolveUri(uri);
     return openUrl(method, resolved).then((_HttpClientRequest request) {
-          // Only follow redirects if initial request did.
-          request.followRedirects = previous.followRedirects;
-          // Allow same number of redirects.
-          request.maxRedirects = previous.maxRedirects;
+
+          request
+              // Only follow redirects if initial request did.
+              ..followRedirects = previous.followRedirects
+              // Allow same number of redirects.
+              ..maxRedirects = previous.maxRedirects;
           // Copy headers.
           for (var header in previous.headers._headers.keys) {
             if (request.headers[header] == null) {
               request.headers.set(header, previous.headers[header]);
             }
           }
-          request.headers.chunkedTransferEncoding = false;
-          request.contentLength = 0;
-          return request;
+          return request
+              ..headers.chunkedTransferEncoding = false
+              ..contentLength = 0;
         });
   }
 
@@ -1906,7 +1905,7 @@
 
   Future _streamFuture;
 
-  _HttpConnection(Socket this._socket, _HttpServer this._httpServer)
+  _HttpConnection(this._socket, this._httpServer)
       : _httpParser = new _HttpParser.requestParser() {
     _startTimeout();
     _socket.pipe(_httpParser);
@@ -2039,8 +2038,7 @@
                                                     onCancel: close);
   }
 
-  _HttpServer.listenOn(ServerSocket this._serverSocket)
-      : _closeServer = false {
+  _HttpServer.listenOn(this._serverSocket) : _closeServer = false {
     _controller = new StreamController<HttpRequest>(sync: true,
                                                     onCancel: close);
   }
@@ -2115,9 +2113,7 @@
     _sessionManager.sessionTimeout = timeout;
   }
 
-  void _handleRequest(HttpRequest request) {
-    _controller.add(request);
-  }
+  void _handleRequest(HttpRequest request) => _controller.add(request);
 
   void _handleError(error) {
     if (!closed) _controller.addError(error);
@@ -2237,37 +2233,37 @@
 
 
 class _Proxy {
-  const _Proxy(
-      this.host, this.port, this.username, this.password) : isDirect = false;
-  const _Proxy.direct() : host = null, port = null,
-                          username = null, password = null, isDirect = true;
-
-  bool get isAuthenticated => username != null;
-
   final String host;
   final int port;
   final String username;
   final String password;
   final bool isDirect;
+
+  const _Proxy(this.host, this.port, this.username, this.password)
+      : isDirect = false;
+  const _Proxy.direct() : host = null, port = null,
+                          username = null, password = null, isDirect = true;
+
+  bool get isAuthenticated => username != null;
 }
 
 
 class _HttpConnectionInfo implements HttpConnectionInfo {
+  InternetAddress remoteAddress;
+  int remotePort;
+  int localPort;
+
   static _HttpConnectionInfo create(Socket socket) {
     if (socket == null) return null;
     try {
       _HttpConnectionInfo info = new _HttpConnectionInfo();
-      info.remoteAddress = socket.remoteAddress;
-      info.remotePort = socket.remotePort;
-      info.localPort = socket.port;
-      return info;
+      return info
+          ..remoteAddress = socket.remoteAddress
+          ..remotePort = socket.remotePort
+          ..localPort = socket.port;
     } catch (e) { }
     return null;
   }
-
-  InternetAddress remoteAddress;
-  int remotePort;
-  int localPort;
 }
 
 
@@ -2335,6 +2331,8 @@
 
 
 class _AuthenticationScheme {
+  final int _scheme;
+
   static const UNKNOWN = const _AuthenticationScheme(-1);
   static const BASIC = const _AuthenticationScheme(0);
   static const DIGEST = const _AuthenticationScheme(1);
@@ -2352,8 +2350,6 @@
     if (this == DIGEST) return "Digest";
     return "Unknown";
   }
-
-  final int _scheme;
 }
 
 
@@ -2378,12 +2374,12 @@
       // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For
       // now always use UTF-8 encoding.
       _HttpClientDigestCredentials creds = credentials;
-      var hasher = new _MD5();
-      hasher.add(UTF8.encode(creds.username));
-      hasher.add([_CharCode.COLON]);
-      hasher.add(realm.codeUnits);
-      hasher.add([_CharCode.COLON]);
-      hasher.add(UTF8.encode(creds.password));
+      var hasher = new _MD5()
+          ..add(UTF8.encode(creds.username))
+          ..add([_CharCode.COLON])
+          ..add(realm.codeUnits)
+          ..add([_CharCode.COLON])
+          ..add(UTF8.encode(creds.password));
       ha1 = _CryptoUtils.bytesToHex(hasher.close());
     }
   }
@@ -2397,7 +2393,7 @@
   Uri uri;
 
   _SiteCredentials(this.uri, realm, _HttpClientCredentials creds)
-  : super(creds, realm);
+      : super(creds, realm);
 
   bool applies(Uri uri, _AuthenticationScheme scheme) {
     if (scheme != null && credentials.scheme != scheme) return false;
@@ -2430,7 +2426,7 @@
                     this.port,
                     realm,
                     _HttpClientCredentials creds)
-  : super(creds, realm);
+      : super(creds, realm);
 
   bool applies(_Proxy proxy, _AuthenticationScheme scheme) {
     if (scheme != null && credentials.scheme != scheme) return false;
@@ -2459,8 +2455,10 @@
 class _HttpClientBasicCredentials
     extends _HttpClientCredentials
     implements HttpClientBasicCredentials {
-  _HttpClientBasicCredentials(this.username,
-                              this.password);
+  String username;
+  String password;
+
+  _HttpClientBasicCredentials(this.username, this.password);
 
   _AuthenticationScheme get scheme => _AuthenticationScheme.BASIC;
 
@@ -2476,75 +2474,75 @@
     return "Basic $auth";
   }
 
-  void authorize(_Credentials _, HttpClientRequest request) {
-    request.headers.set(HttpHeaders.AUTHORIZATION, authorization());
-  }
+  void authorize(_Credentials _, HttpClientRequest request) =>
+      request.headers.set(HttpHeaders.AUTHORIZATION, authorization());
 
-  void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) {
-    request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, authorization());
-  }
-
-  String username;
-  String password;
+  void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) =>
+      request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, authorization());
 }
 
 
 class _HttpClientDigestCredentials
     extends _HttpClientCredentials
     implements HttpClientDigestCredentials {
-  _HttpClientDigestCredentials(this.username,
-                               this.password);
+  String username;
+  String password;
+
+  _HttpClientDigestCredentials(this.username, this.password);
 
   _AuthenticationScheme get scheme => _AuthenticationScheme.DIGEST;
 
   String authorization(_Credentials credentials, _HttpClientRequest request) {
     String requestUri = request._requestUri();
-    _MD5 hasher = new _MD5();
-    hasher.add(request.method.codeUnits);
-    hasher.add([_CharCode.COLON]);
-    hasher.add(requestUri.codeUnits);
+    _MD5 hasher = new _MD5()
+        ..add(request.method.codeUnits)
+        ..add([_CharCode.COLON])
+        ..add(requestUri.codeUnits);
     var ha2 = _CryptoUtils.bytesToHex(hasher.close());
 
     String qop;
     String cnonce;
     String nc;
     var x;
-    hasher = new _MD5();
-    hasher.add(credentials.ha1.codeUnits);
-    hasher.add([_CharCode.COLON]);
+    hasher = new _MD5()
+        ..add(credentials.ha1.codeUnits)
+        ..add([_CharCode.COLON]);
     if (credentials.qop == "auth") {
       qop = credentials.qop;
       cnonce = _CryptoUtils.bytesToHex(_IOCrypto.getRandomBytes(4));
       ++credentials.nonceCount;
       nc = credentials.nonceCount.toRadixString(16);
       nc = "00000000".substring(0, 8 - nc.length + 1) + nc;
-      hasher.add(credentials.nonce.codeUnits);
-      hasher.add([_CharCode.COLON]);
-      hasher.add(nc.codeUnits);
-      hasher.add([_CharCode.COLON]);
-      hasher.add(cnonce.codeUnits);
-      hasher.add([_CharCode.COLON]);
-      hasher.add(credentials.qop.codeUnits);
-      hasher.add([_CharCode.COLON]);
-      hasher.add(ha2.codeUnits);
+      hasher
+          ..add(credentials.nonce.codeUnits)
+          ..add([_CharCode.COLON])
+          ..add(nc.codeUnits)
+          ..add([_CharCode.COLON])
+          ..add(cnonce.codeUnits)
+          ..add([_CharCode.COLON])
+          ..add(credentials.qop.codeUnits)
+          ..add([_CharCode.COLON])
+          ..add(ha2.codeUnits);
     } else {
-      hasher.add(credentials.nonce.codeUnits);
-      hasher.add([_CharCode.COLON]);
-      hasher.add(ha2.codeUnits);
+      hasher
+          ..add(credentials.nonce.codeUnits)
+          ..add([_CharCode.COLON])
+          ..add(ha2.codeUnits);
     }
     var response = _CryptoUtils.bytesToHex(hasher.close());
 
-    StringBuffer buffer = new StringBuffer();
-    buffer.write('Digest ');
-    buffer.write('username="$username"');
-    buffer.write(', realm="${credentials.realm}"');
-    buffer.write(', nonce="${credentials.nonce}"');
-    buffer.write(', uri="$requestUri"');
-    buffer.write(', algorithm="${credentials.algorithm}"');
+    StringBuffer buffer = new StringBuffer()
+        ..write('Digest ')
+        ..write('username="$username"')
+        ..write(', realm="${credentials.realm}"')
+        ..write(', nonce="${credentials.nonce}"')
+        ..write(', uri="$requestUri"')
+        ..write(', algorithm="${credentials.algorithm}"');
     if (qop == "auth") {
-      buffer.write(', qop="$qop"');
-      buffer.write(', cnonce="$cnonce"');
-      buffer.write(', nc="$nc"');
+      buffer
+          ..write(', qop="$qop"')
+          ..write(', cnonce="$cnonce"')
+          ..write(', nc="$nc"');
     }
     buffer.write(', response="$response"');
     return buffer.toString();
@@ -2560,19 +2558,14 @@
     request.headers.set(HttpHeaders.PROXY_AUTHORIZATION,
                         authorization(credentials, request));
   }
-
-  String username;
-  String password;
 }
 
 
 class _RedirectInfo implements RedirectInfo {
-  const _RedirectInfo(int this.statusCode,
-                      String this.method,
-                      Uri this.location);
   final int statusCode;
   final String method;
   final Uri location;
+  const _RedirectInfo(this.statusCode, this.method, this.location);
 }
 
 String _getHttpVersion() {
@@ -2582,5 +2575,3 @@
   version = version.substring(0, index);
   return 'Dart/$version (dart:io)';
 }
-
-
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index de55780..401f638 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -105,8 +105,7 @@
 
   Completer resumeCompleter;
 
-  _HttpDetachedIncoming(StreamSubscription this.subscription,
-                        List<int> this.bufferedData) {
+  _HttpDetachedIncoming(this.subscription, this.bufferedData) {
     controller = new StreamController<List<int>>(
         sync: true,
         onListen: resume,
@@ -119,10 +118,11 @@
       controller.close();
     } else {
       pause();
-      subscription.resume();
-      subscription.onData(controller.add);
-      subscription.onDone(controller.close);
-      subscription.onError(controller.addError);
+      subscription
+          ..resume()
+          ..onData(controller.add)
+          ..onDone(controller.close)
+          ..onError(controller.addError);
     }
   }
 
@@ -186,6 +186,42 @@
 class _HttpParser
     extends Stream<_HttpIncoming>
     implements StreamConsumer<List<int>> {
+  // State.
+  bool _parserCalled = false;
+
+  // The data that is currently being parsed.
+  Uint8List _buffer;
+  int _index;
+
+  final bool _requestParser;
+  int _state;
+  int _httpVersionIndex;
+  int _messageType;
+  int _statusCode = 0;
+  List _method_or_status_code;
+  List _uri_or_reason_phrase;
+  List _headerField;
+  List _headerValue;
+
+  int _httpVersion;
+  int _transferLength = -1;
+  bool _persistentConnection;
+  bool _connectionUpgrade;
+  bool _chunked;
+
+  bool _noMessageBody;
+  String _responseToMethod;  // Indicates the method used for the request.
+  int _remainingContent = -1;
+
+  _HttpHeaders _headers;
+
+  // The current incoming connection.
+  _HttpIncoming _incoming;
+  StreamSubscription _socketSubscription;
+  bool _paused = true;
+  bool _bodyPaused = false;
+  StreamController<_HttpIncoming> _controller;
+  StreamController<List<int>> _bodyController;
 
   factory _HttpParser.requestParser() {
     return new _HttpParser._(true);
@@ -955,41 +991,4 @@
     _controller.addError(error, stackTrace);
     _controller.close();
   }
-
-  // State.
-  bool _parserCalled = false;
-
-  // The data that is currently being parsed.
-  Uint8List _buffer;
-  int _index;
-
-  final bool _requestParser;
-  int _state;
-  int _httpVersionIndex;
-  int _messageType;
-  int _statusCode = 0;
-  List _method_or_status_code;
-  List _uri_or_reason_phrase;
-  List _headerField;
-  List _headerValue;
-
-  int _httpVersion;
-  int _transferLength = -1;
-  bool _persistentConnection;
-  bool _connectionUpgrade;
-  bool _chunked;
-
-  bool _noMessageBody;
-  String _responseToMethod;  // Indicates the method used for the request.
-  int _remainingContent = -1;
-
-  _HttpHeaders _headers;
-
-  // The current incoming connection.
-  _HttpIncoming _incoming;
-  StreamSubscription _socketSubscription;
-  bool _paused = true;
-  bool _bodyPaused = false;
-  StreamController<_HttpIncoming> _controller;
-  StreamController<List<int>> _bodyController;
 }
diff --git a/sdk/lib/io/http_session.dart b/sdk/lib/io/http_session.dart
index 1b049e3..9d87ae9 100644
--- a/sdk/lib/io/http_session.dart
+++ b/sdk/lib/io/http_session.dart
@@ -18,11 +18,11 @@
   // Pointers in timeout queue.
   _HttpSession _prev;
   _HttpSession _next;
+  final String id;
 
   final Map _data = new HashMap();
 
-  _HttpSession(_HttpSessionManager this._sessionManager, String this.id)
-    : _lastSeen = new DateTime.now();
+  _HttpSession(this._sessionManager, this.id) : _lastSeen = new DateTime.now();
 
   void destroy() {
     _destroyed = true;
@@ -41,8 +41,6 @@
 
   bool get isNew => _isNew;
 
-  final String id;
-
   void set onTimeout(void callback()) {
     _timeoutCallback = callback;
   }
@@ -70,6 +68,12 @@
 //  * In a map, mapping from ID to HttpSession.
 //  * In a linked list, used as a timeout queue.
 class _HttpSessionManager {
+  Map<String, _HttpSession> _sessions;
+  int _sessionTimeout = 20 * 60;  // 20 mins.
+  _HttpSession _head;
+  _HttpSession _tail;
+  Timer _timer;
+
   _HttpSessionManager() : _sessions = {};
 
   String createSessionId() {
@@ -78,9 +82,7 @@
     return _CryptoUtils.bytesToHex(data);
   }
 
-  _HttpSession getSession(String id) {
-    return _sessions[id];
-  }
+  _HttpSession getSession(String id) => _sessions[id];
 
   _HttpSession createSession() {
     var id = createSessionId();
@@ -100,9 +102,7 @@
     _startTimer();
   }
 
-  void close() {
-    _stopTimer();
-  }
+  void close() => _stopTimer();
 
   void _bumpToEnd(_HttpSession session) {
     _removeFromTimeoutQueue(session);
@@ -168,11 +168,5 @@
       _timer = null;
     }
   }
-
-  Map<String, _HttpSession> _sessions;
-  int _sessionTimeout = 20 * 60;  // 20 mins.
-  _HttpSession _head;
-  _HttpSession _tail;
-  Timer _timer;
 }
 
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index 1cf9c4d..59b0697 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -5,17 +5,198 @@
 /**
  * File, socket, HTTP, and other I/O support for server applications.
  *
- * The IO library is used for Dart server applications,
+ * The I/O library is used for Dart server applications,
  * which run on a stand-alone Dart VM from the command line.
- * *This library does not work in browser based applications.*
+ * *This library does not work in browser-based applications.*
  *
  * This library allows you to work with files, directories,
  * sockets, processes, HTTP servers and clients, and more.
+ *
+ * To use this library in your code:
+ *
+ *     import 'dart:io';
+ *
+ * *Note:* Many operations related to input and output are asynchronous
+ * and are handled using [Future]s or [Stream]s, both of which
+ * are defined in the `dart:async` library.
+ *
+ * ## File, Directory, and Link
+ *
+ * An instance of [File], [Directory], or [Link] represents a file,
+ * directory, or link, respectively, in the native file system.
+ *
+ * You can manipulate the file system through objects of these types.
+ * For example, you can rename a file or directory:
+ *
+ *     File myFile = new File('myFile.txt');
+ *     myFile.rename('yourFile.txt').then((_) => print('file renamed'));
+ *
+ * Many methods provided by the File, Directory, and Link classes
+ * run asynchronously and return a Future.
+ *
+ * ## FileSystemEntity
+ *
+ * File, Directory, and Link all extend [FileSystemEntity].
+ * In addition to being the superclass for these classes,
+ * FileSystemEntity has a number of static methods for working with paths.
+ *
+ * To get information about a path,
+ * you can use the FileSystemEntity static methods
+ * such as 'isDirectory', 'isFile', and 'exists'.
+ * Because file system access involves I/O, these methods
+ * are asynchronous and return a Future.
+ *
+ *     FileSystemEntity.isDirectory(myPath).then((isDir) {
+ *       if (isDir) {
+ *         print('$myPath is a directory');
+ *       } else {
+ *         print('$myPath is not a directory');
+ *       }
+ *     });
+ *
+ * ## HttpServer and HttpClient
+ *
+ * The classes [HttpServer] and [HttpClient]
+ * provide HTTP server and HTTP client functionality.
+ *
+ * The [HttpServer] class provides the basic functionality for
+ * implementing an HTTP server.
+ * For some higher-level building-blocks, we recommend that you try
+ * the [http_server](https://pub.dartlang.org/packages/http_server)
+ * pub package, which contains
+ * a set of high-level classes that, together with the [HttpServer] class
+ * in this library, make it easier to implement HTTP servers.
+ *
+ * ## Process
+ *
+ * The [Process] class provides a way to run a process on
+ * the native machine.
+ * For example, the following code spawns a process that recursively lists
+ * the files under `web`.
+ *
+ *     Process.start('ls', ['-R', 'web']).then((process) {
+ *       stdout.addStream(process.stdout);
+ *       stderr.addStream(process.stderr);
+ *       process.exitCode.then(print);
+ *     });
+ *
+ * Using `start()` returns a Future, which completes with a [Process] object when
+ * the process has started. This [Process] object allows you to interact with the
+ * process while it is running. Using `run()` returns a Future, which completes with
+ * a [ProcessResult] object when the spawned process has terminated. This
+ * [ProcessResult] object collects the output and exit code from the process. 
+ *
+ * When using `start()`,
+ * you need to read all data coming on the stdout and stderr streams otherwise
+ * the system resources will not be freed.
+ *
+ * ## WebSocket
+ *
+ * The [WebSocket] class provides support for the web socket protocol. This allows
+ * full-duplex communications between client and server applications.
+ * Use the WebSocket class in the `dart:html` library for web clients.
+ *
+ * A web socket server uses a normal HTTP server for accepting web socket
+ * connections. The initial handshake is a HTTP request which is then upgraded to a
+ * web socket connection.
+ * The server upgrades the request using [WebSocketTransformer]
+ * and listens for the data on the returned web socket.
+ * For example, here's a mini server that listens for 'ws' data
+ * on a WebSocket:
+ *
+ *     runZoned(() {
+ *       HttpServer.bind('127.0.0.1', 4040).then((server) {
+ *         server.listen((HttpRequest req) {
+ *           if (req.uri.path == '/ws') {
+ *             WebSocketTransformer.upgrade(req).then((socket) {
+ *               socket.listen(handleMsg);
+ *             });
+ *           }
+ *         });
+ *       });
+ *     },
+ *     onError: (e) => print("An error occurred."));
+ *
+ * The client connects to the WebSocket using the `connect()` method
+ * and a URI that uses the Web Socket protocol.
+ * The the client can write to the WebSocket with the `add()` method.
+ * For example,
+ *
+ *     WebSocket.connect('ws://127.0.0.1:4040/ws').then((socket) {
+ *       socket.add('Hello, World!');
+ *     });
+ *
+ * Check out the
+ * [dartiverse_search](https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/samples/dartiverse_search)
+ * sample for a client/server pair that uses
+ * WebSockets to communicate.
+ *
+ * ## Socket and ServerSocket
+ *
+ * Clients and servers use [Socket]s to communicate using the TCP protocol.
+ * Use [ServerSocket] on the server side and [Socket] on the client.
+ * The server creates a listening socket using the `bind()` method and
+ * then listens for incoming connections on the socket. For example:
+ *
+ *     ServerSocket.bind('127.0.0.1', 4041)
+ *       .then((serverSocket) {
+ *         serverSocket.listen((socket) {
+ *           socket.transform(UTF8.decoder).listen(print);
+ *         });
+ *       });
+ *
+ * A client connects a Socket using the `connect()` method,
+ * which returns a Future.
+ * Using `write()`, `writeln()`, or `writeAll()` are the easiest ways to 
+ * send data over the socket.
+ * For example:
+ *
+ *     Socket.connect('127.0.0.1', 4041).then((socket) {
+ *       socket.write('Hello, World!');
+ *     });
+ *
+ * Besides [Socket] and [ServerSocket], the [RawSocket] and
+ * [RawServerSocket] classes are available for lower-level access
+ * to async socket IO.
+ *
+ * ## Standard output, error, and input streams
+ *
+ * This library provides the standard output, error, and input
+ * streams, named 'stdout', 'stderr', and 'stdin', respectively.
+ *
+ * The stdout and stderr streams are both [IOSink]s and have the same set
+ * of methods and properties.
+ *
+ * To write a string to 'stdout':
+ *
+ *     stdout.writeln('Hello, World!');
+ *
+ * To write a list of objects to 'stderr':
+ *
+ *     stderr.writeAll([ 'That ', 'is ', 'an ', 'error.', '\n']);
+ *
+ * The standard input stream is a true [Stream], so it inherits
+ * properties and methods from the Stream class.
+ *
+ * To read text synchronously from the command line
+ * (the program blocks waiting for user to type information):
+ *
+ *      String inputText = stdin.readLineSync();
+ *
+ * ## Other resources
+ *
+ * For an introduction to I/O in Dart, see the
+ * [dart:io section of the library tour]
+ * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartio---file-and-socket-io-for-command-line-apps).
+ *
+ * To learn more about I/O in Dart, refer to the
+ * [tutorial about writing command-line apps]
+ * (https://www.dartlang.org/docs/tutorials/io/).
  */
 library dart.io;
 
 import 'dart:async';
-import 'dart:_collection-dev';
+import 'dart:_internal';
 import 'dart:collection' show HashMap,
                               HashSet,
                               LinkedList,
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index 45390d8..e2ea2bd 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -78,7 +78,7 @@
   bool _isBound = false;
   bool _hasError = false;
 
-  _StreamSinkImpl(StreamConsumer<T> this._target) {
+  _StreamSinkImpl(this._target) {
     _doneFuture = _doneCompleter.future;
   }
 
@@ -87,9 +87,8 @@
     _controller.add(data);
   }
 
-  void addError(error, [StackTrace stackTrace]) {
-    _controller.addError(error, stackTrace);
-  }
+  void addError(error, [StackTrace stackTrace]) =>
+      _controller.addError(error, stackTrace);
 
   Future addStream(Stream<T> stream) {
     if (_isBound) {
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 0ffcf0e..3fc8376 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -143,7 +143,7 @@
 class _Link extends FileSystemEntity implements Link {
   final String path;
 
-  _Link(String this.path) {
+  _Link(this.path) {
     if (path is! String) {
       throw new ArgumentError('${Error.safeToString(path)} '
                               'is not a String');
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 48bf58b..f58d567 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -63,6 +63,9 @@
   /**
    * Get the environment for this process.
    *
+   * The returned environment is a unmodifiable map which content is
+   * retrieved from the operating system on its first use.
+   *
    * Environment variables on Windows are case-insensitive. The map
    * returned on Windows is therefore case-insensitive and will convert
    * all keys to upper case. On other platforms the returned map is
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 40fe2f0..57598e8 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -15,6 +15,13 @@
   external static String _packageRoot();
   external static String _version();
 
+  static String executable = _executable();
+  static String packageRoot = _packageRoot();
+
+  // Cache the OS environemnt. This can be an OSError instance if
+  // retrieving the environment failed.
+  static var _environmentCache;
+
   static int get numberOfProcessors => _numberOfProcessors();
   static String get pathSeparator => _pathSeparator();
   static String get operatingSystem => _operatingSystem();
@@ -40,33 +47,40 @@
     }
   }
 
-  static String executable = _executable();
-  static String packageRoot = _packageRoot();
   static List<String> get executableArguments => _executableArguments();
 
   static Map<String, String> get environment {
-    var env = _environment();
-    if (env is OSError) {
-      throw env;
-    } else {
-      var isWindows = operatingSystem == 'windows';
-      var result = isWindows ? new _CaseInsensitiveStringMap() : new Map();
-      for (var str in env) {
-        // When running on Windows through cmd.exe there are strange
-        // environment variables that are used to record the current
-        // working directory for each drive and the exit code for the
-        // last command. As an example: '=A:=A:\subdir' records the
-        // current working directory on the 'A' drive.  In order to
-        // handle these correctly we search for a second occurrence of
-        // of '=' in the string if the first occurrence is at index 0.
-        var equalsIndex = str.indexOf('=');
-        if (equalsIndex == 0) {
-          equalsIndex = str.indexOf('=', 1);
+    if (_environmentCache == null) {
+      var env = _environment();
+      if (env is !OSError) {
+        var isWindows = operatingSystem == 'windows';
+        var result = isWindows ? new _CaseInsensitiveStringMap() : new Map();
+        for (var str in env) {
+          // When running on Windows through cmd.exe there are strange
+          // environment variables that are used to record the current
+          // working directory for each drive and the exit code for the
+          // last command. As an example: '=A:=A:\subdir' records the
+          // current working directory on the 'A' drive.  In order to
+          // handle these correctly we search for a second occurrence of
+          // of '=' in the string if the first occurrence is at index 0.
+          var equalsIndex = str.indexOf('=');
+          if (equalsIndex == 0) {
+            equalsIndex = str.indexOf('=', 1);
+          }
+          assert(equalsIndex != -1);
+          result[str.substring(0, equalsIndex)] =
+              str.substring(equalsIndex + 1);
         }
-        assert(equalsIndex != -1);
-        result[str.substring(0, equalsIndex)] = str.substring(equalsIndex + 1);
+        _environmentCache = new _UnmodifiableMap(result);
+      } else {
+        _environmentCache = env;
       }
-      return result;
+    }
+
+    if (_environmentCache is OSError) {
+      throw _environmentCache;
+    } else {
+      return _environmentCache;
     }
   }
 
@@ -76,6 +90,8 @@
 // Environment variables are case-insensitive on Windows. In order
 // to reflect that we use a case-insensitive string map on Windows.
 class _CaseInsensitiveStringMap<V> implements Map<String, V> {
+  Map<String, V> _map;
+
   _CaseInsensitiveStringMap() : _map = new Map<String, V>();
 
   _CaseInsensitiveStringMap.from(Map<String, V> other)
@@ -105,6 +121,4 @@
   int get length => _map.length;
   bool get isEmpty => _map.isEmpty;
   bool get isNotEmpty => _map.isNotEmpty;
-
-  Map<String, V> _map;
 }
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 3b340c3..a59fc88 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -90,6 +90,31 @@
  */
 abstract class Process {
   /**
+   * Returns a [:Future:] which completes with the exit code of the process
+   * when the process completes.
+   *
+   * The handling of exit codes is platform specific.
+   *
+   * On Linux and Mac a normal exit code will be a positive value in
+   * the range [0..255]. If the process was terminated due to a signal
+   * the exit code will be a negative value in the range [-255..0[,
+   * where the absolute value of the exit code is the signal
+   * number. For example, if a process crashes due to a segmentation
+   * violation the exit code will be -11, as the signal SIGSEGV has the
+   * number 11.
+   *
+   * On Windows a process can report any 32-bit value as an exit
+   * code. When returning the exit code this exit code is turned into
+   * a signed value. Some special values are used to report
+   * termination due to some system event. E.g. if a process crashes
+   * due to an access violation the 32-bit exit code is `0xc0000005`,
+   * which will be returned as the negative number `-1073741819`. To
+   * get the original 32-bit value use `(0x100000000 + exitCode) &
+   * 0xffffffff`.
+   */
+  Future<int> exitCode;
+
+  /**
    * Starts a process running the [executable] with the specified
    * [arguments]. Returns a [:Future<Process>:] that completes with a
    * Process instance when the process has been successfully
@@ -229,36 +254,11 @@
   int get pid;
 
   /**
-   * Returns a [:Future:] which completes with the exit code of the process
-   * when the process completes.
-   *
-   * The handling of exit codes is platform specific.
-   *
-   * On Linux and Mac a normal exit code will be a positive value in
-   * the range [0..255]. If the process was terminated due to a signal
-   * the exit code will be a negative value in the range [-255..0[,
-   * where the absolute value of the exit code is the signal
-   * number. For example, if a process crashes due to a segmentation
-   * violation the exit code will be -11, as the signal SIGSEGV has the
-   * number 11.
-   *
-   * On Windows a process can report any 32-bit value as an exit
-   * code. When returning the exit code this exit code is turned into
-   * a signed value. Some special values are used to report
-   * termination due to some system event. E.g. if a process crashes
-   * due to an access violation the 32-bit exit code is `0xc0000005`,
-   * which will be returned as the negative number `-1073741819`. To
-   * get the original 32-bit value use `(0x100000000 + exitCode) &
-   * 0xffffffff`.
-   */
-  Future<int> exitCode;
-
-  /**
    * On Windows, [kill] kills the process, ignoring the [signal]
    * flag. On Posix systems, [kill] sends [signal] to the
-   * process. Depending on the signal giving, it'll have different
+   * process. Depending on the signal send, it'll have different
    * meanings. When the process terminates as a result of calling
-   * [kill] [onExit] is called.
+   * [kill], the [exitCode] future is completed with the exit code.
    *
    * Returns [:true:] if the process is successfully killed (the
    * signal is successfully sent). Returns [:false:] if the process
@@ -356,7 +356,7 @@
   final String message;
   final osError;
 
-  const SignalException(String this.message, [this.osError = null]);
+  const SignalException(this.message, [this.osError = null]);
 
   String toString() {
     var msg = "";
@@ -369,16 +369,6 @@
 
 
 class ProcessException implements IOException {
-  const ProcessException(String this.executable,
-                         List<String> this.arguments,
-                         [String this.message = "",
-                          int this.errorCode = 0]);
-  String toString() {
-    var msg = (message == null) ? 'OS error code: $errorCode' : message;
-    var args = arguments.join(' ');
-    return "ProcessException: $msg\n  Command: $executable $args";
-  }
-
   /**
    * Contains the executable provided for the process.
    */
@@ -398,4 +388,12 @@
    * Contains the OS error code for the process exception if any.
    */
   final int errorCode;
+
+  const ProcessException(this.executable, this.arguments, [this.message = "",
+                         this.errorCode = 0]);
+  String toString() {
+    var msg = (message == null) ? 'OS error code: $errorCode' : message;
+    var args = arguments.join(' ');
+    return "ProcessException: $msg\n  Command: $executable $args";
+  }
 }
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index affa57c..7f928b1 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -13,7 +13,7 @@
 class SecureServerSocket extends Stream<SecureSocket> {
   final RawSecureServerSocket _socket;
 
-  SecureServerSocket._(RawSecureServerSocket this._socket);
+  SecureServerSocket._(this._socket);
 
   /**
    * Returns a future for a [SecureServerSocket]. When the future
@@ -123,9 +123,9 @@
   bool _closed = false;
 
   RawSecureServerSocket._(RawServerSocket serverSocket,
-                          String this.certificateName,
-                          bool this.requestClientCertificate,
-                          bool this.requireClientCertificate) {
+                          this.certificateName,
+                          this.requestClientCertificate,
+                          this.requireClientCertificate) {
     _socket = serverSocket;
     _controller = new StreamController<RawSecureSocket>(
         sync: true,
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 9bfa032..8590284 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -491,17 +491,17 @@
   }
 
   _RawSecureSocket(
-      InternetAddress this.address,
+      this.address,
       int requestedPort,
-      String this.certificateName,
-      bool this.is_server,
+      this.certificateName,
+      this.is_server,
       RawSocket socket,
-      StreamSubscription this._socketSubscription,
-      List<int> this._bufferedData,
-      bool this.requestClientCertificate,
-      bool this.requireClientCertificate,
-      bool this.sendClientCertificate,
-      bool this.onBadCertificate(X509Certificate certificate)) {
+      this._socketSubscription,
+      this._bufferedData,
+      this.requestClientCertificate,
+      this.requireClientCertificate,
+      this.sendClientCertificate,
+      this.onBadCertificate(X509Certificate certificate)) {
     _controller = new StreamController<RawSocketEvent>(
         sync: true,
         onListen: _onSubscriptionStateChange,
@@ -535,9 +535,10 @@
                                              onError: _reportError,
                                              onDone: _doneHandler);
       } else {
-        _socketSubscription.onData(_eventDispatcher);
-        _socketSubscription.onError(_reportError);
-        _socketSubscription.onDone(_doneHandler);
+        _socketSubscription
+            ..onData(_eventDispatcher)
+            ..onError(_reportError)
+            ..onDone(_doneHandler);
       }
       _secureFilter.connect(address.host,
                             (address as dynamic)._in_addr,
@@ -608,8 +609,8 @@
   int get remotePort => _socket.remotePort;
 
   int available() {
-    if (_status != CONNECTED) return 0;
-    return _secureFilter.buffers[READ_PLAINTEXT].length;
+    return _status != CONNECTED ? 0
+                                : _secureFilter.buffers[READ_PLAINTEXT].length;
   }
 
   Future<RawSecureSocket> close() {
@@ -1068,9 +1069,13 @@
  * and one writing.  All updates to start and end are done by Dart code.
  */
 class _ExternalBuffer {
+  List data;  // This will be a ExternalByteArray, backed by C allocated data.
+  int start;
+  int end;
+  final size;
+
   _ExternalBuffer(this.size) {
-    start = size~/2;
-    end = size~/2;
+    start = end = size ~/ 2;
   }
 
   void advanceStart(int bytes) {
@@ -1095,20 +1100,14 @@
 
   bool get isEmpty => end == start;
 
-  int get length {
-    if (start > end) return size + end - start;
-    return end - start;
-  }
+  int get length =>
+      start > end ? size + end - start : end - start;
 
-  int get linearLength {
-    if (start > end) return size - start;
-    return end - start;
-  }
+  int get linearLength =>
+      start > end ? size - start : end - start;
 
-  int get free {
-    if (start > end) return start - end - 1;
-    return size + start - end - 1;
-  }
+  int get free =>
+      start > end ? start - end - 1 : size + start - end - 1;
 
   int get linearFree {
     if (start > end) return start - end - 1;
@@ -1185,11 +1184,6 @@
       }
     }
   }
-
-  List data;  // This will be a ExternalByteArray, backed by C allocated data.
-  int start;
-  int end;
-  final size;
 }
 
 
@@ -1232,9 +1226,7 @@
                       OSError osError = null])
      : this._("TlsException", message, osError);
 
-  const TlsException._(String this.type,
-                       String this.message,
-                       OSError this.osError);
+  const TlsException._(this.type, this.message, this.osError);
 
   String toString() {
     StringBuffer sb = new StringBuffer();
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index b619fec..35e646a 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -16,7 +16,7 @@
 
   final int _value;
 
-  const InternetAddressType._(int this._value);
+  const InternetAddressType._(this._value);
 
   factory InternetAddressType._from(int value) {
     if (value == 0) return IP_V4;
@@ -304,8 +304,9 @@
   static const SocketDirection RECEIVE = const SocketDirection._(0);
   static const SocketDirection SEND = const SocketDirection._(1);
   static const SocketDirection BOTH = const SocketDirection._(2);
-  const SocketDirection._(this._value);
   final _value;
+
+  const SocketDirection._(this._value);
 }
 
 /**
@@ -327,9 +328,9 @@
   static const SocketOption _IP_MULTICAST_HOPS = const SocketOption._(2);
   static const SocketOption _IP_MULTICAST_IF = const SocketOption._(3);
   static const SocketOption _IP_BROADCAST = const SocketOption._(4);
+  final _value;
 
   const SocketOption._(this._value);
-  final _value;
 }
 
 /**
@@ -340,8 +341,9 @@
   static const RawSocketEvent WRITE = const RawSocketEvent._(1);
   static const RawSocketEvent READ_CLOSED = const RawSocketEvent._(2);
   static const RawSocketEvent CLOSED = const RawSocketEvent._(3);
-  const RawSocketEvent._(this._value);
   final int _value;
+
+  const RawSocketEvent._(this._value);
   String toString() {
     return ['RawSocketEvent:READ',
             'RawSocketEvent:WRITE',
@@ -356,6 +358,20 @@
  */
 abstract class RawSocket implements Stream<RawSocketEvent> {
   /**
+   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.READ]
+   * events. Default is [true].
+   */
+  bool readEventsEnabled;
+
+  /**
+   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.WRITE]
+   * events. Default is [true].
+   * This is a one-shot listener, and writeEventsEnabled must be set
+   * to true again to receive another write event.
+   */
+  bool writeEventsEnabled;
+
+  /**
    * Creates a new socket connection to the host and port and returns a [Future]
    * that will complete with either a [RawSocket] once connected or an error
    * if the host-lookup or connection failed.
@@ -431,20 +447,6 @@
   void shutdown(SocketDirection direction);
 
   /**
-   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.READ]
-   * events. Default is [true].
-   */
-  bool readEventsEnabled;
-
-  /**
-   * Set or get, if the [RawSocket] should listen for [RawSocketEvent.WRITE]
-   * events. Default is [true].
-   * This is a one-shot listener, and writeEventsEnabled must be set
-   * to true again to receive another write event.
-   */
-  bool writeEventsEnabled;
-
-  /**
    * Use [setOption] to customize the [RawSocket]. See [SocketOption] for
    * available options.
    *
@@ -535,58 +537,6 @@
  */
 abstract class RawDatagramSocket extends Stream<RawSocketEvent> {
   /**
-   * Creates a new raw datagram socket binding it to an address and
-   * port.
-   */
-  external static Future<RawDatagramSocket> bind(
-      host, int port, {bool reuseAddress: true});
-
-  /**
-   * Returns the port used by this socket.
-   */
-  int get port;
-
-  /**
-   * Returns the address used by this socket.
-   */
-  InternetAddress get address;
-
-  /**
-   * Close the datagram socket.
-   */
-  void close();
-
-  /**
-   * Send a datagram.
-   *
-   * Returns the number of bytes written. This will always be either
-   * the size of [buffer] or `0`.
-   */
-  int send(List<int> buffer, InternetAddress address, int port);
-
-  /**
-   * Receive a datagram. If there are no datagrams available `null` is
-   * returned.
-   */
-  Datagram receive();
-
-  /**
-   * Join a multicast group.
-   *
-   * If an error occur when trying to join the multicast group an
-   * exception is thrown.
-   */
-  void joinMulticast(InternetAddress group, {NetworkInterface interface});
-
-  /**
-   * Leave a multicast group.
-   *
-   * If an error occur when trying to join the multicase group an
-   * exception is thrown.
-   */
-  void leaveMulticast(InternetAddress group, {NetworkInterface interface});
-
-  /**
    * Set or get, if the [RawDatagramSocket] should listen for
    * [RawSocketEvent.READ] events. Default is [true].
    */
@@ -638,6 +588,58 @@
    * instead.
    */
   bool broadcastEnabled;
+
+  /**
+   * Creates a new raw datagram socket binding it to an address and
+   * port.
+   */
+  external static Future<RawDatagramSocket> bind(
+      host, int port, {bool reuseAddress: true});
+
+  /**
+   * Returns the port used by this socket.
+   */
+  int get port;
+
+  /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address;
+
+  /**
+   * Close the datagram socket.
+   */
+  void close();
+
+  /**
+   * Send a datagram.
+   *
+   * Returns the number of bytes written. This will always be either
+   * the size of [buffer] or `0`.
+   */
+  int send(List<int> buffer, InternetAddress address, int port);
+
+  /**
+   * Receive a datagram. If there are no datagrams available `null` is
+   * returned.
+   */
+  Datagram receive();
+
+  /**
+   * Join a multicast group.
+   *
+   * If an error occur when trying to join the multicast group an
+   * exception is thrown.
+   */
+  void joinMulticast(InternetAddress group, {NetworkInterface interface});
+
+  /**
+   * Leave a multicast group.
+   *
+   * If an error occur when trying to join the multicase group an
+   * exception is thrown.
+   */
+  void leaveMulticast(InternetAddress group, {NetworkInterface interface});
 }
 
 
@@ -647,10 +649,7 @@
   final InternetAddress address;
   final int port;
 
-  const SocketException(String this.message,
-                        {OSError this.osError,
-                         InternetAddress this.address,
-                         int this.port});
+  const SocketException(this.message, {this.osError, this.address, this.port});
 
   String toString() {
     StringBuffer sb = new StringBuffer();
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index ea0a382..5c1fa8f 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -14,7 +14,7 @@
 class _StdStream extends Stream<List<int>> {
   final Stream<List<int>> _stream;
 
-  _StdStream(Stream<List<int>> this._stream);
+  _StdStream(this._stream);
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
                                        {Function onError,
@@ -205,7 +205,7 @@
 class _StdSink implements IOSink {
   final IOSink _sink;
 
-  _StdSink(IOSink this._sink);
+  _StdSink(this._sink);
 
   Encoding get encoding => _sink.encoding;
   void set encoding(Encoding encoding) {
@@ -231,7 +231,7 @@
   static const StdioType FILE = const StdioType._("file");
   static const StdioType OTHER = const StdioType._("other");
   final String name;
-  const StdioType._(String this.name);
+  const StdioType._(this.name);
   String toString() => "StdioType: $name";
 }
 
diff --git a/sdk/lib/io/websocket.dart b/sdk/lib/io/websocket.dart
index 1e2d0fa..32dc9e0 100644
--- a/sdk/lib/io/websocket.dart
+++ b/sdk/lib/io/websocket.dart
@@ -109,6 +109,22 @@
   static const int CLOSED = 3;
 
   /**
+   * Set and get the interval for sending ping signals. If a ping message is not
+   * answered by a pong message from the peer, the `WebSocket` is assumed
+   * disconnected and the connection is closed with a
+   * [WebSocketStatus.GOING_AWAY] close code. When a ping signal is sent, the
+   * pong message must be received within [pingInterval].
+   *
+   * There are never two outstanding pings at any given time, and the next ping
+   * timer starts when the pong is received.
+   *
+   * Set the [pingInterval] to `null` to disable sending ping messages.
+   *
+   * The default value is `null`.
+   */
+  Duration pingInterval;
+
+  /**
    * Create a new web socket connection. The URL supplied in [url]
    * must use the scheme [:ws:] or [:wss:]. The [protocols] argument is
    * specifying the subprotocols the client is willing to speak.
@@ -150,22 +166,6 @@
   String get closeReason;
 
   /**
-   * Set and get the interval for sending ping signals. If a ping message is not
-   * answered by a pong message from the peer, the `WebSocket` is assumed
-   * disconnected and the connection is closed with a
-   * [WebSocketStatus.GOING_AWAY] close code. When a ping signal is sent, the
-   * pong message must be received within [pingInterval].
-   *
-   * There are never two outstanding pings at any given time, and the next ping
-   * timer starts when the pong is received.
-   *
-   * Set the [pingInterval] to `null` to disable sending ping messages.
-   *
-   * The default value is `null`.
-   */
-  Duration pingInterval;
-
-  /**
    * Closes the web socket connection. Set the optional [code] and [reason]
    * arguments to send close information to the remote peer. If they are
    * omitted, the peer will see [WebSocketStatus.NO_STATUS_RECEIVED] code
@@ -189,7 +189,7 @@
 
 
 class WebSocketException implements IOException {
-  const WebSocketException([String this.message = ""]);
-  String toString() => "WebSocketException: $message";
   final String message;
+  const WebSocketException([this.message = ""]);
+  String toString() => "WebSocketException: $message";
 }
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index 556de41..48eeca1 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -51,10 +51,28 @@
   static const int CLOSED = 5;
   static const int FAILURE = 6;
 
+  int _state;
+  bool _fin;
+  int _opcode;
+  int _len;
+  bool _masked;
+  int _maskingKey;
+  int _remainingLenBytes;
+  int _remainingMaskingKeyBytes;
+  int _remainingPayloadBytes;
+  int _unmaskingIndex;
+
+  int _currentMessageType;
+  List<int> _controlPayload;
+  StreamController _controller;
+
+  int closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
+  String closeReason = "";
+
   bool _serverSide;
   EventSink _eventSink;
 
-  _WebSocketProtocolTransformer([bool this._serverSide = false]) {
+  _WebSocketProtocolTransformer([this._serverSide = false]) {
     _prepareForNextFrame();
     _currentMessageType = _WebSocketMessageType.NONE;
   }
@@ -71,9 +89,8 @@
         });
   }
 
-  void addError(Object error, [StackTrace stackTrace]) {
-    _eventSink.addError(error, stackTrace);
-  }
+  void addError(Object error, [StackTrace stackTrace]) =>
+      _eventSink.addError(error, stackTrace);
 
   void close() => _eventSink.close();
 
@@ -357,24 +374,6 @@
     _unmaskingIndex = 0;
     _controlPayload = null;
   }
-
-  int _state;
-  bool _fin;
-  int _opcode;
-  int _len;
-  bool _masked;
-  int _maskingKey;
-  int _remainingLenBytes;
-  int _remainingMaskingKeyBytes;
-  int _remainingPayloadBytes;
-  int _unmaskingIndex;
-
-  int _currentMessageType;
-  List<int> _controlPayload;
-  StreamController _controller;
-
-  int closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
-  String closeReason = "";
 }
 
 
@@ -411,17 +410,19 @@
     var response = request.response;
     if (!_isUpgradeRequest(request)) {
       // Send error response.
-      response.statusCode = HttpStatus.BAD_REQUEST;
-      response.close();
+      response
+          ..statusCode = HttpStatus.BAD_REQUEST
+          ..close();
       return new Future.error(
           new WebSocketException("Invalid WebSocket upgrade request"));
     }
 
     Future upgrade(String protocol) {
       // Send the upgrade response.
-      response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
-      response.headers.add(HttpHeaders.CONNECTION, "Upgrade");
-      response.headers.add(HttpHeaders.UPGRADE, "websocket");
+      response
+          ..statusCode = HttpStatus.SWITCHING_PROTOCOLS
+          ..headers.add(HttpHeaders.CONNECTION, "Upgrade")
+          ..headers.add(HttpHeaders.UPGRADE, "websocket");
       String key = request.headers.value("Sec-WebSocket-Key");
       _SHA1 sha1 = new _SHA1();
       sha1.add("$key$_webSocketGUID".codeUnits);
@@ -451,8 +452,9 @@
           return protocol;
         })
         .catchError((error) {
-          response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
-          response.close();
+          response
+              ..statusCode = HttpStatus.INTERNAL_SERVER_ERROR
+              ..close();
           throw error;
         })
         .then(upgrade);
@@ -495,7 +497,7 @@
   final _WebSocketImpl webSocket;
   EventSink _eventSink;
 
-  _WebSocketOutgoingTransformer(_WebSocketImpl this.webSocket);
+  _WebSocketOutgoingTransformer(this.webSocket);
 
   Stream bind(Stream stream) {
     return new Stream.eventTransformed(
@@ -537,9 +539,8 @@
     addFrame(opcode, data);
   }
 
-  void addError(Object error, [StackTrace stackTrace]) {
-    _eventSink.addError(error, stackTrace);
-  }
+  void addError(Object error, [StackTrace stackTrace]) =>
+      _eventSink.addError(error, stackTrace);
 
   void close() {
     int code = webSocket._outCloseCode;
@@ -557,9 +558,8 @@
     _eventSink.close();
   }
 
-  void addFrame(int opcode, List<int> data) {
-    createFrame(opcode, data, webSocket._serverSide).forEach(_eventSink.add);
-  }
+  void addFrame(int opcode, List<int> data) =>
+      createFrame(opcode, data, webSocket._serverSide).forEach(_eventSink.add);
 
   static Iterable createFrame(int opcode, List<int> data, bool serverSide) {
     bool mask = !serverSide;  // Masking not implemented for server.
@@ -640,7 +640,7 @@
   Completer _closeCompleter = new Completer();
   Completer _completer;
 
-  _WebSocketConsumer(_WebSocketImpl this.webSocket, Socket this.socket);
+  _WebSocketConsumer(this.webSocket, this.socket);
 
   void _onListen() {
     if (_subscription != null) {
@@ -802,10 +802,11 @@
     return _httpClient.openUrl("GET", uri)
       .then((request) {
         // Setup the initial handshake.
-        request.headers.add(HttpHeaders.CONNECTION, "upgrade");
-        request.headers.set(HttpHeaders.UPGRADE, "websocket");
-        request.headers.set("Sec-WebSocket-Key", nonce);
-        request.headers.set("Sec-WebSocket-Version", "13");
+        request.headers
+            ..add(HttpHeaders.CONNECTION, "upgrade")
+            ..set(HttpHeaders.UPGRADE, "websocket")
+            ..set("Sec-WebSocket-Key", nonce)
+            ..set("Sec-WebSocket-Version", "13");
         if (protocols.isNotEmpty) {
           request.headers.add("Sec-WebSocket-Protocol", protocols);
         }
@@ -849,9 +850,8 @@
       });
   }
 
-  _WebSocketImpl._fromSocket(Socket this._socket,
-                             String this.protocol,
-                             [bool this._serverSide = false]) {
+  _WebSocketImpl._fromSocket(this._socket, this.protocol,
+                             [this._serverSide = false]) {
     _consumer = new _WebSocketConsumer(this, _socket);
     _sink = new _StreamSinkImpl(_consumer);
     _readyState = WebSocket.OPEN;
diff --git a/sdk/lib/math/point.dart b/sdk/lib/math/point.dart
index 6c731c1..42fcc46 100644
--- a/sdk/lib/math/point.dart
+++ b/sdk/lib/math/point.dart
@@ -14,6 +14,13 @@
 
   String toString() => 'Point($x, $y)';
 
+  /**
+   * A `Point` is only equal to another `Point` with the same coordinates.
+   *
+   * This point is equal to `other` if, and only if,
+   * `other` is a `Point` with
+   * [x] equal to `other.x` and [y] equal to `other.y`.
+   */
   bool operator ==(other) {
     if (other is !Point) return false;
     return x == other.x && y == other.y;
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index 25bce63..be338f9 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -15,8 +15,6 @@
    * Creates a random-number generator. The optional parameter [seed] is used
    * to initialize the internal state of the generator. The implementation of
    * the random stream can change between releases of the library.
-   *
-   * Implementation note: The default implementation uses up to 64-bits of seed.
    */
   external factory Random([int seed]);
 
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index f96525a..1c4c799 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -705,6 +705,11 @@
   List<ClassMirror> get superinterfaces;
 
   /**
+   * Is the reflectee abstract?
+   */
+  bool get isAbstract;
+
+  /**
    * Returns an immutable map of the declarations actually given in the class
    * declaration.
    *
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index d599314..1fc55d8 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -10,7 +10,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, Returns, JSName;
@@ -1439,7 +1439,7 @@
   /// Checks if this type is supported on the current platform.
   static bool supported(SvgElement element) => JS('bool', '#.externalResourcesRequired !== undefined && #.externalResourcesRequired.animVal !== undefined', element, element);
 
-  AnimatedBoolean externalResourcesRequired;
+  final AnimatedBoolean externalResourcesRequired;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -3012,15 +3012,15 @@
   // To suppress missing implicit constructor warnings.
   factory FilterPrimitiveStandardAttributes._() { throw new UnsupportedError("Not supported"); }
 
-  AnimatedLength height;
+  final AnimatedLength height;
 
-  AnimatedString result;
+  final AnimatedString result;
 
-  AnimatedLength width;
+  final AnimatedLength width;
 
-  AnimatedLength x;
+  final AnimatedLength x;
 
-  AnimatedLength y;
+  final AnimatedLength y;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -3034,9 +3034,9 @@
   // To suppress missing implicit constructor warnings.
   factory FitToViewBox._() { throw new UnsupportedError("Not supported"); }
 
-  AnimatedPreserveAspectRatio preserveAspectRatio;
+  final AnimatedPreserveAspectRatio preserveAspectRatio;
 
-  AnimatedRect viewBox;
+  final AnimatedRect viewBox;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -3166,6 +3166,11 @@
   @Experimental() // untriaged
   Matrix getScreenCtm() native;
 
+  @DomName('SVGGraphicsElement.getStrokeBBox')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Rect getStrokeBBox() native;
+
   @DomName('SVGGraphicsElement.getTransformToElement')
   @DocsEditable()
   @Experimental() // untriaged
@@ -5418,7 +5423,7 @@
 
 @DomName('SVGElement')
 @Unstable()
-class SvgElement extends Element native "SVGElement" {
+class SvgElement extends Element implements GlobalEventHandlers native "SVGElement" {
   static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
 
   factory SvgElement.tag(String tag) =>
@@ -5538,6 +5543,261 @@
   }
   // To suppress missing implicit constructor warnings.
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('SVGElement.abortEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
+
+  @DomName('SVGElement.blurEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
+
+  @DomName('SVGElement.canplayEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');
+
+  @DomName('SVGElement.canplaythroughEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');
+
+  @DomName('SVGElement.changeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
+
+  @DomName('SVGElement.clickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
+
+  @DomName('SVGElement.contextmenuEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('SVGElement.dblclickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
+
+  @DomName('SVGElement.dragEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
+
+  @DomName('SVGElement.dragendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
+
+  @DomName('SVGElement.dragenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
+
+  @DomName('SVGElement.dragleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
+
+  @DomName('SVGElement.dragoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
+
+  @DomName('SVGElement.dragstartEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
+
+  @DomName('SVGElement.dropEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
+
+  @DomName('SVGElement.durationchangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');
+
+  @DomName('SVGElement.emptiedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');
+
+  @DomName('SVGElement.endedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
+
+  @DomName('SVGElement.errorEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('SVGElement.focusEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
+
+  @DomName('SVGElement.inputEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
+
+  @DomName('SVGElement.invalidEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
+
+  @DomName('SVGElement.keydownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
+
+  @DomName('SVGElement.keypressEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
+
+  @DomName('SVGElement.keyupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
+
+  @DomName('SVGElement.loadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('SVGElement.loadeddataEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');
+
+  @DomName('SVGElement.loadedmetadataEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');
+
+  @DomName('SVGElement.mousedownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
+
+  @DomName('SVGElement.mouseenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');
+
+  @DomName('SVGElement.mouseleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');
+
+  @DomName('SVGElement.mousemoveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
+
+  @DomName('SVGElement.mouseoutEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
+
+  @DomName('SVGElement.mouseoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
+
+  @DomName('SVGElement.mouseupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
+
+  @DomName('SVGElement.mousewheelEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
+
+  @DomName('SVGElement.pauseEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');
+
+  @DomName('SVGElement.playEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');
+
+  @DomName('SVGElement.playingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');
+
+  @DomName('SVGElement.ratechangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');
+
+  @DomName('SVGElement.resetEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
+
+  @DomName('SVGElement.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
+  @DomName('SVGElement.seekedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');
+
+  @DomName('SVGElement.seekingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');
+
+  @DomName('SVGElement.selectEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
+
+  @DomName('SVGElement.stalledEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');
+
+  @DomName('SVGElement.submitEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
+
+  @DomName('SVGElement.suspendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');
+
+  @DomName('SVGElement.timeupdateEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');
+
+  @DomName('SVGElement.volumechangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');
+
+  @DomName('SVGElement.waitingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');
   /**
    * Constructor instantiated by the DOM when a custom element has been created.
    *
@@ -5574,6 +5834,261 @@
   @Experimental() // untriaged
   String xmlspace;
 
+  @DomName('SVGElement.onabort')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onAbort => abortEvent.forElement(this);
+
+  @DomName('SVGElement.onblur')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onBlur => blurEvent.forElement(this);
+
+  @DomName('SVGElement.oncanplay')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);
+
+  @DomName('SVGElement.oncanplaythrough')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);
+
+  @DomName('SVGElement.onchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onChange => changeEvent.forElement(this);
+
+  @DomName('SVGElement.onclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);
+
+  @DomName('SVGElement.oncontextmenu')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);
+
+  @DomName('SVGElement.ondblclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
+
+  @DomName('SVGElement.ondrag')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);
+
+  @DomName('SVGElement.ondragend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);
+
+  @DomName('SVGElement.ondragenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);
+
+  @DomName('SVGElement.ondragleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);
+
+  @DomName('SVGElement.ondragover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);
+
+  @DomName('SVGElement.ondragstart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);
+
+  @DomName('SVGElement.ondrop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);
+
+  @DomName('SVGElement.ondurationchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);
+
+  @DomName('SVGElement.onemptied')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);
+
+  @DomName('SVGElement.onended')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onEnded => endedEvent.forElement(this);
+
+  @DomName('SVGElement.onerror')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onError => errorEvent.forElement(this);
+
+  @DomName('SVGElement.onfocus')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onFocus => focusEvent.forElement(this);
+
+  @DomName('SVGElement.oninput')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onInput => inputEvent.forElement(this);
+
+  @DomName('SVGElement.oninvalid')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);
+
+  @DomName('SVGElement.onkeydown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);
+
+  @DomName('SVGElement.onkeypress')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);
+
+  @DomName('SVGElement.onkeyup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);
+
+  @DomName('SVGElement.onload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoad => loadEvent.forElement(this);
+
+  @DomName('SVGElement.onloadeddata')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);
+
+  @DomName('SVGElement.onloadedmetadata')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);
+
+  @DomName('SVGElement.onmousedown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);
+
+  @DomName('SVGElement.onmousemove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseout')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);
+
+  @DomName('SVGElement.onmousewheel')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);
+
+  @DomName('SVGElement.onpause')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPause => pauseEvent.forElement(this);
+
+  @DomName('SVGElement.onplay')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPlay => playEvent.forElement(this);
+
+  @DomName('SVGElement.onplaying')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPlaying => playingEvent.forElement(this);
+
+  @DomName('SVGElement.onratechange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);
+
+  @DomName('SVGElement.onreset')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onReset => resetEvent.forElement(this);
+
+  @DomName('SVGElement.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
+  @DomName('SVGElement.onseeked')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);
+
+  @DomName('SVGElement.onseeking')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);
+
+  @DomName('SVGElement.onselect')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSelect => selectEvent.forElement(this);
+
+  @DomName('SVGElement.onstalled')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onStalled => stalledEvent.forElement(this);
+
+  @DomName('SVGElement.onsubmit')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSubmit => submitEvent.forElement(this);
+
+  @DomName('SVGElement.onsuspend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);
+
+  @DomName('SVGElement.ontimeupdate')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);
+
+  @DomName('SVGElement.onvolumechange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);
+
+  @DomName('SVGElement.onwaiting')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5886,11 +6401,11 @@
   // To suppress missing implicit constructor warnings.
   factory Tests._() { throw new UnsupportedError("Not supported"); }
 
-  StringList requiredExtensions;
+  final StringList requiredExtensions;
 
-  StringList requiredFeatures;
+  final StringList requiredFeatures;
 
-  StringList systemLanguage;
+  final StringList systemLanguage;
 
   bool hasExtension(String extension);
 }
@@ -6327,7 +6842,7 @@
   // To suppress missing implicit constructor warnings.
   factory UriReference._() { throw new UnsupportedError("Not supported"); }
 
-  AnimatedString href;
+  final AnimatedString href;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index b6cb36e..e257800 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -2,7 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
@@ -3327,6 +3327,11 @@
   @Experimental() // untriaged
   Matrix getScreenCtm() native "SVGGraphicsElement_getScreenCTM_Callback";
 
+  @DomName('SVGGraphicsElement.getStrokeBBox')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Rect getStrokeBBox() native "SVGGraphicsElement_getStrokeBBox_Callback";
+
   @DomName('SVGGraphicsElement.getTransformToElement')
   @DocsEditable()
   @Experimental() // untriaged
@@ -5996,7 +6001,7 @@
 
 @DomName('SVGElement')
 @Unstable()
-class SvgElement extends Element {
+class SvgElement extends Element implements GlobalEventHandlers {
   static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
 
   factory SvgElement.tag(String tag) =>
@@ -6116,6 +6121,261 @@
   }
   // To suppress missing implicit constructor warnings.
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('SVGElement.abortEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
+
+  @DomName('SVGElement.blurEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
+
+  @DomName('SVGElement.canplayEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');
+
+  @DomName('SVGElement.canplaythroughEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');
+
+  @DomName('SVGElement.changeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
+
+  @DomName('SVGElement.clickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
+
+  @DomName('SVGElement.contextmenuEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
+
+  @DomName('SVGElement.dblclickEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
+
+  @DomName('SVGElement.dragEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
+
+  @DomName('SVGElement.dragendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
+
+  @DomName('SVGElement.dragenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
+
+  @DomName('SVGElement.dragleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
+
+  @DomName('SVGElement.dragoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
+
+  @DomName('SVGElement.dragstartEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
+
+  @DomName('SVGElement.dropEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
+
+  @DomName('SVGElement.durationchangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');
+
+  @DomName('SVGElement.emptiedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');
+
+  @DomName('SVGElement.endedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
+
+  @DomName('SVGElement.errorEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('SVGElement.focusEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
+
+  @DomName('SVGElement.inputEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
+
+  @DomName('SVGElement.invalidEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
+
+  @DomName('SVGElement.keydownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
+
+  @DomName('SVGElement.keypressEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
+
+  @DomName('SVGElement.keyupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
+
+  @DomName('SVGElement.loadEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('SVGElement.loadeddataEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');
+
+  @DomName('SVGElement.loadedmetadataEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');
+
+  @DomName('SVGElement.mousedownEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
+
+  @DomName('SVGElement.mouseenterEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');
+
+  @DomName('SVGElement.mouseleaveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');
+
+  @DomName('SVGElement.mousemoveEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
+
+  @DomName('SVGElement.mouseoutEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
+
+  @DomName('SVGElement.mouseoverEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
+
+  @DomName('SVGElement.mouseupEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
+
+  @DomName('SVGElement.mousewheelEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
+
+  @DomName('SVGElement.pauseEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');
+
+  @DomName('SVGElement.playEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');
+
+  @DomName('SVGElement.playingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');
+
+  @DomName('SVGElement.ratechangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');
+
+  @DomName('SVGElement.resetEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
+
+  @DomName('SVGElement.scrollEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
+
+  @DomName('SVGElement.seekedEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');
+
+  @DomName('SVGElement.seekingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');
+
+  @DomName('SVGElement.selectEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
+
+  @DomName('SVGElement.stalledEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');
+
+  @DomName('SVGElement.submitEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
+
+  @DomName('SVGElement.suspendEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');
+
+  @DomName('SVGElement.timeupdateEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');
+
+  @DomName('SVGElement.volumechangeEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');
+
+  @DomName('SVGElement.waitingEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');
   /**
    * Constructor instantiated by the DOM when a custom element has been created.
    *
@@ -6169,6 +6429,261 @@
   @Experimental() // untriaged
   void set xmlspace(String value) native "SVGElement_xmlspace_Setter";
 
+  @DomName('SVGElement.onabort')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onAbort => abortEvent.forElement(this);
+
+  @DomName('SVGElement.onblur')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onBlur => blurEvent.forElement(this);
+
+  @DomName('SVGElement.oncanplay')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);
+
+  @DomName('SVGElement.oncanplaythrough')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);
+
+  @DomName('SVGElement.onchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onChange => changeEvent.forElement(this);
+
+  @DomName('SVGElement.onclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);
+
+  @DomName('SVGElement.oncontextmenu')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);
+
+  @DomName('SVGElement.ondblclick')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
+
+  @DomName('SVGElement.ondrag')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);
+
+  @DomName('SVGElement.ondragend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);
+
+  @DomName('SVGElement.ondragenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);
+
+  @DomName('SVGElement.ondragleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);
+
+  @DomName('SVGElement.ondragover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);
+
+  @DomName('SVGElement.ondragstart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);
+
+  @DomName('SVGElement.ondrop')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);
+
+  @DomName('SVGElement.ondurationchange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);
+
+  @DomName('SVGElement.onemptied')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);
+
+  @DomName('SVGElement.onended')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onEnded => endedEvent.forElement(this);
+
+  @DomName('SVGElement.onerror')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onError => errorEvent.forElement(this);
+
+  @DomName('SVGElement.onfocus')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onFocus => focusEvent.forElement(this);
+
+  @DomName('SVGElement.oninput')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onInput => inputEvent.forElement(this);
+
+  @DomName('SVGElement.oninvalid')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);
+
+  @DomName('SVGElement.onkeydown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);
+
+  @DomName('SVGElement.onkeypress')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);
+
+  @DomName('SVGElement.onkeyup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);
+
+  @DomName('SVGElement.onload')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoad => loadEvent.forElement(this);
+
+  @DomName('SVGElement.onloadeddata')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);
+
+  @DomName('SVGElement.onloadedmetadata')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);
+
+  @DomName('SVGElement.onmousedown')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseenter')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseleave')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);
+
+  @DomName('SVGElement.onmousemove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseout')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseover')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);
+
+  @DomName('SVGElement.onmouseup')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);
+
+  @DomName('SVGElement.onmousewheel')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);
+
+  @DomName('SVGElement.onpause')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPause => pauseEvent.forElement(this);
+
+  @DomName('SVGElement.onplay')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPlay => playEvent.forElement(this);
+
+  @DomName('SVGElement.onplaying')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onPlaying => playingEvent.forElement(this);
+
+  @DomName('SVGElement.onratechange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);
+
+  @DomName('SVGElement.onreset')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onReset => resetEvent.forElement(this);
+
+  @DomName('SVGElement.onscroll')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onScroll => scrollEvent.forElement(this);
+
+  @DomName('SVGElement.onseeked')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);
+
+  @DomName('SVGElement.onseeking')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);
+
+  @DomName('SVGElement.onselect')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSelect => selectEvent.forElement(this);
+
+  @DomName('SVGElement.onstalled')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onStalled => stalledEvent.forElement(this);
+
+  @DomName('SVGElement.onsubmit')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSubmit => submitEvent.forElement(this);
+
+  @DomName('SVGElement.onsuspend')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);
+
+  @DomName('SVGElement.ontimeupdate')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);
+
+  @DomName('SVGElement.onvolumechange')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);
+
+  @DomName('SVGElement.onwaiting')
+  @DocsEditable()
+  @Experimental() // untriaged
+  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index 83044ce..92716d9 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -9,7 +9,7 @@
 library dart.typed_data;
 
 import 'dart:collection';
-import 'dart:_collection-dev';
+import 'dart:_internal';
 import 'dart:_interceptors' show JSIndexable, JSUInt32, JSUInt31;
 import 'dart:_js_helper'
     show Creates, JavaScriptIndexingBehavior, JSName, Null, Returns;
@@ -100,6 +100,30 @@
 }
 
 
+// Validates the unnamed constructor length argument.  Checking is necessary
+// because passing unvalidated values to the native constructors can cause
+// conversions or create views.
+int _checkLength(length) {
+  if (length is! int) throw new ArgumentError('Invalid length $length');
+  return length;
+}
+
+// Validates `.view` constructor arguments.  Checking is necessary because
+// passing unvalidated values to the native constructors can cause conversions
+// (e.g. String arguments) or create typed data objects that are not actually
+// views of the input.
+void _checkViewArguments(buffer, offsetInBytes, length) {
+  if (buffer is! ByteBuffer) {
+    throw new ArgumentError('Invalid view buffer');
+  }
+  if (offsetInBytes is! int) {
+    throw new ArgumentError('Invalid view offsetInBytes $offsetInBytes');
+  }
+  if (length != null && length is! int) {
+    throw new ArgumentError('Invalid view length $length');
+  }
+}
+
 // Ensures that [list] is a JavaScript Array or a typed array.  If necessary,
 // returns a copy of the list.
 List _ensureNativeList(List list) {
@@ -136,7 +160,7 @@
    * Creates a [ByteData] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory ByteData(int length) => _create1(length);
+  factory ByteData(int length) => _create1(_checkLength(length));
 
   /**
    * Creates an [ByteData] _view_ of the specified region in the specified
@@ -151,10 +175,12 @@
    * the length of [buffer].
    */
   factory ByteData.view(ByteBuffer buffer,
-                        [int byteOffset = 0, int byteLength]) =>
-      byteLength == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, byteLength);
+                        [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   /**
    * Returns the floating point number represented by the four bytes at
@@ -532,13 +558,13 @@
    * Creates a [Float32List] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Float32List(int length) => _create1(length);
+  factory Float32List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Float32List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Float32List.fromList(List<num> list) =>
+  factory Float32List.fromList(List<double> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -557,10 +583,12 @@
    * BYTES_PER_ELEMENT.
    */
   factory Float32List.view(ByteBuffer buffer,
-                           [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+                           [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 4;
 
@@ -602,13 +630,13 @@
    * Creates a [Float64List] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Float64List(int length) => _create1(length);
+  factory Float64List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Float64List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Float64List.fromList(List<num> list) =>
+  factory Float64List.fromList(List<double> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -627,10 +655,12 @@
    * BYTES_PER_ELEMENT.
    */
   factory Float64List.view(ByteBuffer buffer,
-                           [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+                           [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 8;
 
@@ -674,13 +704,13 @@
    * Creates an [Int16List] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Int16List(int length) => _create1(length);
+  factory Int16List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Int16List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Int16List.fromList(List<num> list) =>
+  factory Int16List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -698,10 +728,13 @@
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * BYTES_PER_ELEMENT.
    */
-  factory Int16List.view(ByteBuffer buffer, [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+  factory Int16List.view(ByteBuffer buffer,
+                         [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 2;
 
@@ -742,13 +775,13 @@
    * Creates an [Int32List] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Int32List(int length) => _create1(length);
+  factory Int32List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Int32List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Int32List.fromList(List<num> list) =>
+  factory Int32List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -766,10 +799,13 @@
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * BYTES_PER_ELEMENT.
    */
-  factory Int32List.view(ByteBuffer buffer, [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+  factory Int32List.view(ByteBuffer buffer,
+                         [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 4;
 
@@ -810,13 +846,13 @@
    * Creates an [Int8List] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Int8List(int length) => _create1(length);
+  factory Int8List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Int8List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Int8List.fromList(List<num> list) =>
+  factory Int8List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -831,10 +867,13 @@
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
    */
-  factory Int8List.view(ByteBuffer buffer, [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+  factory Int8List.view(ByteBuffer buffer,
+                        [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 1;
 
@@ -875,13 +914,13 @@
    * Creates a [Uint16List] of the specified length (in elements), all
    * of whose elements are initially zero.
    */
-  factory Uint16List(int length) => _create1(length);
+  factory Uint16List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Uint16List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Uint16List.fromList(List<num> list) =>
+  factory Uint16List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -900,10 +939,12 @@
    * BYTES_PER_ELEMENT.
    */
   factory Uint16List.view(ByteBuffer buffer,
-                          [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+                          [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 2;
 
@@ -944,13 +985,13 @@
    * Creates a [Uint32List] of the specified length (in elements), all
    * of whose elements are initially zero.
    */
-  factory Uint32List(int length) => _create1(length);
+  factory Uint32List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Uint32List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Uint32List.fromList(List<num> list) =>
+  factory Uint32List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -969,10 +1010,12 @@
    * BYTES_PER_ELEMENT.
    */
   factory Uint32List.view(ByteBuffer buffer,
-                          [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+                          [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 4;
 
@@ -1015,13 +1058,13 @@
    * Creates a [Uint8ClampedList] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Uint8ClampedList(int length) => _create1(length);
+  factory Uint8ClampedList(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Uint8ClampedList] of the same size as the [elements]
    * list and copies over the values clamping when needed.
    */
-  factory Uint8ClampedList.fromList(List<num> list) =>
+  factory Uint8ClampedList.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -1037,10 +1080,12 @@
    * the length of [buffer].
    */
   factory Uint8ClampedList.view(ByteBuffer buffer,
-                                [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+                                [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 1;
 
@@ -1089,13 +1134,13 @@
    * Creates a [Uint8List] of the specified length (in elements), all of
    * whose elements are initially zero.
    */
-  factory Uint8List(int length) => _create1(length);
+  factory Uint8List(int length) => _create1(_checkLength(length));
 
   /**
    * Creates a [Uint8List] with the same size as the [elements] list
    * and copies over the elements.
    */
-  factory Uint8List.fromList(List<num> list) =>
+  factory Uint8List.fromList(List<int> list) =>
       _create1(_ensureNativeList(list));
 
   /**
@@ -1111,10 +1156,12 @@
    * the length of [buffer].
    */
   factory Uint8List.view(ByteBuffer buffer,
-                         [int byteOffset = 0, int length]) =>
-      length == null
-          ? _create2(buffer, byteOffset)
-          : _create3(buffer, byteOffset, length);
+                         [int offsetInBytes = 0, int length]) {
+    _checkViewArguments(buffer, offsetInBytes, length);
+    return length == null
+        ? _create2(buffer, offsetInBytes)
+        : _create3(buffer, offsetInBytes, length);
+  }
 
   static const int BYTES_PER_ELEMENT = 1;
 
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 9d37eb6..413eff3 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -5,8 +5,6 @@
 library dart.typed_data;
 
 import 'dart:collection';
-import 'dart:_collection-dev';
-import 'dart:math' show Random;
 
 /**
  * A sequence of bytes underlying a typed data object.
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 4556a90..b3e88e9 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -5,7 +5,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:typed_data';
@@ -956,11 +956,11 @@
 
   @DomName('OscillatorNode.start')
   @DocsEditable()
-  void start(num when) native;
+  void start([num when]) native;
 
   @DomName('OscillatorNode.stop')
   @DocsEditable()
-  void stop(num when) native;
+  void stop([num when]) native;
 
   /// Stream of `ended` events handled by this [OscillatorNode].
   @DomName('OscillatorNode.onended')
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 5157bc3..8e581b0 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -2,7 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
@@ -230,31 +230,43 @@
   @DocsEditable()
   void noteOn(num when) native "AudioBufferSourceNode_noteOn_Callback";
 
-  void start(num when, [num grainOffset, num grainDuration]) {
-    if ((when is num || when == null) && grainOffset == null && grainDuration == null) {
-      _start_1(when);
+  void start([num when, num grainOffset, num grainDuration]) {
+    if (grainDuration != null) {
+      _start_1(when, grainOffset, grainDuration);
       return;
     }
-    if ((grainOffset is num || grainOffset == null) && (when is num || when == null) && grainDuration == null) {
+    if (grainOffset != null) {
       _start_2(when, grainOffset);
       return;
     }
-    if ((grainDuration is num || grainDuration == null) && (grainOffset is num || grainOffset == null) && (when is num || when == null)) {
-      _start_3(when, grainOffset, grainDuration);
+    if (when != null) {
+      _start_3(when);
       return;
     }
-    throw new ArgumentError("Incorrect number or type of arguments");
+    _start_4();
+    return;
   }
 
-  void _start_1(when) native "AudioBufferSourceNode__start_1_Callback";
+  void _start_1(when, grainOffset, grainDuration) native "AudioBufferSourceNode__start_1_Callback";
 
   void _start_2(when, grainOffset) native "AudioBufferSourceNode__start_2_Callback";
 
-  void _start_3(when, grainOffset, grainDuration) native "AudioBufferSourceNode__start_3_Callback";
+  void _start_3(when) native "AudioBufferSourceNode__start_3_Callback";
 
-  @DomName('AudioBufferSourceNode.stop')
-  @DocsEditable()
-  void stop(num when) native "AudioBufferSourceNode_stop_Callback";
+  void _start_4() native "AudioBufferSourceNode__start_4_Callback";
+
+  void stop([num when]) {
+    if (when != null) {
+      _stop_1(when);
+      return;
+    }
+    _stop_2();
+    return;
+  }
+
+  void _stop_1(when) native "AudioBufferSourceNode__stop_1_Callback";
+
+  void _stop_2() native "AudioBufferSourceNode__stop_2_Callback";
 
   /// Stream of `ended` events handled by this [AudioBufferSourceNode].
   @DomName('AudioBufferSourceNode.onended')
@@ -287,10 +299,12 @@
 
   @DomName('AudioContext.AudioContext')
   @DocsEditable()
-  factory AudioContext() => _create();
+  factory AudioContext() {
+    return AudioContext._create_1();
+  }
 
   @DocsEditable()
-  static AudioContext _create() native "AudioContext_constructorCallback";
+  static AudioContext _create_1() native "AudioContext__create_1constructorCallback";
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -436,14 +450,17 @@
   @Experimental() // untriaged
   PeriodicWave createPeriodicWave(Float32List real, Float32List imag) native "AudioContext_createPeriodicWave_Callback";
 
-  ScriptProcessorNode createScriptProcessor(int bufferSize, [int numberOfInputChannels, int numberOfOutputChannels]) {
+  ScriptProcessorNode createScriptProcessor([int bufferSize, int numberOfInputChannels, int numberOfOutputChannels]) {
     if (numberOfOutputChannels != null) {
       return _createScriptProcessor_1(bufferSize, numberOfInputChannels, numberOfOutputChannels);
     }
     if (numberOfInputChannels != null) {
       return _createScriptProcessor_2(bufferSize, numberOfInputChannels);
     }
-    return _createScriptProcessor_3(bufferSize);
+    if (bufferSize != null) {
+      return _createScriptProcessor_3(bufferSize);
+    }
+    return _createScriptProcessor_4();
   }
 
   ScriptProcessorNode _createScriptProcessor_1(bufferSize, numberOfInputChannels, numberOfOutputChannels) native "AudioContext__createScriptProcessor_1_Callback";
@@ -452,6 +469,8 @@
 
   ScriptProcessorNode _createScriptProcessor_3(bufferSize) native "AudioContext__createScriptProcessor_3_Callback";
 
+  ScriptProcessorNode _createScriptProcessor_4() native "AudioContext__createScriptProcessor_4_Callback";
+
   @DomName('AudioContext.createWaveShaper')
   @DocsEditable()
   WaveShaperNode createWaveShaper() native "AudioContext_createWaveShaper_Callback";
@@ -1158,13 +1177,31 @@
   @Experimental() // untriaged
   void setPeriodicWave(PeriodicWave periodicWave) native "OscillatorNode_setPeriodicWave_Callback";
 
-  @DomName('OscillatorNode.start')
-  @DocsEditable()
-  void start(num when) native "OscillatorNode_start_Callback";
+  void start([num when]) {
+    if (when != null) {
+      _start_1(when);
+      return;
+    }
+    _start_2();
+    return;
+  }
 
-  @DomName('OscillatorNode.stop')
-  @DocsEditable()
-  void stop(num when) native "OscillatorNode_stop_Callback";
+  void _start_1(when) native "OscillatorNode__start_1_Callback";
+
+  void _start_2() native "OscillatorNode__start_2_Callback";
+
+  void stop([num when]) {
+    if (when != null) {
+      _stop_1(when);
+      return;
+    }
+    _stop_2();
+    return;
+  }
+
+  void _stop_1(when) native "OscillatorNode__stop_1_Callback";
+
+  void _stop_2() native "OscillatorNode__stop_2_Callback";
 
   /// Stream of `ended` events handled by this [OscillatorNode].
   @DomName('OscillatorNode.onended')
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 4416a72..d0d67a3 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -4,7 +4,7 @@
 library dart.dom.web_gl;
 
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:typed_data';
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index a3c4286..e19200f 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -2,7 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 668bdef..de33d88 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -12,7 +12,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show convertDartClosureToJS, Creates, JSName;
diff --git a/sdk/lib/web_sql/dartium/web_sql_dartium.dart b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
index 62f2497..5917aef 100644
--- a/sdk/lib/web_sql/dartium/web_sql_dartium.dart
+++ b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
@@ -12,7 +12,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/site/try/Makefile b/site/try/Makefile
new file mode 100644
index 0000000..61e2b4e
--- /dev/null
+++ b/site/try/Makefile
@@ -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
+
+# TODO(ahe): Convert this to GYP.
+
+all:
+	../../sdk/bin/dart -Dlist_all_libraries=true ../../sdk/lib/_internal/compiler/samples/jsonify/jsonify.dart sdk.dart
+	../../sdk/bin/dart jsonify.dart > sdk.json
+	../../sdk/bin/dart2js -Denable_ir=false leap.dart -oleap.dart.js
diff --git a/site/try/README b/site/try/README
new file mode 100644
index 0000000..a23e257
--- /dev/null
+++ b/site/try/README
@@ -0,0 +1 @@
+See https://code.google.com/p/dart/wiki/TryDart.
diff --git a/site/try/add_time_stamp.py b/site/try/add_time_stamp.py
new file mode 100644
index 0000000..adc0612
--- /dev/null
+++ b/site/try/add_time_stamp.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for 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 datetime
+import sys
+
+def Main():
+  (_, input_file_name, output_file_name) = sys.argv
+  if not input_file_name or not output_file_name:
+    raise Exception('Missing argument')
+
+  timestamp = str(datetime.datetime.now())
+
+  with open(input_file_name, 'r') as input_file:
+    with open(output_file_name, 'w') as output_file:
+      output_file.write(input_file.read().replace('@@TIMESTAMP@@', timestamp))
+
+
+if __name__ == '__main__':
+  sys.exit(Main())
diff --git a/site/try/app.yaml b/site/try/app.yaml
new file mode 100644
index 0000000..24ae310
--- /dev/null
+++ b/site/try/app.yaml
@@ -0,0 +1,64 @@
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# App Engine configuration, see:
+# https://developers.google.com/appengine/docs/python/config/appconfig
+
+# The version number should be something like rSVN_REVISION.
+version: remember to edit app.yaml before deploying
+# This version name is used to create a new host, for example,
+# http://r31824.try-dart-lang.appspot.com/, which can be tested before going
+# live at http://try.dartlang.org/.  This is controlled from
+# https://appengine.google.com/deployment?&app_id=s~try-dart-lang
+
+application: try-dart-lang
+runtime: python27
+api_version: 1
+threadsafe: yes
+
+# Set "Cache-Control" and "Expires" HTTP headers to only cache for one second.
+# We do this because we frequently push new changes and rely on AppCache for
+# caching.  Once files are installed in AppCache, the site launches
+# immediately.
+#
+# Problem: PageSpeed Insights doesn't realize that we use AppCache and keeps
+# nagging about caching.
+# Solution: Ignore its advice about "Leverage browser caching".
+default_expiration: 1s
+
+handlers:
+
+- url: /favicon\.ico
+  static_files: favicon.ico
+  upload: favicon\.ico
+  secure: never
+
+- url: /
+  static_files: index.html
+  upload: index.html
+  secure: never
+
+- url: /nossl.appcache
+  static_files: nossl.appcache
+  upload: nossl.appcache
+  secure: never
+
+- url: /(.*\.(html|js|png|css|dart|json))
+  static_files: \1
+  upload: (.*\.(html|js|png|css|dart|json))
+  secure: never
+
+- url: /css/fonts/fontawesome-webfont.woff
+  static_files: fontawesome-webfont.woff
+  upload: fontawesome-webfont.woff
+  secure: never
+
+- url: .*
+  static_files: not_found.html
+  upload: not_found.html
+  secure: never
+
+libraries:
+- name: webapp2
+  version: "2.5.2"
diff --git a/site/try/bugs/isolate_worker_bug.dart b/site/try/bugs/isolate_worker_bug.dart
new file mode 100644
index 0000000..0f46014
--- /dev/null
+++ b/site/try/bugs/isolate_worker_bug.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Successful test: output div contains "future!".
+
+import 'dart:async';
+
+const greeting = "Hello, cool people doing nice things!";
+
+// Prints a greeting.
+void main() {
+  print(greeting);
+
+  new Future(() => print("future!"));
+}
diff --git a/site/try/build_try.gyp b/site/try/build_try.gyp
new file mode 100644
index 0000000..1122ba0
--- /dev/null
+++ b/site/try/build_try.gyp
@@ -0,0 +1,121 @@
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE
+
+{
+  'targets': [
+    {
+      'target_name': 'try_site',
+      'type': 'none',
+      'dependencies': [
+        '../../runtime/dart-runtime.gyp:dart',
+        # Concern: there should really be a dependency on
+        # ../../dart.gyp:create_sdk, but this is reported as a cycle by GYP.
+      ],
+      'variables': {
+        'try_dart_static_files': [
+          'index.html',
+          'dartlang-style.css',
+          'iframe.html',
+          'iframe.js',
+          'dart-icon.png', # iOS icon.
+          'dart-iphone5.png', # iPhone 5 splash screen.
+          'dart-icon-196px.png', # Android icon.
+          'try-dart-screenshot.png', # Google+ screen shot.
+
+          '../../third_party/font-awesome/font-awesome-4.0.3/'
+          'fonts/fontawesome-webfont.woff',
+
+          '../../sdk/lib/_internal/dartdoc/static/favicon.ico',
+
+          '<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
+          '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
+        ],
+      },
+      'actions': [
+        {
+          'action_name': 'sdk_json',
+          'message': 'Creating sdk.json',
+          'inputs': [
+
+            # Depending on this file ensures that the SDK is built before this
+            # action is executed.
+            '<(PRODUCT_DIR)/dart-sdk/README',
+
+            # This dependency is redundant for now, as this directory is
+            # implicitly part of the dependencies for dart-sdk/README.
+            '<!@(["python", "../../tools/list_files.py", "\\.dart$", '
+                 '"../../sdk/lib/_internal/compiler/samples/jsonify"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
+          ],
+          'action': [
+
+            '<(PRODUCT_DIR)/dart-sdk/bin/'
+            '<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+
+            '-Dlist_all_libraries=true',
+            '-DoutputJson=true',
+            '../../sdk/lib/_internal/compiler/samples/jsonify/jsonify.dart',
+            '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
+          ],
+        },
+        {
+          'action_name': 'compile',
+          'message': 'Creating leap.dart.js',
+          'inputs': [
+            # Depending on this file ensures that the SDK is built before this
+            # action is executed.
+            '<(PRODUCT_DIR)/dart-sdk/README',
+
+            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "src"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
+          ],
+          'action': [
+            '<(PRODUCT_DIR)/dart-sdk/bin/dart2js',
+            '-v',
+            '-Denable_ir=false',
+            'src/leap.dart',
+            '-o<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
+          ],
+        },
+        {
+          'action_name': 'nossl_appcache',
+          'message': 'Creating nossl.appcache',
+          'inputs': [
+            'add_time_stamp.py',
+            'nossl.appcache',
+            '<@(try_dart_static_files)',
+            'build_try.gyp', # If the list of files changed.
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/nossl.appcache',
+          ],
+          # Try Dart! uses AppCache. Cached files are only validated when the
+          # manifest changes (not its timestamp, but its actual contents).
+          'action': [
+            'python',
+            'add_time_stamp.py',
+            'nossl.appcache',
+            '<(SHARED_INTERMEDIATE_DIR)/nossl.appcache',
+          ],
+        },
+      ],
+      'copies': [
+        {
+          # Destination directory.
+          'destination': '<(PRODUCT_DIR)/try_dartlang_org/',
+          # List of files to be copied (creates implicit build dependencies).
+          'files': [
+            'app.yaml',
+            '<@(try_dart_static_files)',
+            '<(SHARED_INTERMEDIATE_DIR)/nossl.appcache',
+          ],
+        },
+      ],
+    },
+  ],
+}
diff --git a/site/try/create_manifest.sh b/site/try/create_manifest.sh
new file mode 100755
index 0000000..c445833
--- /dev/null
+++ b/site/try/create_manifest.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Script to create AppCache manifest.
+
+echo CACHE MANIFEST
+
+date +'# %s'
+
+echo CACHE:
+
+PKG_DIR="$(cd $(dirname ${0})/../pkg ; pwd)"
+SDK_DIR="$(cd $(dirname ${0})/../sdk ; pwd)"
+LIVE_DIR="$(cd $(dirname ${0})/../web_editor ; pwd)"
+
+echo ${PKG_DIR}/browser/lib/dart.js | sed -e "s|$(pwd)/||"
+
+# find ${SDK_DIR} \
+#     \( -name dartdoc -o -name pub -o -name dartium \) -prune \
+#     -o -name \*.dart -print \
+#     | sed -e "s|$(pwd)/||"
+
+find ${LIVE_DIR} \
+    \( -name \*~ \) -prune \
+    -o -type f -print | sed -e "s|$(pwd)/||"
+
+echo iframe.html
+echo iframe.js
+echo dart-icon.png
+echo dart-iphone5.png
+
+echo NETWORK:
+echo '*'
diff --git a/site/try/dart-icon-196px.png b/site/try/dart-icon-196px.png
new file mode 100644
index 0000000..fc454d7
--- /dev/null
+++ b/site/try/dart-icon-196px.png
Binary files differ
diff --git a/site/try/dart-icon.png b/site/try/dart-icon.png
new file mode 100644
index 0000000..bc2c9f4
--- /dev/null
+++ b/site/try/dart-icon.png
Binary files differ
diff --git a/site/try/dart-iphone5.png b/site/try/dart-iphone5.png
new file mode 100644
index 0000000..9b2144c
--- /dev/null
+++ b/site/try/dart-iphone5.png
Binary files differ
diff --git a/site/try/dartlang-style.css b/site/try/dartlang-style.css
new file mode 100644
index 0000000..d890ec6
--- /dev/null
+++ b/site/try/dartlang-style.css
@@ -0,0 +1,38 @@
+@import url(https://fonts.googleapis.com/css?family=Open+Sans:400|Montserrat:400);/*
+ * Bootstrap v2.3.1
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.12766%;*margin-left:2.07447%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.12766%}.row-fluid .span12{width:100%;*width:99.94681%}.row-fluid .offset12{margin-left:104.25532%;*margin-left:104.14894%}.row-fluid .offset12:first-child{margin-left:102.12766%;*margin-left:102.02128%}.row-fluid .span11{width:91.48936%;*width:91.43617%}.row-fluid .offset11{margin-left:95.74468%;*margin-left:95.6383%}.row-fluid .offset11:first-child{margin-left:93.61702%;*margin-left:93.51064%}.row-fluid .span10{width:82.97872%;*width:82.92553%}.row-fluid .offset10{margin-left:87.23404%;*margin-left:87.12766%}.row-fluid .offset10:first-child{margin-left:85.10638%;*margin-left:85.0%}.row-fluid .span9{width:74.46809%;*width:74.41489%}.row-fluid .offset9{margin-left:78.7234%;*margin-left:78.61702%}.row-fluid .offset9:first-child{margin-left:76.59574%;*margin-left:76.48936%}.row-fluid .span8{width:65.95745%;*width:65.90426%}.row-fluid .offset8{margin-left:70.21277%;*margin-left:70.10638%}.row-fluid .offset8:first-child{margin-left:68.08511%;*margin-left:67.97872%}.row-fluid .span7{width:57.44681%;*width:57.39362%}.row-fluid .offset7{margin-left:61.70213%;*margin-left:61.59574%}.row-fluid .offset7:first-child{margin-left:59.57447%;*margin-left:59.46809%}.row-fluid .span6{width:48.93617%;*width:48.88298%}.row-fluid .offset6{margin-left:53.19149%;*margin-left:53.08511%}.row-fluid .offset6:first-child{margin-left:51.06383%;*margin-left:50.95745%}.row-fluid .span5{width:40.42553%;*width:40.37234%}.row-fluid .offset5{margin-left:44.68085%;*margin-left:44.57447%}.row-fluid .offset5:first-child{margin-left:42.55319%;*margin-left:42.44681%}.row-fluid .span4{width:31.91489%;*width:31.8617%}.row-fluid .offset4{margin-left:36.17021%;*margin-left:36.06383%}.row-fluid .offset4:first-child{margin-left:34.04255%;*margin-left:33.93617%}.row-fluid .span3{width:23.40426%;*width:23.35106%}.row-fluid .offset3{margin-left:27.65957%;*margin-left:27.55319%}.row-fluid .offset3:first-child{margin-left:25.53191%;*margin-left:25.42553%}.row-fluid .span2{width:14.89362%;*width:14.84043%}.row-fluid .offset2{margin-left:19.14894%;*margin-left:19.04255%}.row-fluid .offset2:first-child{margin-left:17.02128%;*margin-left:16.91489%}.row-fluid .span1{width:6.38298%;*width:6.32979%}.row-fluid .offset1{margin-left:10.6383%;*margin-left:10.53191%}.row-fluid .offset1:first-child{margin-left:8.51064%;*margin-left:8.40426%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:"";line-height:0}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0}.container-fluid:after{clear:both}p{margin:0 0 11px}.lead{margin-bottom:22px;font-size:21px;font-weight:200;line-height:33px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:gray}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:11px 0;font-family:inherit;font-weight:bold;line-height:22px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:44px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:10px;margin:22px 0 33px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 11px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:22px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;*zoom:1;padding-left:5px;padding-right:5px}dl{margin-bottom:22px}dt,dd{line-height:22px}dt{font-weight:bold}dd{margin-left:11px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:22px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 22px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:22px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:22px;font-style:normal;line-height:22px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap}pre{display:block;padding:10.5px;margin:0 0 11px;font-size:13px;line-height:22px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:22px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 22px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:22px;font-size:21px;line-height:44px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:16.5px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:22px}input,button,select,textarea{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:22px;padding:4px 6px;margin-bottom:11px;font-size:14px;line-height:22px;color:#555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:32px;*margin-top:4px;line-height:32px}select{width:220px;border:1px solid #ccc;background-color:#fff}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);cursor:not-allowed}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:22px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:21px 20px 22px;margin-top:22px;margin-bottom:22px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:11px}.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px}.input-append,.input-prepend{display:inline-block;margin-bottom:11px;vertical-align:middle;font-size:0;white-space:nowrap}.input-append input,.input-append select,.input-append .uneditable-input,.input-append .dropdown-menu,.input-append .popover,.input-prepend input,.input-prepend select,.input-prepend .uneditable-input,.input-prepend .dropdown-menu,.input-prepend .popover{font-size:14px}.input-append input,.input-append select,.input-append .uneditable-input,.input-prepend input,.input-prepend select,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-append select:focus,.input-append .uneditable-input:focus,.input-prepend input:focus,.input-prepend select:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:22px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:22px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-append .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .add-on,.input-prepend .btn,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-search textarea,.form-search select,.form-search .help-inline,.form-search .uneditable-input,.form-search .input-prepend,.form-search .input-append,.form-inline input,.form-inline textarea,.form-inline select,.form-inline .help-inline,.form-inline .uneditable-input,.form-inline .input-prepend,.form-inline .input-append,.form-horizontal input,.form-horizontal textarea,.form-horizontal select,.form-horizontal .help-inline,.form-horizontal .uneditable-input,.form-horizontal .input-prepend,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:11px}legend+.control-group{margin-top:22px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:22px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:11px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:22px}.table th,.table td{padding:8px;line-height:22px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}/*
+ *  Font Awesome 3.0.1
+ *  the iconic font designed for use with Twitter Bootstrap
+ *  -------------------------------------------------------
+ *  The full suite of pictographic icons, examples, and documentation
+ *  can be found at: http://fortawesome.github.com/Font-Awesome/
+ *
+ *  License
+ *  -------------------------------------------------------
+ *  - The Font Awesome font is licensed under the SIL Open Font License - http://scripts.sil.org/OFL
+ *  - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License -
+ *    http://opensource.org/licenses/mit-license.html
+ *  - The Font Awesome pictograms are licensed under the CC BY 3.0 License - http://creativecommons.org/licenses/by/3.0/
+ *  - Attribution is no longer required in Font Awesome 3.0, but much appreciated:
+ *    "Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome"
+ *
+ *  Contact
+ *  -------------------------------------------------------
+ *  Email: dave@davegandy.com
+ *  Twitter: http://twitter.com/fortaweso_me
+ *  Work: Lead Product Designer @ http://kyruus.com
+ */@font-face{font-family:"FontAwesome";src:url('/css/fonts/fontawesome-webfont.eot?v=3.0.1');src:url('/css/fonts/fontawesome-webfont.eot?v=3.0.1?#iefix') format('eot'),url('/css/fonts/fontawesome-webfont.woff?v=3.0.1') format('woff'), url('/css/fonts/fontawesome-webfont.ttf?v=3.0.1') format('truetype');font-weight:normal;font-style:normal}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}a [class^="icon-"],a [class*=" icon-"]{display:inline-block}.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}.btn [class^="icon-"],.btn [class*=" icon-"],.nav [class^="icon-"],.nav [class*=" icon-"]{display:inline}.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}.nav-tabs [class^="icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"],.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class^="icon-"],.nav-pills [class^="icon-"].icon-large,.nav-pills [class*=" icon-"],.nav-pills [class*=" icon-"].icon-large{line-height:.9em}li [class^="icon-"],li [class*=" icon-"],.nav li [class^="icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center}li [class^="icon-"].icon-large,li [class*=" icon-"].icon-large,.nav li [class^="icon-"].icon-large,.nav li [class*=" icon-"].icon-large{width:1.5625em}ul.icons{list-style-type:none;text-indent:-.75em}ul.icons li [class^="icon-"],ul.icons li [class*=" icon-"]{width:.75em}.icon-muted{color:#eee}.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.pull-right{float:right}.pull-left{float:left}[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}.btn [class^="icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}@-moz-document url-prefix(){.icon-spin{height:.9em}.btn .icon-spin{height:auto}.icon-spin.icon-large{height:1.25em}.btn .icon-spin.icon-large{height:.75em}}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-repeat:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-share-alt:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope-alt:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-undo:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-reply:before{content:"\f112"}.icon-github-alt:before{content:"\f113"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:10px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:22px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #0088cc,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0085c7', endColorstr='#0074ad', GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #0088cc,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0085c7', endColorstr='#0074ad', GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:default}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:22px;color:#000;text-shadow:0 1px 0 #fff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:22px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #fff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #fff, #e6e6e6);background-image:-o-linear-gradient(top, #fff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#e3e3e3', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006ecc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #0088cc,#0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0085c7', endColorstr='#0042c7', GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#f9a834;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb24b', endColorstr='#f39106', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#db4f4a;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b,#bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5a56', endColorstr='#b9352e', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462,#51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5ec35e', endColorstr='#4fa04f', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#4ab0ce;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de,#2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#57bedd', endColorstr='#2e93b0', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#373737;background-image:-moz-linear-gradient(top, #444, #222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444), to(#222));background-image:-webkit-linear-gradient(top, #444, #222);background-image:-o-linear-gradient(top, #444, #222);background-image:linear-gradient(to bottom, #444444,#222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#414141', endColorstr='#1f1f1f', GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#090909 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{border-color:transparent;cursor:pointer;color:#08c;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{font-size:0;margin-top:11px;margin-bottom:11px}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);*padding-top:5px;*padding-bottom:5px}.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert,article.up-and-running-contents .note,article.up-and-running-contents .tip,article.up-and-running-contents .caution,article.up-and-running-contents .warning{padding:8px 35px 8px 14px;margin-bottom:22px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,article.up-and-running-contents .note,article.up-and-running-contents .tip,article.up-and-running-contents .caution,article.up-and-running-contents .warning,.alert h4,article.up-and-running-contents .note h4,article.up-and-running-contents .tip h4,article.up-and-running-contents .caution h4,article.up-and-running-contents .warning h4{color:#c09853}.alert h4,article.up-and-running-contents .note h4,article.up-and-running-contents .tip h4,article.up-and-running-contents .caution h4,article.up-and-running-contents .warning h4{margin:0}.alert .close,article.up-and-running-contents .note .close,article.up-and-running-contents .tip .close,article.up-and-running-contents .caution .close,article.up-and-running-contents .warning .close{position:relative;top:-2px;right:-21px;line-height:22px}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847}.alert-success h4{color:#468847}.alert-danger,article.up-and-running-contents .caution,article.up-and-running-contents .warning,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48}.alert-danger h4,article.up-and-running-contents .caution h4,article.up-and-running-contents .warning h4,.alert-error h4{color:#b94a48}.alert-info,article.up-and-running-contents .note,article.up-and-running-contents .tip{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad}.alert-info h4,article.up-and-running-contents .note h4,article.up-and-running-contents .tip h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-left:0;margin-bottom:22px;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:22px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:10px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-tabs:after,.nav-pills:before,.nav-pills:after{display:table;content:"";line-height:0}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:22px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{border-top-color:#08c;border-bottom-color:#08c;margin-top:6px}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:0.01;filter:alpha(opacity=1)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-bottom-color:transparent;border-top-color:#ddd}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default}.navbar{overflow:visible;margin-bottom:22px;*position:relative;*z-index:2}.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #fff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #fff, #f2f2f2);background-image:-o-linear-gradient(top, #fff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff,#f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#f0f0f0', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065);*zoom:1}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{float:left;display:block;padding:9px 20px 9px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #fff}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:9px 15px 9px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333;text-decoration:none}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e6e6e6;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #f2f2f2, #e6e6e6);background-image:-o-linear-gradient(top, #f2f2f2, #e6e6e6);background-image:linear-gradient(to bottom, #f2f2f2,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f0f0f0', endColorstr='#e3e3e3', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e6e6e6;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute;top:-7px;left:9px}.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:10px}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0,0,0,0.2);border-bottom:0;bottom:-7px;top:auto}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #fff;border-bottom:0;bottom:-6px;top:auto}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e6e6e6;color:#555}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222, #111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222), to(#111));background-image:-webkit-linear-gradient(top, #222, #111);background-image:-o-linear-gradient(top, #222, #111);background-image:linear-gradient(to bottom, #222222,#111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#1f1f1f', endColorstr='#0e0e0e', GradientType=0);border-color:#252525}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:hover,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#fff}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-left-color:#111;border-right-color:#222}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111;color:#fff}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15);outline:0}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515,#040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#131313', endColorstr='#020202', GradientType=0);border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 22px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #fff}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:22px 0}.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:22px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;background-color:transparent;cursor:default}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px}.pagination-mini ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>a,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px}.pagination-mini ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>a,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:22px 0;list-style:none;text-align:center;*zoom:1}.pager:before,.pager:after{display:table;content:"";line-height:0}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:default}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none}.modal.fade{-webkit-transition:"opacity .3s linear, top .3s ease-out";-moz-transition:"opacity .3s linear, top .3s ease-out";-o-transition:"opacity .3s linear, top .3s ease-out";transition:"opacity .3s linear, top .3s ease-out";top:-25%}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff;*zoom:1}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right .arrow:after{left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:22px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:22px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-left:9px;padding-right:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:22px;margin-bottom:22px;background-color:#f6f6f6;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5,#f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f2f2', endColorstr='#f6f6f6', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.progress .bar{width:0%;height:100%;color:#fff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#1498da', endColorstr='#047db9', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#de514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5a56', endColorstr='#c03b34', GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5db95d;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5ec35e', endColorstr='#55a655', GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4cb2d0;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#57bedd', endColorstr='#3298b5', GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#f9a834;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb24b', endColorstr='#f39106', GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:22px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:22px;line-height:1}.carousel-inner{overflow:hidden;width:100%;position:relative}.carousel-inner>.item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50)}.carousel-control.right{left:auto;right:15px}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{color:#fff;line-height:22px}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:33px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px}.hero-unit li{line-height:33px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}body{padding-top:60px}/*
+ * Bootstrap Responsive v2.3.1
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none !important}.visible-tablet{display:none !important}.hidden-desktop{display:none !important}.visible-desktop{display:inherit !important}@media (min-width: 768px) and (max-width: 979px){.hidden-desktop{display:inherit !important}.visible-desktop{display:none !important}.visible-tablet{display:inherit !important}.hidden-tablet{display:none !important}}@media (max-width: 767px){.hidden-desktop{display:inherit !important}.visible-desktop{display:none !important}.visible-phone{display:inherit !important}.hidden-phone{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:inherit !important}.hidden-print{display:none !important}}@media (min-width: 1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.5641%;*margin-left:2.51091%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.5641%}.row-fluid .span12{width:100%;*width:99.94681%}.row-fluid .offset12{margin-left:105.12821%;*margin-left:105.02182%}.row-fluid .offset12:first-child{margin-left:102.5641%;*margin-left:102.45772%}.row-fluid .span11{width:91.45299%;*width:91.3998%}.row-fluid .offset11{margin-left:96.5812%;*margin-left:96.47481%}.row-fluid .offset11:first-child{margin-left:94.01709%;*margin-left:93.91071%}.row-fluid .span10{width:82.90598%;*width:82.85279%}.row-fluid .offset10{margin-left:88.03419%;*margin-left:87.92781%}.row-fluid .offset10:first-child{margin-left:85.47009%;*margin-left:85.3637%}.row-fluid .span9{width:74.35897%;*width:74.30578%}.row-fluid .offset9{margin-left:79.48718%;*margin-left:79.3808%}.row-fluid .offset9:first-child{margin-left:76.92308%;*margin-left:76.81669%}.row-fluid .span8{width:65.81197%;*width:65.75877%}.row-fluid .offset8{margin-left:70.94017%;*margin-left:70.83379%}.row-fluid .offset8:first-child{margin-left:68.37607%;*margin-left:68.26969%}.row-fluid .span7{width:57.26496%;*width:57.21177%}.row-fluid .offset7{margin-left:62.39316%;*margin-left:62.28678%}.row-fluid .offset7:first-child{margin-left:59.82906%;*margin-left:59.72268%}.row-fluid .span6{width:48.71795%;*width:48.66476%}.row-fluid .offset6{margin-left:53.84615%;*margin-left:53.73977%}.row-fluid .offset6:first-child{margin-left:51.28205%;*margin-left:51.17567%}.row-fluid .span5{width:40.17094%;*width:40.11775%}.row-fluid .offset5{margin-left:45.29915%;*margin-left:45.19276%}.row-fluid .offset5:first-child{margin-left:42.73504%;*margin-left:42.62866%}.row-fluid .span4{width:31.62393%;*width:31.57074%}.row-fluid .offset4{margin-left:36.75214%;*margin-left:36.64575%}.row-fluid .offset4:first-child{margin-left:34.18803%;*margin-left:34.08165%}.row-fluid .span3{width:23.07692%;*width:23.02373%}.row-fluid .offset3{margin-left:28.20513%;*margin-left:28.09875%}.row-fluid .offset3:first-child{margin-left:25.64103%;*margin-left:25.53464%}.row-fluid .span2{width:14.52991%;*width:14.47672%}.row-fluid .offset2{margin-left:19.65812%;*margin-left:19.55174%}.row-fluid .offset2:first-child{margin-left:17.09402%;*margin-left:16.98763%}.row-fluid .span1{width:5.98291%;*width:5.92971%}.row-fluid .offset1{margin-left:11.11111%;*margin-left:11.00473%}.row-fluid .offset1:first-child{margin-left:8.54701%;*margin-left:8.44063%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media (min-width: 768px) and (max-width: 979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.76243%;*margin-left:2.70924%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.76243%}.row-fluid .span12{width:100%;*width:99.94681%}.row-fluid .offset12{margin-left:105.52486%;*margin-left:105.41848%}.row-fluid .offset12:first-child{margin-left:102.76243%;*margin-left:102.65605%}.row-fluid .span11{width:91.43646%;*width:91.38327%}.row-fluid .offset11{margin-left:96.96133%;*margin-left:96.85494%}.row-fluid .offset11:first-child{margin-left:94.1989%;*margin-left:94.09251%}.row-fluid .span10{width:82.87293%;*width:82.81974%}.row-fluid .offset10{margin-left:88.39779%;*margin-left:88.29141%}.row-fluid .offset10:first-child{margin-left:85.63536%;*margin-left:85.52898%}.row-fluid .span9{width:74.30939%;*width:74.2562%}.row-fluid .offset9{margin-left:79.83425%;*margin-left:79.72787%}.row-fluid .offset9:first-child{margin-left:77.07182%;*margin-left:76.96544%}.row-fluid .span8{width:65.74586%;*width:65.69266%}.row-fluid .offset8{margin-left:71.27072%;*margin-left:71.16434%}.row-fluid .offset8:first-child{margin-left:68.50829%;*margin-left:68.4019%}.row-fluid .span7{width:57.18232%;*width:57.12913%}.row-fluid .offset7{margin-left:62.70718%;*margin-left:62.6008%}.row-fluid .offset7:first-child{margin-left:59.94475%;*margin-left:59.83837%}.row-fluid .span6{width:48.61878%;*width:48.56559%}.row-fluid .offset6{margin-left:54.14365%;*margin-left:54.03726%}.row-fluid .offset6:first-child{margin-left:51.38122%;*margin-left:51.27483%}.row-fluid .span5{width:40.05525%;*width:40.00206%}.row-fluid .offset5{margin-left:45.58011%;*margin-left:45.47373%}.row-fluid .offset5:first-child{margin-left:42.81768%;*margin-left:42.7113%}.row-fluid .span4{width:31.49171%;*width:31.43852%}.row-fluid .offset4{margin-left:37.01657%;*margin-left:36.91019%}.row-fluid .offset4:first-child{margin-left:34.25414%;*margin-left:34.14776%}.row-fluid .span3{width:22.92818%;*width:22.87499%}.row-fluid .offset3{margin-left:28.45304%;*margin-left:28.34666%}.row-fluid .offset3:first-child{margin-left:25.69061%;*margin-left:25.58422%}.row-fluid .span2{width:14.36464%;*width:14.31145%}.row-fluid .offset2{margin-left:19.8895%;*margin-left:19.78312%}.row-fluid .offset2:first-child{margin-left:17.12707%;*margin-left:17.02069%}.row-fluid .span1{width:5.8011%;*width:5.74791%}.row-fluid .offset1{margin-left:11.32597%;*margin-left:11.21958%}.row-fluid .offset1:first-child{margin-left:8.56354%;*margin-left:8.45715%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media (max-width: 767px){body{padding-left:20px;padding-right:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;clear:none;width:auto;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media (max-width: 480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0)}.page-header h1 small{display:block;line-height:22px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-left:10px;padding-right:10px}.media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;left:10px;right:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media (max-width: 979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:22px}.navbar-fixed-bottom{margin-top:22px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 11px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{margin-top:5px;padding:0}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:11px 15px;margin:11px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-left:10px;padding-right:10px}}@media (min-width: 980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important}}section{margin-bottom:1em}code{border:0;padding:0}table{margin-bottom:1em}.alert a,article.up-and-running-contents .note a,article.up-and-running-contents .tip a,article.up-and-running-contents .caution a,article.up-and-running-contents .warning a{color:#005580;text-decoration:underline}ol.toc li{list-style-type:none}.search-query{width:100px}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#008ed1;background-image:-moz-linear-gradient(top, #0081c6, #00a4e4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0081c6), to(#00a4e4));background-image:-webkit-linear-gradient(top, #0081c6, #00a4e4);background-image:-o-linear-gradient(top, #0081c6, #00a4e4);background-image:linear-gradient(to bottom, #0081c6,#00a4e4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#007ec1', endColorstr='#00a0df', GradientType=0);border-color:#00a4e4 #00a4e4 #006d98;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#00a4e4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#00a4e4;*background-color:#0092cb}.btn-primary:active,.btn-primary.active{background-color:#007fb1 \9}.thumbnail{background-color:whitesmoke;padding:15px}.navbar a.brand{padding:6px 20px 0 20px}.navbar-search{margin-top:4px}.navbar li.share-button{padding:8px 8px 0 0}.navbar li.share-button a{padding:0}.navbar .nav li.dropdown .dropdown-toggle .caret,.navbar .nav li.dropdown.open .caret{border-top-color:#0081c6;border-bottom-color:#0081c6;opacity:1}article.homepage pre.prettyprint{font-size:12px}article.homepage h1{font-family:"Montserrat",sans-serif;text-transform:uppercase;-webkit-text-stroke:1px}article.homepage h2{color:#00a4e4;-webkit-text-stroke:0.5px}article.homepage section{margin-bottom:60px}article.homepage section .callouts h2{text-transform:uppercase;font-family:"Montserrat",sans-serif}article.homepage section .callouts p.img{text-align:center}article.homepage ul.buttons{text-align:center;list-style:none}article.homepage ul.buttons li{display:inline-block}article.homepage #top-mast{text-align:center;margin-bottom:30px}article.homepage #top-mast .logo{margin-bottom:36px;position:relative;left:-28px}article.homepage #top-mast .contents{padding-top:30px;background-repeat:no-repeat;background-position:center bottom}@media (min-width: 481px){article.homepage #top-mast .contents{background-image:url("/imgs/Dart_Background-large-white-dartboard.jpg")}}article.homepage #top-mast h1{font-size:40px;margin-bottom:18px}article.homepage #top-mast p{font-size:18px;font-weight:200;line-height:33px;color:inherit}article.homepage #top-mast ul.buttons{margin-top:40px}article.homepage #top-mast ul.buttons li{margin:0 1em;vertical-align:top;width:180px;height:73px}article.homepage .overview-transition{text-align:center}article.homepage .overview-transition h1{font-size:50px;margin-bottom:1em;color:#AAA}div.editor-current-version{font-style:italic;margin-bottom:11px}section.article div.author-and-date{font-style:italic;color:#A8A8A8;font-size:11px;line-height:14px}.nowrap{white-space:nowrap}label.os-choice{display:inline}a.permalink{margin-left:0.5em;display:none}.has-permalink:hover>a.permalink{display:inline}.book{margin-bottom:2em}.book img.cover{box-shadow:8px 8px 15px #CCC}.spec-commentary{color:green}.spec-rationale{color:blue;font-style:italic}.spec-change{background:yellow}footer{border-top:1px solid #CECECE;background-color:#EFEFEF;color:#999;font-size:13px;padding:70px 0;margin-top:50px}footer ul{list-style:none;margin:0}footer p{font-size:12px}footer .copyright{padding-top:30px;text-align:center}div.bad pre.prettyprint{border-radius:5px;background-image:linear-gradient(bottom, #fff2f2 16%,#ffcccc 86%);background-image:-o-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-moz-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-webkit-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-ms-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0.16, #fff2f2), color-stop(0.86, #fcc))}div.good pre.prettyprint{border-radius:5px;background-image:linear-gradient(bottom, #f3fff0 16%,#d5ffcc 86%);background-image:-o-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-moz-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-webkit-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-ms-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0.16, #f3fff0), color-stop(0.86, #d5ffcc))}.good pre.prettyprint:before{content:"good";color:#696;float:right}.bad pre.prettyprint:before{content:"bad";color:red;float:right}pre.prettyprint .pln{color:#000}@media screen{pre.prettyprint .str{color:#d14}pre.prettyprint .kwd{color:#000;font-weight:bold}pre.prettyprint .com{color:#998}pre.prettyprint .typ{color:#445588;font-weight:bold}pre.prettyprint .lit{color:#099}pre.prettyprint .pun,pre.prettyprint .opn,pre.prettyprint .clo{color:#000}pre.prettyprint .tag{color:navy}pre.prettyprint .atn{color:teal}pre.prettyprint .atv{color:#d14}pre.prettyprint .dec,pre.prettyprint .var{color:teal}pre.prettyprint .fun{color:#900}}@media print, projection{pre.prettyprint .str{color:#d14}pre.prettyprint .kwd{color:#000;font-weight:bold}pre.prettyprint .com{color:#666}pre.prettyprint .typ{color:#445588;font-weight:bold}pre.prettyprint .lit{color:#099}pre.prettyprint .pun,pre.prettyprint .opn,pre.prettyprint .clo{color:#000}pre.prettyprint .tag{color:navy}pre.prettyprint .atn{color:teal}pre.prettyprint .atv{color:#d14}pre.prettyprint .dec,pre.prettyprint .var{color:teal}pre.prettyprint .fun{color:#900}}pre.prettyprint pre.prettyprint{font-size:12px}pre.prettyprint ol.linenums{margin-top:0;margin-bottom:0}pre.prettyprint li.L0,pre.prettyprint li.L1,pre.prettyprint li.L2,pre.prettyprint li.L3,pre.prettyprint li.L5,pre.prettyprint li.L6,pre.prettyprint li.L7,pre.prettyprint li.L8{list-style-type:none}pre.prettyprint li.L1,pre.prettyprint li.L3,pre.prettyprint li.L5,pre.prettyprint li.L7,pre.prettyprint li.L9{background:#eee}#tutorial-side{width:200px;position:fixed;top:85px}@media (min-width: 1200px){#tutorial-side{width:258px}}@media (min-width: 768px) and (max-width: 979px){#tutorial-side{width:158px}}@media (max-width: 767px){#tutorial-side{position:static;width:100%}}@media (max-width: 480px){#tutorial-side{position:static;width:100%}}#tutorial-toc{list-style-type:square;font-size:9pt;padding:10px;background-color:#DDFFDD;border-radius:10px;margin:0px 0px 15px 0px}#tutorial-toc ul{margin:0px 0px 0px 15px}#tutorial-toc li{line-height:120%}#tutorial-toc h4{padding-bottom:7px}#whats-the-point{list-style-type:square;font-size:9pt;padding:10px;background-color:#D8ECFD;border-radius:10px;margin:0px 0px 15px 0px}#whats-the-point ul{margin:0px 0px 0px 15px}#whats-the-point li{line-height:120%;padding-bottom:7px}#whats-the-point h4{padding-bottom:7px}#code-links{list-style-type:square;font-size:9pt;padding:10px;background-color:#FFE4E1;border-radius:10px;line-height:120%;margin:10px 0px 15px 0px}#code-links p{font-size:9pt;line-height:120%}#code-links ul{margin:0px 0px 0px 15px}#code-links li{line-height:120%;padding-bottom:7px}#code-links h4{padding-bottom:7px}.icon-info-sign{color:SlateBlue;font-size:18pt;vertical-align:middle}#under-construction{background-color:#F5E2FF;border-radius:10px;border-width:1px;margin:15px 50px 15px 50px;padding:10px}#under-construction h3{font-weight:bold;font-size:16pt}#under-construction .icon-wrench{font-size:24pt}#target-group{background-color:#F5E2FF;border-radius:10px;border-width:1px;margin:15px 10px 15px 10px;padding:10px}#target-group h3{font-weight:bold;font-size:16pt}#target-group .icon-wrench{font-size:24pt}.running-app-frame{border-style:solid;border-width:1px;border-radius:7px;background-color:WhiteSmoke;padding:5px}#dartisans-ribbon{position:fixed;top:0px;right:-95px;background:#00A4E4;color:white;-webkit-transform:rotateZ(40deg);-moz-transform:rotateZ(40deg);-ms-transform:rotateZ(40deg);-o-transform:rotateZ(40deg);transform:rotateZ(40deg);font-size:25px;padding:5px 70px;text-transform:uppercase;z-index:1000;-webkit-transform-origin:0 50%;-moz-transform-origin:0 50%;-ms-transform-origin:0 50%;-o-transform-origin:0 50%;transform-origin:0 50%;font-weight:600;-webkit-box-shadow:0px 0px 10px #222;-moz-box-shadow:0px 0px 10px #222;-ms-box-shadow:0px 0px 10px #222;-o-box-shadow:0px 0px 10px #222;box-shadow:0px 0px 10px #222;text-shadow:0px 0px 5px #000}@media (max-width: 979px){#dartisans-ribbon{top:-30px}}@media (max-width: 480px){#dartisans-ribbon{position:static}}#dartisans-ribbon .record{background-color:red;border-radius:50%;display:inline-block;width:15px;height:15px;margin-bottom:2px}article.up-and-running-contents #book-header{color:#999;font-size:13px;font-style:italic;text-align:center}article.up-and-running-contents span.remark{display:none}article.up-and-running-contents div.toc p:first-child b:first-child{display:none}article.up-and-running-contents dd dl{margin-top:0px}article.up-and-running-contents a.xref i{font-style:normal}@media print{.no-print{display:none}}
diff --git a/site/try/favicon.ico b/site/try/favicon.ico
new file mode 100644
index 0000000..50ea5b0
--- /dev/null
+++ b/site/try/favicon.ico
Binary files differ
diff --git a/site/try/iframe.html b/site/try/iframe.html
new file mode 100644
index 0000000..d92887b
--- /dev/null
+++ b/site/try/iframe.html
@@ -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.
+-->
+<!DOCTYPE html>
+<html lang="en" manifest="nossl.appcache">
+<head>
+<title>JavaScript output</title>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+</head>
+<body>
+<script type="application/javascript" src="iframe.js"></script>
+</body>
+</html>
diff --git a/site/try/iframe.js b/site/try/iframe.js
new file mode 100644
index 0000000..d1460fd
--- /dev/null
+++ b/site/try/iframe.js
@@ -0,0 +1,51 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+function dartPrint(msg) {
+  window.parent.postMessage(String(msg), "*");
+}
+
+window.onerror = function (message, url, lineNumber) {
+  window.parent.postMessage(
+      ["error", {message: message, url: url, lineNumber: lineNumber}], "*");
+};
+
+function onMessageReceived(event) {
+  var data = event.data;
+  if (data instanceof Array) {
+    if (data.length == 2 && data[0] == 'source') {
+      var script = document.createElement('script');
+      script.innerHTML = data[1];
+      script.type = 'application/javascript';
+      document.head.appendChild(script);
+      return;
+    }
+  }
+}
+
+window.addEventListener("message", onMessageReceived, false);
+
+(function () {
+  function postScrollHeight() {
+    window.parent.postMessage(
+      ["scrollHeight", document.documentElement.scrollHeight], "*");
+  }
+
+  var mutationObserverConstructor =
+      window.MutationObserver ||
+      window.WebKitMutationObserver ||
+      window.MozMutationObserver;
+
+  var observer = new mutationObserverConstructor(function(mutations) {
+    postScrollHeight()
+    window.setTimeout(postScrollHeight, 500);
+  });
+
+  observer.observe(
+      document.body,
+      { attributes: true,
+        childList: true,
+        characterData: true,
+        subtree: true });
+})();
diff --git a/site/try/index.html b/site/try/index.html
new file mode 100644
index 0000000..708a1c4
--- /dev/null
+++ b/site/try/index.html
@@ -0,0 +1,158 @@
+<!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 lang="en" manifest="nossl.appcache" itemscope itemtype="http://schema.org/Product">
+<head>
+<meta charset="utf-8">
+<title>Try Dart!</title>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+<link rel="stylesheet" type="text/css" href="dartlang-style.css">
+<style>
+a.diagnostic {
+  /* position: relative; */
+  color: inherit;
+  border-bottom: 2px dotted red;
+}
+a:hover.diagnostic {
+  text-decoration: none;
+}
+a.diagnostic span {
+  display: none;
+}
+a:hover.diagnostic span {
+  display: block;
+  position: absolute;
+  /* left: 1em; */
+  /* top: 2em; */
+  right: 10px;
+}
+
+.offline {
+  transition: opacity 10s;
+  -webkit-transition: opacity 10s;
+}
+
+.offlineyay {
+  font-weight: bolder;
+  opacity: 0.0;
+}
+</style>
+
+<meta itemprop="name" content="Try Dart!">
+<meta itemprop="description" content="Write and run Dart code in your browser.  Dart is a class-based, object-oriented language with lexical scoping, closures, and optional static typing.">
+<meta name="description" content="Write and run Dart code in your browser.  Dart is a class-based, object-oriented language with lexical scoping, closures, and optional static typing.">
+<meta itemprop="image" content="try-dart-screenshot.png">
+
+<link rel="dart-sdk" href="sdk.json">
+<link rel="benchmark-DeltaBlue" href="benchmarks/DeltaBlue.dart">
+<link rel="benchmark-Richards" href="benchmarks/Richards.dart">
+<link rel="benchmark-base" href="benchmarks/benchmark_base.dart">
+
+<link href="favicon.ico" rel="icon" type="image/x-icon">
+
+<meta name="viewport" content="initial-scale=1.0">
+
+<!-- Chrome Mobile (Android) "Add to home screen" support -->
+<meta name="mobile-web-app-capable" content="yes">
+<link rel="shortcut icon" sizes="196x196" href="dart-icon-196px.png">
+
+<!-- iOS "Add to Home Screen" support -->
+<meta name="apple-mobile-web-app-capable" content="yes">
+<link rel="apple-touch-icon" href="dart-icon-196px.png">
+<meta names="apple-mobile-web-app-status-bar-style" content="black">
+<link rel="apple-touch-startup-image"
+      media="(device-width: 320px)
+         and (device-height: 568px)
+         and (-webkit-device-pixel-ratio: 2)"
+      href="dart-iphone5.png">
+
+<!-- Enable Google Analytics -->
+<script type="text/javascript">
+/*
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-26406144-2']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+*/
+</script>
+</head>
+<body>
+<div class="navbar navbar-fixed-top">
+<div class="navbar-inner">
+<div class="container">
+<a class="brand" href="//www.dartlang.org/" title="Dart Homepage" target="_blank">
+<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAMAAACeyVWkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJxQTFRFAAAAAIvMdsvDAIvMdsvDAIvMdsvDLaTJAIvMOqnHdsvDAIvMdsvDAIvMKaLJdsvDAIvMAIvMdsvDAIvMdsvDdsvDAIvMAIvMAZnFdsvDAILHAIPHAITIAIXJAIfKAIjKAIrLAIrMAIvMAJXHAJjFC5i/I6HENr2yOb6zPr+0TsK4UsO5WbnEWcW8Xsa9Yse+Zsi/asjAc8rCdsvDdt4SRQAAABp0Uk5TABAQICAwMFBgYGBwcICAgI+vr7+/z9/v7+97IXGnAAAAqUlEQVQYV13QxxaCQBBE0VZkjBgAGVEBaVEUM/P//yaTGg5vV3dZANTCZ9BvFAoR93kVC9FnthW6uIPTJ7UkdHaXvS2LXKNBURInyDXPsShbzjU7XCpxhooDVGo5QcQAJmjUco64AY/UcIrowYCTaj5KBZeTaj5JBTc6l11OlQKMf497y1ahefFb3TQfcqtM/fipJF/X9gnDon6/ah/aDDfNOgosNA2b8QdGciZlh/U93AAAAABJRU5ErkJggg==" alt="Dart">
+</a>
+<ul class="nav pull-right"><li><a href="#" id="settings"><i class="icon-cog"></i></a></li></ul>
+
+<ul class="nav hidden-phone">
+<li class="active"><a>Try Dart!</a></li>
+<li><a href="//api.dartlang.org/" target="_blank">API Reference</a></li>
+</ul>
+<form class="navbar-search pull-right hidden-phone" action="//www.dartlang.org/search.html" id="cse-search-box" target="_blank">
+<input type="hidden" name="ie" value="UTF-8">
+<input type="hidden" name="hl" value="en">
+<input type="search" name="q" class="search-query" id="q" autocomplete="off" placeholder="Search">
+</form>
+<ul class="nav pull-right"><li><a><span id="appcache-status" class="offline">offline status</span></a></li></ul>
+
+
+</div>
+</div>
+</div>
+<div class="container-fluid">
+<article class="homepage">
+<section>
+<div class="callouts row-fluid">
+<div class="span6" id="try-dart-column">
+<h2><i class="icon-play"></i> Try Dart! <select id="inspiration"></select></h2>
+</div>
+<div class="span6" id="run-dart-column">
+<h2><i class="icon-cogs"></i> See Dart</h2>
+</div>
+</div>
+</section>
+</article>
+</div>
+
+<div id="settings-dialog" class="modal hide fade">
+  <div class="modal-header">
+    <h3>Settings</h3>
+  </div>
+  <div class="modal-body" id="settings-body">
+  </div>
+  <div class="modal-footer">
+    <a href="#" class="btn btn-primary" id="settings-done">Done</a>
+  </div>
+</div>
+
+<footer>
+<div class="container">
+<div class="row copyright">
+<div class="span8 offset2">
+<p>
+Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>, the content of this page is licensed under the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>, and code samples are licensed under the <a href="http://code.google.com/google_bsd_license.html">BSD License</a>.
+</p>
+<p>
+<a href="//www.dartlang.org/tos.html">Terms of Service</a> —
+<a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
+</p>
+</div>
+</div>
+</div>
+</footer>
+<!--
+<script type="application/javascript" src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/browser/lib/dart.js"></script>
+<script type="application/dart" src="leap.dart"></script>
+-->
+<script type="application/javascript" src="leap.dart.js"></script>
+</body>
+</html>
diff --git a/site/try/nossl.appcache b/site/try/nossl.appcache
new file mode 100644
index 0000000..d5218a3
--- /dev/null
+++ b/site/try/nossl.appcache
@@ -0,0 +1,22 @@
+CACHE MANIFEST
+# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# @@TIMESTAMP@@
+
+CACHE:
+index.html
+dartlang-style.css
+leap.dart.js
+
+iframe.html
+iframe.js
+dart-icon.png
+dart-iphone5.png
+sdk.json
+
+/css/fonts/fontawesome-webfont.woff?v=3.0.1
+
+NETWORK:
+*
diff --git a/site/try/not_found.html b/site/try/not_found.html
new file mode 100644
index 0000000..ecd6203
--- /dev/null
+++ b/site/try/not_found.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+for 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 lang="en">
+  <head>
+    <title>Missing Resource</title>
+    <meta charset="UTF-8">
+  </head>
+  <body>
+    <h1>Missing Resource</h1>
+  </body>
+</html>
diff --git a/site/try/src/cache.dart b/site/try/src/cache.dart
new file mode 100644
index 0000000..fd4cce0
--- /dev/null
+++ b/site/try/src/cache.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library trydart.cache;
+
+import 'dart:async' show
+    Timer;
+
+import 'dart:html' show
+    AnchorElement,
+    ApplicationCache,
+    Event,
+    MeterElement,
+    ProgressEvent,
+    window;
+
+import 'ui.dart' show
+    cacheStatusElement;
+
+/// Called when the window has finished loading.
+void onLoad(Event event) {
+  window.applicationCache.onUpdateReady.listen((_) => updateCacheStatus());
+  window.applicationCache.onCached.listen((_) => updateCacheStatus());
+  window.applicationCache.onChecking.listen((_) => updateCacheStatus());
+  window.applicationCache.onDownloading.listen((_) => updateCacheStatus());
+  window.applicationCache.onError.listen((_) => updateCacheStatus());
+  window.applicationCache.onNoUpdate.listen((_) => updateCacheStatus());
+  window.applicationCache.onObsolete.listen((_) => updateCacheStatus());
+  window.applicationCache.onProgress.listen(onCacheProgress);
+}
+
+onCacheProgress(ProgressEvent event) {
+  if (!event.lengthComputable) {
+    updateCacheStatus();
+    return;
+  }
+  cacheStatusElement.nodes.clear();
+  cacheStatusElement.appendText('Downloading SDK ');
+  var progress = '${event.loaded} of ${event.total}';
+  if (MeterElement.supported) {
+    cacheStatusElement.append(
+        new MeterElement()
+            ..appendText(progress)
+            ..min = 0
+            ..max = event.total
+            ..value = event.loaded);
+  } else {
+    cacheStatusElement.appendText(progress);
+  }
+}
+
+String cacheStatus() {
+  if (!ApplicationCache.supported) return 'offline not supported';
+  int status = window.applicationCache.status;
+  if (status == ApplicationCache.CHECKING) return 'Checking for updates';
+  if (status == ApplicationCache.DOWNLOADING) return 'Downloading SDK';
+  if (status == ApplicationCache.IDLE) return 'Try Dart! works offline';
+  if (status == ApplicationCache.OBSOLETE) return 'OBSOLETE';
+  if (status == ApplicationCache.UNCACHED) return 'offline not available';
+  if (status == ApplicationCache.UPDATEREADY) return 'SDK downloaded';
+  return '?';
+}
+
+void updateCacheStatus() {
+  cacheStatusElement.nodes.clear();
+  int status = window.applicationCache.status;
+  if (status == ApplicationCache.UPDATEREADY) {
+    cacheStatusElement.appendText('New version of Try Dart! ready: ');
+    cacheStatusElement.append(
+        new AnchorElement(href: '#')
+            ..appendText('Load')
+            ..onClick.listen((event) {
+              event.preventDefault();
+              window.applicationCache.swapCache();
+              window.location.reload();
+            }));
+  } else if (status == ApplicationCache.IDLE) {
+    cacheStatusElement.appendText(cacheStatus());
+    cacheStatusElement.classes.add('offlineyay');
+    new Timer(const Duration(seconds: 10), () {
+      cacheStatusElement.style.display = 'none';
+    });
+  } else {
+    cacheStatusElement.appendText(cacheStatus());
+  }
+}
diff --git a/site/try/src/compilation.dart b/site/try/src/compilation.dart
new file mode 100644
index 0000000..eb82457
--- /dev/null
+++ b/site/try/src/compilation.dart
@@ -0,0 +1,287 @@
+// 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 trydart.compilation;
+
+import 'dart:html' show
+    Blob,
+    Element,
+    ErrorEvent,
+    IFrameElement,
+    MessageEvent,
+    Url,
+    Worker;
+
+import 'dart:async' show
+    Timer;
+
+import 'dart:isolate' show
+    ReceivePort,
+    SendPort;
+
+import 'editor.dart' show
+    addDiagnostic,
+    currentSource,
+    isMalformedInput;
+
+import 'run.dart' show
+    makeOutputFrame;
+
+import 'ui.dart' show
+    alwaysRunInWorker,
+    applyingSettings,
+    buildButton,
+    minified,
+    onlyAnalyze,
+    outputDiv,
+    outputFrame,
+    verboseCompiler;
+
+@lazy import 'compiler_isolate.dart';
+
+// const lazy = const DeferredLibrary('compiler_isolate');
+const lazy = null;
+
+SendPort compilerPort;
+Timer compilerTimer;
+
+void scheduleCompilation() {
+  if (applyingSettings) return;
+  if (compilerTimer != null) {
+    compilerTimer.cancel();
+    compilerTimer = null;
+  }
+  compilerTimer =
+      new Timer(const Duration(milliseconds: 500), startCompilation);
+}
+
+void startCompilation() {
+  if (compilerTimer != null) {
+    compilerTimer.cancel();
+    compilerTimer = null;
+  }
+
+  new CompilationProcess(currentSource, outputDiv).start();
+}
+
+class CompilationProcess {
+  final String source;
+  final Element console;
+  final ReceivePort receivePort = new ReceivePort();
+  bool isCleared = false;
+  bool isDone = false;
+  bool usesDartHtml = false;
+  Worker worker;
+  List<String> objectUrls = <String>[];
+
+  static CompilationProcess current;
+
+  CompilationProcess(this.source, this.console);
+
+  static bool shouldStartCompilation() {
+    if (compilerPort == null) return false;
+    if (isMalformedInput) return false;
+    if (current != null) return current.isDone;
+    return true;
+  }
+
+  void clear() {
+    if (verboseCompiler) return;
+    if (!isCleared) console.nodes.clear();
+    isCleared = true;
+  }
+
+  void start() {
+    if (!shouldStartCompilation()) {
+      receivePort.close();
+      if (!isMalformedInput) scheduleCompilation();
+      return;
+    }
+    if (current != null) current.dispose();
+    current = this;
+    console.nodes.clear();
+    var options = [];
+    if (verboseCompiler) options.add('--verbose');
+    if (minified) options.add('--minify');
+    if (onlyAnalyze) options.add('--analyze-only');
+    compilerPort.send([['options', options], receivePort.sendPort]);
+    console.appendHtml('<i class="icon-spinner icon-spin"></i>');
+    console.appendText(' Compiling Dart program...\n');
+    outputFrame.style.display = 'none';
+    receivePort.listen(onMessage);
+    compilerPort.send([source, receivePort.sendPort]);
+  }
+
+  void dispose() {
+    if (worker != null) worker.terminate();
+    objectUrls.forEach(Url.revokeObjectUrl);
+  }
+
+  onMessage(message) {
+    String kind = message is String ? message : message[0];
+    var data = (message is List && message.length == 2) ? message[1] : null;
+    switch (kind) {
+      case 'done': return onDone(data);
+      case 'url': return onUrl(data);
+      case 'code': return onCode(data);
+      case 'diagnostic': return onDiagnostic(data);
+      case 'crash': return onCrash(data);
+      case 'failed': return onFail(data);
+      case 'dart:html': return onDartHtml(data);
+      default:
+        throw ['Unknown message kind', message];
+    }
+  }
+
+  onDartHtml(_) {
+    usesDartHtml = true;
+  }
+
+  onFail(_) {
+    clear();
+    consolePrint('Compilation failed');
+  }
+
+  onDone(_) {
+    isDone = true;
+    receivePort.close();
+  }
+
+  // This is called in browsers that support creating Object URLs in a
+  // web worker.  For example, Chrome and Firefox 21.
+  onUrl(String url) {
+    objectUrls.add(url);
+    clear();
+    String wrapper = '''
+// Fool isolate_helper.dart so it does not think this is an isolate.
+var window = self;
+function dartPrint(msg) {
+  self.postMessage(msg);
+};
+self.importScripts("$url");
+''';
+    var wrapperUrl =
+        Url.createObjectUrl(new Blob([wrapper], 'application/javascript'));
+    objectUrls.add(wrapperUrl);
+    void retryInIframe(_) {
+      var frame = makeOutputFrame(url);
+      outputFrame.replaceWith(frame);
+      outputFrame = frame;
+    }
+    void onError(String errorMessage) {
+      console.appendText(errorMessage);
+      console.appendText(' ');
+      console.append(buildButton('Try in iframe', retryInIframe));
+      console.appendText('\n');
+    }
+    if (usesDartHtml && !alwaysRunInWorker) {
+      retryInIframe(null);
+    } else {
+      runInWorker(wrapperUrl, onError);
+    }
+  }
+
+  // This is called in browsers that do not support creating Object
+  // URLs in a web worker.  For example, Safari and Firefox < 21.
+  onCode(String code) {
+    clear();
+
+    void retryInIframe(_) {
+      // The obvious thing would be to call [makeOutputFrame], but
+      // Safari doesn't support access to Object URLs in an iframe.
+
+      var frame = new IFrameElement()
+          ..src = 'iframe.html'
+          ..style.width = '100%'
+          ..style.height = '0px'
+          ..seamless = false;
+      frame.onLoad.listen((_) {
+        frame.contentWindow.postMessage(['source', code], '*');
+      });
+      outputFrame.replaceWith(frame);
+      outputFrame = frame;
+    }
+
+    void onError(String errorMessage) {
+      console.appendText(errorMessage);
+      console.appendText(' ');
+      console.append(buildButton('Try in iframe', retryInIframe));
+      console.appendText('\n');
+    }
+
+    String codeWithPrint =
+        '$code\n'
+        'function dartPrint(msg) { postMessage(msg); }\n';
+    var url =
+        Url.createObjectUrl(
+            new Blob([codeWithPrint], 'application/javascript'));
+    objectUrls.add(url);
+
+    if (usesDartHtml && !alwaysRunInWorker) {
+      retryInIframe(null);
+    } else {
+      runInWorker(url, onError);
+    }
+  }
+
+  void runInWorker(String url, void onError(String errorMessage)) {
+    worker = new Worker(url)
+        ..onMessage.listen((MessageEvent event) {
+          consolePrint(event.data);
+        })
+        ..onError.listen((ErrorEvent event) {
+          worker.terminate();
+          worker = null;
+          onError(event.message);
+        });
+  }
+
+  onDiagnostic(Map<String, dynamic> diagnostic) {
+    String kind = diagnostic['kind'];
+    String message = diagnostic['message'];
+    if (kind == 'verbose info') {
+      if (verboseCompiler) {
+        consolePrint(message);
+      } else {
+        console.appendText('.');
+      }
+      return;
+    }
+    String uri = diagnostic['uri'];
+    if (uri == null) {
+      clear();
+      consolePrint(message);
+      return;
+    }
+    if (uri != 'memory:/main.dart') return;
+    if (currentSource != source) return;
+    int begin = diagnostic['begin'];
+    int end = diagnostic['end'];
+    if (begin == null) return;
+    addDiagnostic(kind, message, begin, end);
+  }
+
+  onCrash(data) {
+    consolePrint(data);
+  }
+
+  void consolePrint(message) {
+    console.appendText('$message\n');
+  }
+}
+
+void compilerIsolate(SendPort port) {
+  // TODO(ahe): Restore when restoring deferred loading.
+  // lazy.load().then((_) => port.listen(compile));
+  ReceivePort replyTo = new ReceivePort();
+  port.send(replyTo.sendPort);
+  replyTo.listen((message) {
+    List list = message as List;
+    try {
+      compile(list[0], list[1]);
+    } catch (exception, stack) {
+      port.send('$exception\n$stack');
+    }
+  });
+}
diff --git a/site/try/src/compiler_isolate.dart b/site/try/src/compiler_isolate.dart
new file mode 100644
index 0000000..9366aac
--- /dev/null
+++ b/site/try/src/compiler_isolate.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.
+
+library compiler_isolate;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:isolate';
+import 'dart:convert' show JSON;
+
+import '../../../sdk/lib/_internal/compiler/compiler.dart' as compiler;
+
+const bool THROW_ON_ERROR = false;
+
+final cachedSources = new Map<Uri, String>();
+
+Uri sdkLocation;
+List options = [];
+
+compile(source, SendPort replyTo) {
+  if (sdkLocation == null) {
+    // The first message received gives us the URI of this web app.
+    if (source.endsWith('/sdk.json')) {
+      var request = new HttpRequest();
+      request.open('GET', source, async: false);
+      request.send(null);
+      if (request.status != 200) {
+        throw 'SDK not found at $source';
+      }
+      sdkLocation = Uri.parse('sdk:/sdk/');
+      JSON.decode(request.responseText).forEach((file, content) {
+        cachedSources[Uri.parse(file)] = content;
+      });
+    } else {
+      sdkLocation = Uri.parse(source);
+    }
+    replyTo.send(null);
+    return;
+  }
+  if (source is List) {
+    String messageType = (source.length > 0) ? source[0] : null;
+    var data = (source.length > 1) ? source[1] : null;
+    if (messageType == 'options') {
+      options = data as List;
+    }
+    return;
+  }
+  int charactersRead = 0;
+  Future<String> inputProvider(Uri uri) {
+    if (uri.path.endsWith('/lib/html/dart2js/html_dart2js.dart')) {
+      replyTo.send('dart:html');
+    }
+    if (uri.scheme == 'sdk') {
+      var value = cachedSources[uri];
+      charactersRead += value.length;
+      return new Future.value(value);
+    } else if (uri.scheme == 'http' || uri.scheme == 'https') {
+      var value = cachedSources.putIfAbsent(uri, () {
+        var request = new HttpRequest();
+        request.open('GET', '$uri', async: false);
+        request.send(null);
+        return request.responseText;
+      });
+      charactersRead += value.length;
+      return new Future.value(value);
+    } else if ('$uri' == 'memory:/main.dart') {
+      charactersRead += source.length;
+      return new Future.value(source);
+    }
+    throw new Exception('Error: Cannot read: $uri');
+  }
+  void handler(Uri uri, int begin, int end,
+               String message, compiler.Diagnostic kind) {
+    replyTo.send(['diagnostic', { 'uri': '$uri',
+                                  'begin': begin,
+                                  'end': end,
+                                  'message': message,
+                                  'kind': kind.name }]);
+    if (THROW_ON_ERROR && kind == compiler.Diagnostic.ERROR) {
+      throw new Exception('Throw on error');
+    }
+  }
+  compiler.compile(Uri.parse('memory:/main.dart'),
+                   sdkLocation,
+                   null,
+                   inputProvider,
+                   handler,
+                   options).then((js) {
+    try {
+      if (js == null) {
+        if (!options.contains('--analyze-only')) replyTo.send('failed');
+      } else {
+        var url;
+        if (options.contains('--verbose')) {
+          handler(null, 0, 0,
+                  'Compiled ${source.length}/${charactersRead} characters Dart'
+                  ' -> ${js.length} characters.',
+                  compiler.Diagnostic.VERBOSE_INFO);
+        }
+        try {
+          // At least Safari and Firefox do not support creating an
+          // object URL from a web worker.  MDN claims that it will be
+          // supported in Firefox 21.
+          url = Url.createObjectUrl(new Blob([js], 'application/javascript'));
+        } catch (_) {
+          // Ignored.
+        }
+        if (url != null) {
+          replyTo.send(['url', url]);
+        } else {
+          replyTo.send(['code', js]);
+        }
+      }
+    } catch (e, trace) {
+      replyTo.send(['crash', '$e, $trace']);
+    }
+    replyTo.send('done');
+  });
+}
diff --git a/site/try/src/decoration.dart b/site/try/src/decoration.dart
new file mode 100644
index 0000000..87e62b8
--- /dev/null
+++ b/site/try/src/decoration.dart
@@ -0,0 +1,101 @@
+// 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 trydart.decoration;
+
+import 'dart:html';
+
+class Decoration {
+  final String color;
+  final bool bold;
+  final bool italic;
+  final bool stress;
+  final bool important;
+
+  const Decoration({this.color: '#000000',
+                    this.bold: false,
+                    this.italic: false,
+                    this.stress: false,
+                    this.important: false});
+
+  Element applyTo(text) {
+    if (text is String) {
+      text = new Text(text);
+    }
+    if (bold) {
+      text = new Element.tag('b')..append(text);
+    }
+    if (italic) {
+      text = new Element.tag('i')..append(text);
+    }
+    if (stress) {
+      text = new Element.tag('em')..append(text);
+    }
+    if (important) {
+      text = new Element.tag('strong')..append(text);
+    }
+    return new SpanElement()..append(text)..style.color = color;
+  }
+}
+
+class DiagnosticDecoration extends Decoration {
+  final String kind;
+  final String message;
+
+  const DiagnosticDecoration(
+      this.kind,
+      this.message,
+      {String color: '#000000',
+       bool bold: false,
+       bool italic: false,
+       bool stress: false,
+       bool important: false})
+      : super(color: color, bold: bold, italic: italic, stress: stress,
+              important: important);
+
+  Element applyTo(text) {
+    var element = super.applyTo(text);
+    var nodes = new List.from(element.nodes);
+    element.nodes.clear();
+    var tip = new Text('');
+    if (kind == 'error') {
+      tip = error(message);
+    }
+    return element..append(
+        new AnchorElement()
+            ..classes.add('diagnostic')
+            ..nodes.addAll(nodes)
+            ..append(tip));
+  }
+}
+
+info(text) {
+  if (text is String) {
+    text = new Text(text);
+  }
+  return new SpanElement()
+      ..classes.addAll(['alert', 'alert-info'])
+      ..style.opacity = '0.75'
+      ..append(text);
+}
+
+error(text) {
+  if (text is String) {
+    text = new Text(text);
+  }
+  return new SpanElement()
+      ..classes.addAll(['alert', 'alert-error'])
+      ..style.opacity = '0.75'
+      ..append(text);
+}
+
+warning(text) {
+  if (text is String) {
+    text = new Text(text);
+  }
+  return new SpanElement()
+      ..classes.add('alert')
+      ..style.opacity = '0.75'
+      ..append(text);
+}
diff --git a/site/try/src/editor.dart b/site/try/src/editor.dart
new file mode 100644
index 0000000..e8ae9e8
--- /dev/null
+++ b/site/try/src/editor.dart
@@ -0,0 +1,315 @@
+// 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 trydart.editor;
+
+import 'dart:html';
+
+import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart'
+  show
+    EOF_TOKEN,
+    StringScanner,
+    Token;
+
+import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart' show
+    StringSourceFile;
+
+import 'compilation.dart' show
+    scheduleCompilation;
+
+import 'ui.dart' show
+    currentTheme,
+    hackDiv,
+    inputPre,
+    observer,
+    outputDiv;
+
+import 'decoration.dart' show
+    Decoration,
+    DiagnosticDecoration,
+    error,
+    info,
+    warning;
+
+const String INDENT = '\u{a0}\u{a0}';
+
+onKeyUp(KeyboardEvent e) {
+  if (e.keyCode == 13) {
+    e.preventDefault();
+    Selection selection = window.getSelection();
+    if (selection.isCollapsed && selection.anchorNode is Text) {
+      Text text = selection.anchorNode;
+      int offset = selection.anchorOffset;
+      text.insertData(offset, '\n');
+      selection.collapse(text, offset + 1);
+    }
+  }
+  // This is a hack to get Safari to send mutation events on contenteditable.
+  var newDiv = new DivElement();
+  hackDiv.replaceWith(newDiv);
+  hackDiv = newDiv;
+}
+
+bool isMalformedInput = false;
+String currentSource = "";
+
+// TODO(ahe): This method should be cleaned up. It is too large.
+onMutation(List<MutationRecord> mutations, MutationObserver observer) {
+  scheduleCompilation();
+
+  for (Element element in inputPre.queryAll('a[class="diagnostic"]>span')) {
+    element.remove();
+  }
+  // Discard clean-up mutations.
+  observer.takeRecords();
+
+  Selection selection = window.getSelection();
+
+  while (!mutations.isEmpty) {
+    for (MutationRecord record in mutations) {
+      String type = record.type;
+      switch (type) {
+
+        case 'characterData':
+
+          bool hasSelection = false;
+          int offset = selection.anchorOffset;
+          if (selection.isCollapsed && selection.anchorNode == record.target) {
+            hasSelection = true;
+          }
+          var parent = record.target.parentNode;
+          if (parent != inputPre) {
+            inlineChildren(parent);
+          }
+          if (hasSelection) {
+            selection.collapse(record.target, offset);
+          }
+          break;
+
+        default:
+          if (!record.addedNodes.isEmpty) {
+            for (var node in record.addedNodes) {
+
+              if (node.nodeType != Node.ELEMENT_NODE) continue;
+
+              if (node is BRElement) {
+                if (selection.anchorNode != node) {
+                  node.replaceWith(new Text('\n'));
+                }
+              } else {
+                var parent = node.parentNode;
+                if (parent == null) continue;
+                var nodes = new List.from(node.nodes);
+                var style = node.getComputedStyle();
+                if (style.display != 'inline') {
+                  var previous = node.previousNode;
+                  if (previous is Text) {
+                    previous.appendData('\n');
+                  } else {
+                    parent.insertBefore(new Text('\n'), node);
+                  }
+                }
+                for (Node child in nodes) {
+                  child.remove();
+                  parent.insertBefore(child, node);
+                }
+                node.remove();
+              }
+            }
+          }
+      }
+    }
+    mutations = observer.takeRecords();
+  }
+
+  if (!inputPre.nodes.isEmpty && inputPre.nodes.last is Text) {
+    Text text = inputPre.nodes.last;
+    if (!text.text.endsWith('\n')) {
+      text.appendData('\n');
+    }
+  }
+
+  int offset = 0;
+  int anchorOffset = 0;
+  bool hasSelection = false;
+  Node anchorNode = selection.anchorNode;
+  // TODO(ahe): Try to share walk4 methods.
+  void walk4(Node node) {
+    // TODO(ahe): Use TreeWalker when that is exposed.
+    // function textNodesUnder(root){
+    //   var n, a=[], walk=document.createTreeWalker(
+    //       root,NodeFilter.SHOW_TEXT,null,false);
+    //   while(n=walk.nextNode()) a.push(n);
+    //   return a;
+    // }
+    int type = node.nodeType;
+    if (type == Node.TEXT_NODE || type == Node.CDATA_SECTION_NODE) {
+      CharacterData text = node;
+      if (anchorNode == node) {
+        hasSelection = true;
+        anchorOffset = selection.anchorOffset + offset;
+        return;
+      }
+      offset += text.length;
+    }
+
+    var child = node.firstChild;
+    while (child != null) {
+      walk4(child);
+      if (hasSelection) return;
+      child = child.nextNode;
+    }
+  }
+  if (selection.isCollapsed) {
+    walk4(inputPre);
+  }
+
+  currentSource = inputPre.text;
+  inputPre.nodes.clear();
+  inputPre.appendText(currentSource);
+  if (hasSelection) {
+    selection.collapse(inputPre.firstChild, anchorOffset);
+  }
+
+  isMalformedInput = false;
+  for (var n in new List.from(inputPre.nodes)) {
+    if (n is! Text) continue;
+    Text node = n;
+    String text = node.text;
+
+    Token token = new StringScanner(
+        new StringSourceFile('', text), includeComments: true).tokenize();
+    int offset = 0;
+    for (;token.kind != EOF_TOKEN; token = token.next) {
+      Decoration decoration = getDecoration(token);
+      if (decoration == null) continue;
+      bool hasSelection = false;
+      int selectionOffset = selection.anchorOffset;
+
+      if (selection.isCollapsed && selection.anchorNode == node) {
+        hasSelection = true;
+        selectionOffset = selection.anchorOffset;
+      }
+      int splitPoint = token.charOffset - offset;
+      Text str = node.splitText(splitPoint);
+      Text after = str.splitText(token.charCount);
+      offset += splitPoint + token.charCount;
+      inputPre.insertBefore(after, node.nextNode);
+      inputPre.insertBefore(decoration.applyTo(str), after);
+
+      if (hasSelection && selectionOffset > node.length) {
+        selectionOffset -= node.length;
+        if (selectionOffset > str.length) {
+          selectionOffset -= str.length;
+          selection.collapse(after, selectionOffset);
+        } else {
+          selection.collapse(str, selectionOffset);
+        }
+      }
+      node = after;
+    }
+  }
+
+  window.localStorage['currentSource'] = currentSource;
+
+  // Discard highlighting mutations.
+  observer.takeRecords();
+}
+
+addDiagnostic(String kind, String message, int begin, int end) {
+  observer.disconnect();
+  Selection selection = window.getSelection();
+  int offset = 0;
+  int anchorOffset = 0;
+  bool hasSelection = false;
+  Node anchorNode = selection.anchorNode;
+  bool foundNode = false;
+  void walk4(Node node) {
+    // TODO(ahe): Use TreeWalker when that is exposed.
+    int type = node.nodeType;
+    if (type == Node.TEXT_NODE || type == Node.CDATA_SECTION_NODE) {
+      CharacterData cdata = node;
+      // print('walking: ${node.data}');
+      if (anchorNode == node) {
+        hasSelection = true;
+        anchorOffset = selection.anchorOffset + offset;
+      }
+      int newOffset = offset + cdata.length;
+      if (offset <= begin && begin < newOffset) {
+        hasSelection = node == anchorNode;
+        anchorOffset = selection.anchorOffset;
+        Node marker = new Text("");
+        node.replaceWith(marker);
+        // TODO(ahe): Don't highlight everything in the node.  Find
+        // the relevant token.
+        if (kind == 'error') {
+          marker.replaceWith(diagnostic(node, error(message)));
+        } else if (kind == 'warning') {
+          marker.replaceWith(diagnostic(node, warning(message)));
+        } else {
+          marker.replaceWith(diagnostic(node, info(message)));
+        }
+        if (hasSelection) {
+          selection.collapse(node, anchorOffset);
+        }
+        foundNode = true;
+        return;
+      }
+      offset = newOffset;
+    } else if (type == Node.ELEMENT_NODE) {
+      Element element = node;
+      if (element.classes.contains('alert')) return;
+    }
+
+    var child = node.firstChild;
+    while(child != null && !foundNode) {
+      walk4(child);
+      child = child.nextNode;
+    }
+  }
+  walk4(inputPre);
+
+  if (!foundNode) {
+    outputDiv.appendText('$message\n');
+  }
+
+  observer.takeRecords();
+  observer.observe(
+      inputPre, childList: true, characterData: true, subtree: true);
+}
+
+void inlineChildren(Element element) {
+  if (element == null) return;
+  var parent = element.parentNode;
+  if (parent == null) return;
+  for (Node child in new List.from(element.nodes)) {
+    child.remove();
+    parent.insertBefore(child, element);
+  }
+  element.remove();
+}
+
+Decoration getDecoration(Token token) {
+  String tokenValue = token.value;
+  String tokenInfo = token.info.value;
+  if (tokenInfo == 'string') return currentTheme.string;
+  // if (tokenInfo == 'identifier') return identifier;
+  if (tokenInfo == 'keyword') return currentTheme.keyword;
+  if (tokenInfo == 'comment') return currentTheme.singleLineComment;
+  if (tokenInfo == 'malformed input') {
+    isMalformedInput = true;
+    return new DiagnosticDecoration('error', tokenValue);
+  }
+  return null;
+}
+
+diagnostic(text, tip) {
+  if (text is String) {
+    text = new Text(text);
+  }
+  return new AnchorElement()
+      ..classes.add('diagnostic')
+      ..append(text)
+      ..append(tip);
+}
diff --git a/site/try/src/extract_theme.dart b/site/try/src/extract_theme.dart
new file mode 100644
index 0000000..8a79516
--- /dev/null
+++ b/site/try/src/extract_theme.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+StringBuffer themes = new StringBuffer();
+
+void main() {
+  print('part of trydart.themes;\n');
+  new Options().arguments.forEach(extractTheme);
+  print('''
+/// List of known themes. The default is the first theme.
+const List<Theme> THEMES = const <Theme> [
+    const Theme(),
+$themes];''');
+}
+
+final DECORATION_PATTERN = new RegExp(r'^ *<([a-z][^ ]+)[ ]');
+
+String attr(String name, String line) {
+  var match = new RegExp('$name'r'="([^"]*)"').firstMatch(line);
+  if (match == null) return null;
+  return match[1];
+}
+
+void extractTheme(String filename) {
+  bool openedTheme = false;
+  for (String line in new File(filename).readAsLinesSync()) {
+    if (line.startsWith('<colorTheme')) {
+      openTheme(line, filename);
+      openedTheme = true;
+    } else if (line.startsWith('</colorTheme>')) {
+      if (!openedTheme) throw 'Theme not found in $filename';
+      closeTheme();
+      openedTheme = false;
+    } else if (DECORATION_PATTERN.hasMatch(line)) {
+      if (!openedTheme) throw 'Theme not found in $filename';
+      printDecoration(line);
+    }
+  }
+}
+
+openTheme(String line, String filename) {
+  var name = attr('name', line);
+  var author = attr('author', line);
+  if (name == null) name = 'Untitled';
+  if (name == 'Default') name = 'Dart Editor';
+  var declaration = name.replaceAll(new RegExp('[^a-zA-Z0-9_]'), '_');
+  themes.write('    const ${declaration}Theme(),\n');
+  print('/// $name theme extracted from');
+  print('/// $filename.');
+  if (author != null) {
+    print('/// Author: $author.');
+  }
+  print("""
+class ${declaration}Theme extends Theme {
+  const ${declaration}Theme();
+
+  String get name => '$name';
+""");
+}
+
+closeTheme() {
+  print('}\n');
+}
+
+printDecoration(String line) {
+  String name = DECORATION_PATTERN.firstMatch(line)[1];
+  if (name == 'class') name = 'className';
+  if (name == 'enum') name = 'enumName';
+  StringBuffer properties = new StringBuffer();
+  var color = attr('color', line);
+  if (color != null) {
+    properties.write("color: '$color'");
+  }
+  var bold = attr('bold', line) == 'true';
+  if (bold) {
+    if (!properties.isEmpty) properties.write(', ');
+    properties.write('bold: true');
+  }
+  print('  Decoration get $name => const Decoration($properties);');
+}
diff --git a/site/try/src/extracted_themes.dart b/site/try/src/extracted_themes.dart
new file mode 100644
index 0000000..43a37fc
--- /dev/null
+++ b/site/try/src/extracted_themes.dart
@@ -0,0 +1,1479 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 trydart.themes;
+
+/// Black Pastel theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/black-pastel.xml.
+/// Author: David.
+class Black_PastelTheme extends Theme {
+  const Black_PastelTheme();
+
+  String get name => 'Black Pastel';
+
+  Decoration get abstractMethod => const Decoration(color: '#E0E2E4');
+  Decoration get annotation => const Decoration(color: '#A082BD');
+  Decoration get background => const Decoration(color: '#000000');
+  Decoration get bracket => const Decoration(color: '#CCCCCC');
+  Decoration get className => const Decoration(color: '#82677E');
+  Decoration get commentTaskTag => const Decoration(color: '#a57b61');
+  Decoration get constant => const Decoration(color: '#A082BD');
+  Decoration get currentLine => const Decoration(color: '#2F393C');
+  Decoration get deletionIndication => const Decoration(color: '#E0E2E4');
+  Decoration get deprecatedMember => const Decoration(color: '#E0E2E4');
+  Decoration get dynamicType => const Decoration(color: '#E0E2E4');
+  Decoration get enumName => const Decoration(color: '#E0E2E4');
+  Decoration get field => const Decoration(color: '#678CB1');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#616161');
+  Decoration get findScope => const Decoration(color: '#E0E2E4');
+  Decoration get foreground => const Decoration(color: '#C0C0C0');
+  Decoration get inheritedMethod => const Decoration(color: '#E0E2E4');
+  Decoration get interface => const Decoration(color: '#82677E');
+  Decoration get javadoc => const Decoration(color: '#7D8C93');
+  Decoration get javadocKeyword => const Decoration(color: '#A082BD');
+  Decoration get javadocLink => const Decoration(color: '#678CB1');
+  Decoration get javadocTag => const Decoration(color: '#E0E2E4');
+  Decoration get keyword => const Decoration(color: '#82677E');
+  Decoration get lineNumber => const Decoration(color: '#81969A');
+  Decoration get localVariable => const Decoration(color: '#E0E2E4');
+  Decoration get localVariableDeclaration => const Decoration(color: '#E0E2E4');
+  Decoration get method => const Decoration(color: '#82677E');
+  Decoration get methodDeclaration => const Decoration(color: '#82677E');
+  Decoration get multiLineComment => const Decoration(color: '#7D8C93');
+  Decoration get number => const Decoration(color: '#c78d9b');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#E8E2B7');
+  Decoration get parameterVariable => const Decoration(color: '#E0E2E4');
+  Decoration get searchResultIndication => const Decoration(color: '#616161');
+  Decoration get selectionBackground => const Decoration(color: '#95bed8');
+  Decoration get selectionForeground => const Decoration(color: '#C0C0C0');
+  Decoration get singleLineComment => const Decoration(color: '#7D8C93');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
+  Decoration get staticField => const Decoration(color: '#678CB1');
+  Decoration get staticFinalField => const Decoration(color: '#E0E2E4');
+  Decoration get staticMethod => const Decoration(color: '#E0E2E4');
+  Decoration get string => const Decoration(color: '#c78d9b');
+  Decoration get typeArgument => const Decoration(color: '#E0E2E4');
+  Decoration get typeParameter => const Decoration(color: '#E0E2E4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#616161');
+}
+
+/// Dartboard theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/dartboard.xml.
+/// Author: Dart.
+class DartboardTheme extends Theme {
+  const DartboardTheme();
+
+  String get name => 'Dartboard';
+
+  Decoration get abstractMethod => const Decoration(color: '#000000');
+  Decoration get annotation => const Decoration(color: '#000000');
+  Decoration get background => const Decoration(color: '#fafafa');
+  Decoration get bracket => const Decoration(color: '#606060');
+  Decoration get builtin => const Decoration(color: '#000000', bold: true);
+  Decoration get className => const Decoration(color: '#0646a7');
+  Decoration get commentTaskTag => const Decoration(color: '#606060');
+  Decoration get constant => const Decoration(color: '#55122a');
+  Decoration get currentLine => const Decoration(color: '#F0F0F0');
+  Decoration get deletionIndication => const Decoration(color: '#000000');
+  Decoration get deprecatedMember => const Decoration(color: '#000000');
+  Decoration get directive => const Decoration(color: '#014d64', bold: true);
+  Decoration get dynamicType => const Decoration(color: '#000000');
+  Decoration get enumName => const Decoration(color: '#000000');
+  Decoration get field => const Decoration(color: '#87312e');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#000000');
+  Decoration get findScope => const Decoration(color: '#000000');
+  Decoration get foreground => const Decoration(color: '#000000');
+  Decoration get getter => const Decoration(color: '#87312e');
+  Decoration get inheritedMethod => const Decoration(color: '#000000');
+  Decoration get interface => const Decoration(color: '#000000');
+  Decoration get javadoc => const Decoration(color: '#606060');
+  Decoration get javadocKeyword => const Decoration(color: '#606060');
+  Decoration get javadocLink => const Decoration(color: '#606060');
+  Decoration get javadocTag => const Decoration(color: '#606060');
+  Decoration get keyword => const Decoration(color: '#000000', bold: true);
+  Decoration get keywordReturn => const Decoration(color: '#000000', bold: true);
+  Decoration get lineNumber => const Decoration(color: '#000000');
+  Decoration get localVariable => const Decoration(color: '#000000');
+  Decoration get localVariableDeclaration => const Decoration(color: '#000000');
+  Decoration get method => const Decoration(color: '#000000');
+  Decoration get methodDeclaration => const Decoration(color: '#0b5bd2', bold: true);
+  Decoration get multiLineComment => const Decoration(color: '#606060');
+  Decoration get multiLineString => const Decoration(color: '#679b3b');
+  Decoration get number => const Decoration(color: '#000000');
+  Decoration get occurrenceIndication => const Decoration(color: '#e0e0e0');
+  Decoration get operator => const Decoration(color: '#000000');
+  Decoration get parameterVariable => const Decoration(color: '#87312e');
+  Decoration get searchResultIndication => const Decoration(color: '#D0D0D0');
+  Decoration get selectionBackground => const Decoration(color: '#b6d6fd');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get setter => const Decoration(color: '#87312e');
+  Decoration get singleLineComment => const Decoration(color: '#7a7a7a');
+  Decoration get sourceHoverBackground => const Decoration(color: '#fbfbc8');
+  Decoration get staticField => const Decoration(color: '#87312e');
+  Decoration get staticFinalField => const Decoration(color: '#55122a');
+  Decoration get staticMethod => const Decoration(color: '#000000');
+  Decoration get staticMethodDeclaration => const Decoration(color: '#0b5bd2', bold: true);
+  Decoration get string => const Decoration(color: '#679b3b');
+  Decoration get typeArgument => const Decoration(color: '#033178');
+  Decoration get typeParameter => const Decoration(color: '#033178');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#e0e0e0');
+}
+
+/// Debugging theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/debugging.xml.
+/// Author: Debug Tool.
+class DebuggingTheme extends Theme {
+  const DebuggingTheme();
+
+  String get name => 'Debugging';
+
+  Decoration get abstractMethod => const Decoration(color: '#F00000');
+  Decoration get annotation => const Decoration(color: '#F00000');
+  Decoration get background => const Decoration(color: '#FFF8FF');
+  Decoration get bracket => const Decoration(color: '#F00000');
+  Decoration get builtin => const Decoration(color: '#F00000');
+  Decoration get className => const Decoration(color: '#F00000');
+  Decoration get commentTaskTag => const Decoration(color: '#F00000');
+  Decoration get constant => const Decoration(color: '#F00000');
+  Decoration get currentLine => const Decoration(color: '#F0F0F0');
+  Decoration get deletionIndication => const Decoration(color: '#F00000');
+  Decoration get deprecatedMember => const Decoration(color: '#F00000');
+  Decoration get directive => const Decoration(color: '#F00000');
+  Decoration get dynamicType => const Decoration(color: '#F00000');
+  Decoration get enumName => const Decoration(color: '#F00000');
+  Decoration get field => const Decoration(color: '#F000000');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#F00000');
+  Decoration get findScope => const Decoration(color: '#F00000');
+  Decoration get foreground => const Decoration(color: '#F00000');
+  Decoration get getter => const Decoration(color: '#F00000');
+  Decoration get inheritedMethod => const Decoration(color: '#F00000');
+  Decoration get interface => const Decoration(color: '#F00000');
+  Decoration get javadoc => const Decoration(color: '#F00000');
+  Decoration get javadocKeyword => const Decoration(color: '#F00000');
+  Decoration get javadocLink => const Decoration(color: '#F00000');
+  Decoration get javadocTag => const Decoration(color: '#F00000');
+  Decoration get keyword => const Decoration(color: '#F00000', bold: true);
+  Decoration get keywordReturn => const Decoration(color: '#F00000', bold: true);
+  Decoration get lineNumber => const Decoration(color: '#F00000');
+  Decoration get localVariable => const Decoration(color: '#F00000');
+  Decoration get localVariableDeclaration => const Decoration(color: '#F00000');
+  Decoration get method => const Decoration(color: '#F00000');
+  Decoration get methodDeclaration => const Decoration(color: '#F00000');
+  Decoration get multiLineComment => const Decoration(color: '#F00000');
+  Decoration get multiLineString => const Decoration(color: '#F00000');
+  Decoration get number => const Decoration(color: '#F00000');
+  Decoration get occurrenceIndication => const Decoration(color: '#F00000');
+  Decoration get operator => const Decoration(color: '#F00000');
+  Decoration get parameterVariable => const Decoration(color: '#F00000');
+  Decoration get searchResultIndication => const Decoration(color: '#F00000');
+  Decoration get selectionBackground => const Decoration(color: '#F000F0');
+  Decoration get selectionForeground => const Decoration(color: '#F00000');
+  Decoration get setter => const Decoration(color: '#F00000');
+  Decoration get singleLineComment => const Decoration(color: '#F00000');
+  Decoration get sourceHoverBackground => const Decoration(color: '#F00000');
+  Decoration get staticField => const Decoration(color: '#F00000');
+  Decoration get staticFinalField => const Decoration(color: '#F00000');
+  Decoration get staticMethod => const Decoration(color: '#F00000');
+  Decoration get staticMethodDeclaration => const Decoration(color: '#F00000');
+  Decoration get string => const Decoration(color: '#F00000');
+  Decoration get typeArgument => const Decoration(color: '#F00000');
+  Decoration get typeParameter => const Decoration(color: '#F00000');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#F00000');
+}
+
+/// Dart Editor theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/default.xml.
+/// Author: Dart.
+class Dart_EditorTheme extends Theme {
+  const Dart_EditorTheme();
+
+  String get name => 'Dart Editor';
+
+  Decoration get abstractMethod => const Decoration(color: '#000000');
+  Decoration get annotation => const Decoration(color: '#000000');
+  Decoration get background => const Decoration(color: '#ffffff');
+  Decoration get bracket => const Decoration(color: '#000000');
+  Decoration get builtin => const Decoration(color: '#7e0854', bold: true);
+  Decoration get className => const Decoration(color: '#000000');
+  Decoration get commentTaskTag => const Decoration(color: '#606060');
+  Decoration get constant => const Decoration(color: '#000000');
+  Decoration get currentLine => const Decoration(color: '#F0F0F0');
+  Decoration get deletionIndication => const Decoration(color: '#000000');
+  Decoration get deprecatedMember => const Decoration(color: '#000000');
+  Decoration get directive => const Decoration(color: '#7e0854', bold: true);
+  Decoration get dynamicType => const Decoration(color: '#000000');
+  Decoration get enumName => const Decoration(color: '#000000');
+  Decoration get field => const Decoration(color: '#0618bd');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#000000');
+  Decoration get findScope => const Decoration(color: '#000000');
+  Decoration get foreground => const Decoration(color: '#000000');
+  Decoration get getter => const Decoration(color: '#0618bd');
+  Decoration get inheritedMethod => const Decoration(color: '#000000');
+  Decoration get interface => const Decoration(color: '#000000');
+  Decoration get javadoc => const Decoration(color: '#4162bc');
+  Decoration get javadocKeyword => const Decoration(color: '#4162bc');
+  Decoration get javadocLink => const Decoration(color: '#4162bc');
+  Decoration get javadocTag => const Decoration(color: '#7f809e');
+  Decoration get keyword => const Decoration(color: '#7e0854', bold: true);
+  Decoration get keywordReturn => const Decoration(color: '#7e0854', bold: true);
+  Decoration get lineNumber => const Decoration(color: '#000000');
+  Decoration get localVariable => const Decoration(color: '#7f1cc9');
+  Decoration get localVariableDeclaration => const Decoration(color: '#7f1cc9');
+  Decoration get method => const Decoration(color: '#000000');
+  Decoration get methodDeclaration => const Decoration(color: '#0b5bd2', bold: true);
+  Decoration get multiLineComment => const Decoration(color: '#4162bc');
+  Decoration get multiLineString => const Decoration(color: '#2d24fb');
+  Decoration get number => const Decoration(color: '#0c6f0e');
+  Decoration get occurrenceIndication => const Decoration(color: '#e0e0e0');
+  Decoration get operator => const Decoration(color: '#000000');
+  Decoration get parameterVariable => const Decoration(color: '#87312e');
+  Decoration get searchResultIndication => const Decoration(color: '#D0D0D0');
+  Decoration get selectionBackground => const Decoration(color: '#b6d6fd');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get setter => const Decoration(color: '#0618bd');
+  Decoration get singleLineComment => const Decoration(color: '#417e60');
+  Decoration get sourceHoverBackground => const Decoration(color: '#fbfbc8');
+  Decoration get staticField => const Decoration(color: '#0618bd');
+  Decoration get staticFinalField => const Decoration(color: '#0618bd');
+  Decoration get staticMethod => const Decoration(color: '#000000');
+  Decoration get staticMethodDeclaration => const Decoration(color: '#404040', bold: true);
+  Decoration get string => const Decoration(color: '#2d24fb');
+  Decoration get typeArgument => const Decoration(color: '#033178');
+  Decoration get typeParameter => const Decoration(color: '#033178');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#e0e0e0');
+}
+
+/// frontenddev theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/frontenddev.xml.
+/// Author: Plebe.
+class frontenddevTheme extends Theme {
+  const frontenddevTheme();
+
+  String get name => 'frontenddev';
+
+  Decoration get abstractMethod => const Decoration(color: '#F1C436');
+  Decoration get annotation => const Decoration(color: '#999999');
+  Decoration get background => const Decoration(color: '#000000');
+  Decoration get bracket => const Decoration(color: '#FFFFFF');
+  Decoration get className => const Decoration(color: '#9CF828');
+  Decoration get commentTaskTag => const Decoration(color: '#666666');
+  Decoration get currentLine => const Decoration(color: '#222220');
+  Decoration get deletionIndication => const Decoration(color: '#FF0000');
+  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
+  Decoration get dynamicType => const Decoration(color: '#F7C527');
+  Decoration get enumName => const Decoration(color: '#408000');
+  Decoration get field => const Decoration(color: '#c38705');
+  Decoration get findScope => const Decoration(color: '#191919');
+  Decoration get foreground => const Decoration(color: '#FFFFFF');
+  Decoration get inheritedMethod => const Decoration(color: '#E3B735');
+  Decoration get interface => const Decoration(color: '#87F025');
+  Decoration get javadoc => const Decoration(color: '#666666');
+  Decoration get javadocKeyword => const Decoration(color: '#800080');
+  Decoration get javadocLink => const Decoration(color: '#666666');
+  Decoration get javadocTag => const Decoration(color: '#800080');
+  Decoration get keyword => const Decoration(color: '#999999');
+  Decoration get lineNumber => const Decoration(color: '#999999');
+  Decoration get localVariable => const Decoration(color: '#F7C527');
+  Decoration get localVariableDeclaration => const Decoration(color: '#F7C527');
+  Decoration get method => const Decoration(color: '#F7C527');
+  Decoration get methodDeclaration => const Decoration(color: '#F1C438');
+  Decoration get multiLineComment => const Decoration(color: '#666666');
+  Decoration get number => const Decoration(color: '#FF0000');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#FFFFFF');
+  Decoration get parameterVariable => const Decoration(color: '#069609');
+  Decoration get selectionBackground => const Decoration(color: '#333333');
+  Decoration get selectionForeground => const Decoration(color: '#333333');
+  Decoration get singleLineComment => const Decoration(color: '#666666');
+  Decoration get staticField => const Decoration(color: '#FFFFFF');
+  Decoration get staticFinalField => const Decoration(color: '#80FF00');
+  Decoration get staticMethod => const Decoration(color: '#FFFFFF');
+  Decoration get string => const Decoration(color: '#00a40f');
+  Decoration get typeArgument => const Decoration(color: '#D9B0AC');
+  Decoration get typeParameter => const Decoration(color: '#CDB1AD');
+}
+
+/// Gedit Original Oblivion theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/gedit-original-oblivion.xml.
+/// Author: Sepehr Lajevardi.
+class Gedit_Original_OblivionTheme extends Theme {
+  const Gedit_Original_OblivionTheme();
+
+  String get name => 'Gedit Original Oblivion';
+
+  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
+  Decoration get annotation => const Decoration(color: '#FFFFFF');
+  Decoration get background => const Decoration(color: '#2e3436');
+  Decoration get bracket => const Decoration(color: '#D8D8D8');
+  Decoration get className => const Decoration(color: '#bbbbbb');
+  Decoration get commentTaskTag => const Decoration(color: '#CCDF32');
+  Decoration get constant => const Decoration(color: '#edd400');
+  Decoration get currentLine => const Decoration(color: '#555753');
+  Decoration get deletionIndication => const Decoration(color: '#D25252');
+  Decoration get dynamicType => const Decoration(color: '#729fcf');
+  Decoration get field => const Decoration(color: '#BED6FF');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get findScope => const Decoration(color: '#000000');
+  Decoration get foreground => const Decoration(color: '#d3d7cf');
+  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
+  Decoration get interface => const Decoration(color: '#D197D9');
+  Decoration get javadoc => const Decoration(color: '#888a85');
+  Decoration get javadocKeyword => const Decoration(color: '#888a85');
+  Decoration get javadocLink => const Decoration(color: '#888a85');
+  Decoration get javadocTag => const Decoration(color: '#888a85');
+  Decoration get keyword => const Decoration(color: '#FFFFFF');
+  Decoration get lineNumber => const Decoration(color: '#555753');
+  Decoration get localVariable => const Decoration(color: '#729fcf');
+  Decoration get localVariableDeclaration => const Decoration(color: '#729fcf');
+  Decoration get method => const Decoration(color: '#FFFFFF');
+  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get multiLineComment => const Decoration(color: '#888a85');
+  Decoration get number => const Decoration(color: '#ce5c00');
+  Decoration get occurrenceIndication => const Decoration(color: '#000000');
+  Decoration get operator => const Decoration(color: '#D8D8D8');
+  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
+  Decoration get searchResultIndication => const Decoration(color: '#eeeeec');
+  Decoration get selectionBackground => const Decoration(color: '#888a85');
+  Decoration get selectionForeground => const Decoration(color: '#eeeeec');
+  Decoration get singleLineComment => const Decoration(color: '#888a85');
+  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
+  Decoration get staticField => const Decoration(color: '#EFC090');
+  Decoration get staticFinalField => const Decoration(color: '#EFC090');
+  Decoration get staticMethod => const Decoration(color: '#BED6FF');
+  Decoration get string => const Decoration(color: '#edd400');
+  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
+  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
+}
+
+/// Havenjark theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/havenjark.xml.
+/// Author: Rodrigo Franco.
+class HavenjarkTheme extends Theme {
+  const HavenjarkTheme();
+
+  String get name => 'Havenjark';
+
+  Decoration get abstractMethod => const Decoration(color: '#C0B6A8');
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#2D3639');
+  Decoration get bracket => const Decoration(color: '#FFFFFF');
+  Decoration get className => const Decoration(color: '#B8ADA0');
+  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
+  Decoration get constant => const Decoration(color: '#93A2CC');
+  Decoration get currentLine => const Decoration(color: '#00001F');
+  Decoration get deprecatedMember => const Decoration(color: '#F3D651');
+  Decoration get dynamicType => const Decoration(color: '#A19A83');
+  Decoration get field => const Decoration(color: '#B3B784');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#3F3F6A');
+  Decoration get findScope => const Decoration(color: '#B9A185');
+  Decoration get foreground => const Decoration(color: '#C0B6A8');
+  Decoration get inheritedMethod => const Decoration(color: '#C0B6A8');
+  Decoration get interface => const Decoration(color: '#B8ADA0');
+  Decoration get javadoc => const Decoration(color: '#B3B5AF');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#A893CC');
+  Decoration get javadocTag => const Decoration(color: '#9393CC');
+  Decoration get keyword => const Decoration(color: '#A38474');
+  Decoration get lineNumber => const Decoration(color: '#C0C0C0');
+  Decoration get localVariable => const Decoration(color: '#A19A83');
+  Decoration get localVariableDeclaration => const Decoration(color: '#A19A83');
+  Decoration get method => const Decoration(color: '#DFBE95');
+  Decoration get methodDeclaration => const Decoration(color: '#DFBE95');
+  Decoration get multiLineComment => const Decoration(color: '#AEAEAE');
+  Decoration get multiLineString => const Decoration(color: '#808080');
+  Decoration get number => const Decoration(color: '#B9A185');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#F0EFD0');
+  Decoration get parameterVariable => const Decoration(color: '#A19A83');
+  Decoration get searchResultIndication => const Decoration(color: '#464467');
+  Decoration get selectionBackground => const Decoration(color: '#2A4750');
+  Decoration get selectionForeground => const Decoration(color: '#C0B6A8');
+  Decoration get singleLineComment => const Decoration(color: '#AEAEAE');
+  Decoration get sourceHoverBackground => const Decoration(color: '#A19879');
+  Decoration get staticField => const Decoration(color: '#93A2CC');
+  Decoration get staticFinalField => const Decoration(color: '#93A2CC');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#CC9393');
+  Decoration get typeArgument => const Decoration(color: '#C0B6A8');
+  Decoration get typeParameter => const Decoration(color: '#C0B6A8');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
+}
+
+/// Hot Pink theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/hotpink.xml.
+/// Author: KS.
+class Hot_PinkTheme extends Theme {
+  const Hot_PinkTheme();
+
+  String get name => 'Hot Pink';
+
+  Decoration get abstractMethod => const Decoration(color: '#000000');
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#FFFFFF');
+  Decoration get bracket => const Decoration(color: '#000f6a');
+  Decoration get builtin => const Decoration(color: '#7e0854');
+  Decoration get className => const Decoration(color: '#008000', bold: true);
+  Decoration get commentTaskTag => const Decoration(color: '#417e60');
+  Decoration get constant => const Decoration(color: '#ae25ab');
+  Decoration get currentLine => const Decoration(color: '#fff7cd');
+  Decoration get deletionIndication => const Decoration(color: '#9b5656');
+  Decoration get deprecatedMember => const Decoration(color: '#000000');
+  Decoration get directive => const Decoration(color: '#FF4040');
+  Decoration get dynamicType => const Decoration(color: '#FF4040');
+  Decoration get enumName => const Decoration(color: '#000000');
+  Decoration get field => const Decoration(color: '#0000C0');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#CC6633');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#000000');
+  Decoration get getter => const Decoration(color: '#0200C0');
+  Decoration get inheritedMethod => const Decoration(color: '#2c577c');
+  Decoration get interface => const Decoration(color: '#000000');
+  Decoration get javadoc => const Decoration(color: '#4162bc');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#4162bc');
+  Decoration get javadocTag => const Decoration(color: '#4162bc');
+  Decoration get keyword => const Decoration(color: '#7e0854', bold: true);
+  Decoration get keywordReturn => const Decoration(color: '#800390', bold: true);
+  Decoration get lineNumber => const Decoration(color: '#999999');
+  Decoration get localVariable => const Decoration(color: '#FF00FF');
+  Decoration get localVariableDeclaration => const Decoration(color: '#008080');
+  Decoration get method => const Decoration(color: '#2BA6E8');
+  Decoration get methodDeclaration => const Decoration(color: '#8000FF');
+  Decoration get multiLineComment => const Decoration(color: '#417e60');
+  Decoration get multiLineString => const Decoration(color: '#2000FF');
+  Decoration get number => const Decoration(color: '#008000');
+  Decoration get occurrenceIndication => const Decoration(color: '#CC6633');
+  Decoration get operator => const Decoration(color: '#5f97a9');
+  Decoration get parameterVariable => const Decoration(color: '#D7721E');
+  Decoration get searchResultIndication => const Decoration(color: '#CC6633');
+  Decoration get selectionBackground => const Decoration(color: '#c0c0c0');
+  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
+  Decoration get setter => const Decoration(color: '#0200C0');
+  Decoration get singleLineComment => const Decoration(color: '#417e60');
+  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
+  Decoration get staticField => const Decoration(color: '#0000C0');
+  Decoration get staticFinalField => const Decoration(color: '#464646');
+  Decoration get staticMethod => const Decoration(color: '#2BA6E8', bold: true);
+  Decoration get staticMethodDeclaration => const Decoration(color: '#8000FF', bold: true);
+  Decoration get string => const Decoration(color: '#2000FF');
+  Decoration get typeArgument => const Decoration(color: '#d07fcd');
+  Decoration get typeParameter => const Decoration(color: '#D00000', bold: true);
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#CC6633');
+}
+
+/// Inkpot theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/inkpot.xml.
+/// Author: Ciaran McCreesh.
+class InkpotTheme extends Theme {
+  const InkpotTheme();
+
+  String get name => 'Inkpot';
+
+  Decoration get background => const Decoration(color: '#1F1F27');
+  Decoration get bracket => const Decoration(color: '#CFBFAD');
+  Decoration get className => const Decoration(color: '#87CEFA');
+  Decoration get commentTaskTag => const Decoration(color: '#FF8BFF');
+  Decoration get currentLine => const Decoration(color: '#2D2D44');
+  Decoration get dynamicType => const Decoration(color: '#CFBFAD');
+  Decoration get enumName => const Decoration(color: '#CFBFAD');
+  Decoration get foreground => const Decoration(color: '#CFBFAD');
+  Decoration get interface => const Decoration(color: '#87FAC4');
+  Decoration get keyword => const Decoration(color: '#808BED');
+  Decoration get lineNumber => const Decoration(color: '#2B91AF');
+  Decoration get localVariable => const Decoration(color: '#CFBFAD');
+  Decoration get localVariableDeclaration => const Decoration(color: '#CFBFAD');
+  Decoration get method => const Decoration(color: '#87CEFA');
+  Decoration get methodDeclaration => const Decoration(color: '#CFBFAD');
+  Decoration get multiLineComment => const Decoration(color: '#CD8B00');
+  Decoration get number => const Decoration(color: '#FFCD8B');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#CFBFAD');
+  Decoration get selectionBackground => const Decoration(color: '#8B8BFF');
+  Decoration get selectionForeground => const Decoration(color: '#404040');
+  Decoration get singleLineComment => const Decoration(color: '#CD8B00');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
+  Decoration get string => const Decoration(color: '#FFCD8B');
+}
+
+/// minimal theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/minimal.xml.
+/// Author: meers davy.
+class minimalTheme extends Theme {
+  const minimalTheme();
+
+  String get name => 'minimal';
+
+  Decoration get abstractMethod => const Decoration(color: '#5c8198');
+  Decoration get annotation => const Decoration(color: '#AAAAFF');
+  Decoration get background => const Decoration(color: '#ffffff');
+  Decoration get bracket => const Decoration(color: '#000066');
+  Decoration get className => const Decoration(color: '#000066');
+  Decoration get commentTaskTag => const Decoration(color: '#666666');
+  Decoration get currentLine => const Decoration(color: '#aaccff');
+  Decoration get deletionIndication => const Decoration(color: '#aaccff');
+  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
+  Decoration get enumName => const Decoration(color: '#000066');
+  Decoration get field => const Decoration(color: '#566874');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#EFEFEF');
+  Decoration get findScope => const Decoration(color: '#BCADff');
+  Decoration get foreground => const Decoration(color: '#000000');
+  Decoration get inheritedMethod => const Decoration(color: '#5c8198');
+  Decoration get interface => const Decoration(color: '#000066');
+  Decoration get javadoc => const Decoration(color: '#05314d');
+  Decoration get javadocKeyword => const Decoration(color: '#05314d');
+  Decoration get javadocLink => const Decoration(color: '#05314d');
+  Decoration get javadocTag => const Decoration(color: '#05314d');
+  Decoration get keyword => const Decoration(color: '#5c8198');
+  Decoration get lineNumber => const Decoration(color: '#666666');
+  Decoration get localVariable => const Decoration(color: '#5c8198');
+  Decoration get localVariableDeclaration => const Decoration(color: '#5c8198');
+  Decoration get method => const Decoration(color: '#5c8198');
+  Decoration get methodDeclaration => const Decoration(color: '#5c8198');
+  Decoration get multiLineComment => const Decoration(color: '#334466');
+  Decoration get number => const Decoration(color: '#333333');
+  Decoration get occurrenceIndication => const Decoration(color: '#EFEFEF');
+  Decoration get operator => const Decoration(color: '#333333');
+  Decoration get parameterVariable => const Decoration(color: '#5c8198');
+  Decoration get searchResultIndication => const Decoration(color: '#EFEFEF');
+  Decoration get selectionBackground => const Decoration(color: '#Efefff');
+  Decoration get selectionForeground => const Decoration(color: '#000066');
+  Decoration get singleLineComment => const Decoration(color: '#334466');
+  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
+  Decoration get staticField => const Decoration(color: '#05314d');
+  Decoration get staticFinalField => const Decoration(color: '#05314d');
+  Decoration get staticMethod => const Decoration(color: '#5c8198');
+  Decoration get string => const Decoration(color: '#333333');
+  Decoration get typeArgument => const Decoration(color: '#5c8198');
+  Decoration get typeParameter => const Decoration(color: '#5c8198');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#EFEFEF');
+}
+
+/// Monokai theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/monokai.xml.
+/// Author: Truong Xuan Tinh.
+class MonokaiTheme extends Theme {
+  const MonokaiTheme();
+
+  String get name => 'Monokai';
+
+  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
+  Decoration get annotation => const Decoration(color: '#FFFFFF');
+  Decoration get background => const Decoration(color: '#272822');
+  Decoration get bracket => const Decoration(color: '#D8D8D8');
+  Decoration get className => const Decoration(color: '#FFFFFF');
+  Decoration get commentTaskTag => const Decoration(color: '#CCDF32');
+  Decoration get constant => const Decoration(color: '#EFB571');
+  Decoration get currentLine => const Decoration(color: '#3E3D32');
+  Decoration get deletionIndication => const Decoration(color: '#D25252');
+  Decoration get deprecatedMember => const Decoration(color: '#F8F8F2');
+  Decoration get dynamicType => const Decoration(color: '#79ABFF');
+  Decoration get enumName => const Decoration(color: '#66D9EF');
+  Decoration get field => const Decoration(color: '#BED6FF');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get findScope => const Decoration(color: '#000000');
+  Decoration get foreground => const Decoration(color: '#F8F8F2');
+  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
+  Decoration get interface => const Decoration(color: '#D197D9');
+  Decoration get javadoc => const Decoration(color: '#75715E');
+  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
+  Decoration get javadocLink => const Decoration(color: '#D9E577');
+  Decoration get javadocTag => const Decoration(color: '#D9E577');
+  Decoration get keyword => const Decoration(color: '#66CCB3');
+  Decoration get lineNumber => const Decoration(color: '#F8F8F2');
+  Decoration get localVariable => const Decoration(color: '#79ABFF');
+  Decoration get localVariableDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get method => const Decoration(color: '#FFFFFF');
+  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get multiLineComment => const Decoration(color: '#75715e');
+  Decoration get number => const Decoration(color: '#7FB347');
+  Decoration get occurrenceIndication => const Decoration(color: '#000000');
+  Decoration get operator => const Decoration(color: '#D8D8D8');
+  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
+  Decoration get searchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get selectionBackground => const Decoration(color: '#757575');
+  Decoration get selectionForeground => const Decoration(color: '#D0D0D0');
+  Decoration get singleLineComment => const Decoration(color: '#75715E');
+  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
+  Decoration get staticField => const Decoration(color: '#EFC090');
+  Decoration get staticFinalField => const Decoration(color: '#EFC090');
+  Decoration get staticMethod => const Decoration(color: '#BED6FF');
+  Decoration get string => const Decoration(color: '#E6DB74');
+  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
+  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
+}
+
+/// Mr theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/mr.xml.
+/// Author: Jongosi.
+class MrTheme extends Theme {
+  const MrTheme();
+
+  String get name => 'Mr';
+
+  Decoration get abstractMethod => const Decoration(color: '#000099');
+  Decoration get annotation => const Decoration(color: '#990000');
+  Decoration get background => const Decoration(color: '#FFFFFF');
+  Decoration get bracket => const Decoration(color: '#000099');
+  Decoration get className => const Decoration(color: '#006600');
+  Decoration get commentTaskTag => const Decoration(color: '#FF3300');
+  Decoration get constant => const Decoration(color: '#552200');
+  Decoration get currentLine => const Decoration(color: '#D8D8D8');
+  Decoration get deprecatedMember => const Decoration(color: '#D8D8D8');
+  Decoration get enumName => const Decoration(color: '#FF0000');
+  Decoration get field => const Decoration(color: '#000099');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get foreground => const Decoration(color: '#333333');
+  Decoration get inheritedMethod => const Decoration(color: '#000099');
+  Decoration get interface => const Decoration(color: '#666666');
+  Decoration get javadoc => const Decoration(color: '#FF3300');
+  Decoration get javadocKeyword => const Decoration(color: '#990099');
+  Decoration get javadocLink => const Decoration(color: '#990099');
+  Decoration get javadocTag => const Decoration(color: '#990099');
+  Decoration get keyword => const Decoration(color: '#0000FF');
+  Decoration get lineNumber => const Decoration(color: '#D8D8D8');
+  Decoration get localVariable => const Decoration(color: '#0066FF');
+  Decoration get localVariableDeclaration => const Decoration(color: '#000099');
+  Decoration get method => const Decoration(color: '#000099');
+  Decoration get methodDeclaration => const Decoration(color: '#000099');
+  Decoration get multiLineComment => const Decoration(color: '#FF9900');
+  Decoration get number => const Decoration(color: '#0000FF');
+  Decoration get occurrenceIndication => const Decoration(color: '#000000');
+  Decoration get operator => const Decoration(color: '#0000FF');
+  Decoration get parameterVariable => const Decoration(color: '#0000FF');
+  Decoration get searchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get selectionBackground => const Decoration(color: '#D8D8D8');
+  Decoration get selectionForeground => const Decoration(color: '#333333');
+  Decoration get singleLineComment => const Decoration(color: '#FF9900');
+  Decoration get sourceHoverBackground => const Decoration(color: '#D8D8D8');
+  Decoration get staticField => const Decoration(color: '#552200');
+  Decoration get staticFinalField => const Decoration(color: '#552200');
+  Decoration get staticMethod => const Decoration(color: '#990000');
+  Decoration get string => const Decoration(color: '#CC0000');
+  Decoration get typeArgument => const Decoration(color: '#0000FF');
+  Decoration get typeParameter => const Decoration(color: '#006600');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
+}
+
+/// NightLion Aptana Theme theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/nightlion-aptana-theme.xml.
+/// Author: NightLion.
+class NightLion_Aptana_ThemeTheme extends Theme {
+  const NightLion_Aptana_ThemeTheme();
+
+  String get name => 'NightLion Aptana Theme';
+
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#1E1E1E');
+  Decoration get bracket => const Decoration(color: '#FFFFFF');
+  Decoration get className => const Decoration(color: '#CAE682');
+  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
+  Decoration get currentLine => const Decoration(color: '#505050');
+  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
+  Decoration get dynamicType => const Decoration(color: '#D4C4A9');
+  Decoration get field => const Decoration(color: '#B3B784');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#3F3F6A');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#E2E2E2');
+  Decoration get interface => const Decoration(color: '#CAE682');
+  Decoration get javadoc => const Decoration(color: '#B3B5AF');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#A893CC');
+  Decoration get javadocTag => const Decoration(color: '#9393CC');
+  Decoration get keyword => const Decoration(color: '#8DCBE2');
+  Decoration get lineNumber => const Decoration(color: '#C0C0C0');
+  Decoration get localVariable => const Decoration(color: '#D4C4A9');
+  Decoration get localVariableDeclaration => const Decoration(color: '#D4C4A9');
+  Decoration get method => const Decoration(color: '#DFBE95');
+  Decoration get methodDeclaration => const Decoration(color: '#DFBE95');
+  Decoration get multiLineComment => const Decoration(color: '#73879B');
+  Decoration get number => const Decoration(color: '#EAB882');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#F0EFD0');
+  Decoration get searchResultIndication => const Decoration(color: '#464467');
+  Decoration get selectionBackground => const Decoration(color: '#364656');
+  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
+  Decoration get singleLineComment => const Decoration(color: '#7F9F7F');
+  Decoration get sourceHoverBackground => const Decoration(color: '#A19879');
+  Decoration get staticField => const Decoration(color: '#93A2CC');
+  Decoration get staticFinalField => const Decoration(color: '#53DCCD');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#CC9393');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
+}
+
+/// Notepad++ Like theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/notepad++-like.xml.
+/// Author: Vokiel.
+class Notepad___LikeTheme extends Theme {
+  const Notepad___LikeTheme();
+
+  String get name => 'Notepad++ Like';
+
+  Decoration get abstractMethod => const Decoration(color: '#FF00FF');
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#FFFFFF');
+  Decoration get bracket => const Decoration(color: '#8000FF');
+  Decoration get className => const Decoration(color: '#000080');
+  Decoration get commentTaskTag => const Decoration(color: '#008000');
+  Decoration get currentLine => const Decoration(color: '#EEEEEE');
+  Decoration get deletionIndication => const Decoration(color: '#9b5656');
+  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
+  Decoration get enumName => const Decoration(color: '#800040');
+  Decoration get field => const Decoration(color: '#800080');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#EFEFEF');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#8000FF');
+  Decoration get inheritedMethod => const Decoration(color: '#FF00FF');
+  Decoration get interface => const Decoration(color: '#9b5656');
+  Decoration get javadoc => const Decoration(color: '#800080');
+  Decoration get javadocKeyword => const Decoration(color: '#0000FF');
+  Decoration get javadocLink => const Decoration(color: '#800080');
+  Decoration get javadocTag => const Decoration(color: '#801f91');
+  Decoration get keyword => const Decoration(color: '#0000FF');
+  Decoration get lineNumber => const Decoration(color: '#999999');
+  Decoration get localVariable => const Decoration(color: '#000080');
+  Decoration get localVariableDeclaration => const Decoration(color: '#000080');
+  Decoration get method => const Decoration(color: '#FF00FF');
+  Decoration get methodDeclaration => const Decoration(color: '#FF00FF');
+  Decoration get multiLineComment => const Decoration(color: '#008000');
+  Decoration get number => const Decoration(color: '#FF8000');
+  Decoration get occurrenceIndication => const Decoration(color: '#EFEFEF');
+  Decoration get operator => const Decoration(color: '#8000FF');
+  Decoration get parameterVariable => const Decoration(color: '#0000FF');
+  Decoration get searchResultIndication => const Decoration(color: '#EFEFEF');
+  Decoration get selectionBackground => const Decoration(color: '#EEEEEE');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get singleLineComment => const Decoration(color: '#008000');
+  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
+  Decoration get staticField => const Decoration(color: '#800040');
+  Decoration get staticFinalField => const Decoration(color: '#800040');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#808080');
+  Decoration get typeArgument => const Decoration(color: '#885d3b');
+  Decoration get typeParameter => const Decoration(color: '#885d3b');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#EFEFEF');
+}
+
+/// Oblivion theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/oblivion.xml.
+/// Author: Roger Dudler.
+class OblivionTheme extends Theme {
+  const OblivionTheme();
+
+  String get name => 'Oblivion';
+
+  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
+  Decoration get annotation => const Decoration(color: '#FFFFFF');
+  Decoration get background => const Decoration(color: '#1E1E1E');
+  Decoration get bracket => const Decoration(color: '#D8D8D8');
+  Decoration get className => const Decoration(color: '#D25252');
+  Decoration get commentTaskTag => const Decoration(color: '#CCDF32');
+  Decoration get constant => const Decoration(color: '#EFC090');
+  Decoration get currentLine => const Decoration(color: '#2A2A2A');
+  Decoration get deletionIndication => const Decoration(color: '#D25252');
+  Decoration get deprecatedMember => const Decoration(color: '#D25252');
+  Decoration get dynamicType => const Decoration(color: '#79ABFF');
+  Decoration get enumName => const Decoration(color: '#7FB347');
+  Decoration get field => const Decoration(color: '#BED6FF');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#000000');
+  Decoration get findScope => const Decoration(color: '#111111');
+  Decoration get foreground => const Decoration(color: '#D8D8D8');
+  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
+  Decoration get interface => const Decoration(color: '#D197D9');
+  Decoration get javadoc => const Decoration(color: '#CCDF32');
+  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
+  Decoration get javadocLink => const Decoration(color: '#D9E577');
+  Decoration get javadocTag => const Decoration(color: '#D9E577');
+  Decoration get keyword => const Decoration(color: '#FFFFFF');
+  Decoration get lineNumber => const Decoration(color: '#D0D0D0');
+  Decoration get localVariable => const Decoration(color: '#79ABFF');
+  Decoration get localVariableDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get method => const Decoration(color: '#FFFFFF');
+  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get multiLineComment => const Decoration(color: '#C7DD0C');
+  Decoration get number => const Decoration(color: '#7FB347');
+  Decoration get occurrenceIndication => const Decoration(color: '#000000');
+  Decoration get operator => const Decoration(color: '#D8D8D8');
+  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
+  Decoration get searchResultIndication => const Decoration(color: '#000000');
+  Decoration get selectionBackground => const Decoration(color: '#404040');
+  Decoration get selectionForeground => const Decoration(color: '#D0D0D0');
+  Decoration get singleLineComment => const Decoration(color: '#C7DD0C');
+  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
+  Decoration get staticField => const Decoration(color: '#EFC090');
+  Decoration get staticFinalField => const Decoration(color: '#EFC090');
+  Decoration get staticMethod => const Decoration(color: '#BED6FF');
+  Decoration get string => const Decoration(color: '#FFC600');
+  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
+  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
+}
+
+/// Obsidian theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/obsidian.xml.
+/// Author: Morinar.
+class ObsidianTheme extends Theme {
+  const ObsidianTheme();
+
+  String get name => 'Obsidian';
+
+  Decoration get abstractMethod => const Decoration(color: '#E0E2E4');
+  Decoration get annotation => const Decoration(color: '#A082BD');
+  Decoration get background => const Decoration(color: '#293134');
+  Decoration get bracket => const Decoration(color: '#E8E2B7');
+  Decoration get className => const Decoration(color: '#678CB1');
+  Decoration get commentTaskTag => const Decoration(color: '#FF8BFF');
+  Decoration get constant => const Decoration(color: '#A082BD');
+  Decoration get currentLine => const Decoration(color: '#2F393C');
+  Decoration get deletionIndication => const Decoration(color: '#E0E2E4');
+  Decoration get deprecatedMember => const Decoration(color: '#E0E2E4');
+  Decoration get dynamicType => const Decoration(color: '#E0E2E4');
+  Decoration get enumName => const Decoration(color: '#E0E2E4');
+  Decoration get field => const Decoration(color: '#678CB1');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#616161');
+  Decoration get findScope => const Decoration(color: '#E0E2E4');
+  Decoration get foreground => const Decoration(color: '#E0E2E4');
+  Decoration get inheritedMethod => const Decoration(color: '#E0E2E4');
+  Decoration get interface => const Decoration(color: '#678CB1');
+  Decoration get javadoc => const Decoration(color: '#7D8C93');
+  Decoration get javadocKeyword => const Decoration(color: '#A082BD');
+  Decoration get javadocLink => const Decoration(color: '#678CB1');
+  Decoration get javadocTag => const Decoration(color: '#E0E2E4');
+  Decoration get keyword => const Decoration(color: '#93C763');
+  Decoration get lineNumber => const Decoration(color: '#81969A');
+  Decoration get localVariable => const Decoration(color: '#E0E2E4');
+  Decoration get localVariableDeclaration => const Decoration(color: '#E0E2E4');
+  Decoration get method => const Decoration(color: '#678CB1');
+  Decoration get methodDeclaration => const Decoration(color: '#E8E2B7');
+  Decoration get multiLineComment => const Decoration(color: '#7D8C93');
+  Decoration get number => const Decoration(color: '#FFCD22');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#E8E2B7');
+  Decoration get parameterVariable => const Decoration(color: '#E0E2E4');
+  Decoration get searchResultIndication => const Decoration(color: '#616161');
+  Decoration get selectionBackground => const Decoration(color: '#804000');
+  Decoration get selectionForeground => const Decoration(color: '#E0E2E4');
+  Decoration get singleLineComment => const Decoration(color: '#7D8C93');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
+  Decoration get staticField => const Decoration(color: '#678CB1');
+  Decoration get staticFinalField => const Decoration(color: '#E0E2E4');
+  Decoration get staticMethod => const Decoration(color: '#E0E2E4');
+  Decoration get string => const Decoration(color: '#EC7600');
+  Decoration get typeArgument => const Decoration(color: '#E0E2E4');
+  Decoration get typeParameter => const Decoration(color: '#E0E2E4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#616161');
+}
+
+/// Pastel theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/pastel.xml.
+/// Author: Ian Kabeary.
+class PastelTheme extends Theme {
+  const PastelTheme();
+
+  String get name => 'Pastel';
+
+  Decoration get abstractMethod => const Decoration(color: '#E0E2E4');
+  Decoration get annotation => const Decoration(color: '#A082BD');
+  Decoration get background => const Decoration(color: '#1f2223');
+  Decoration get bracket => const Decoration(color: '#95bed8');
+  Decoration get className => const Decoration(color: '#678CB1');
+  Decoration get commentTaskTag => const Decoration(color: '#a57b61');
+  Decoration get constant => const Decoration(color: '#A082BD');
+  Decoration get currentLine => const Decoration(color: '#2F393C');
+  Decoration get deletionIndication => const Decoration(color: '#E0E2E4');
+  Decoration get deprecatedMember => const Decoration(color: '#E0E2E4');
+  Decoration get dynamicType => const Decoration(color: '#E0E2E4');
+  Decoration get enumName => const Decoration(color: '#E0E2E4');
+  Decoration get field => const Decoration(color: '#678CB1');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#616161');
+  Decoration get findScope => const Decoration(color: '#E0E2E4');
+  Decoration get foreground => const Decoration(color: '#E0E2E4');
+  Decoration get inheritedMethod => const Decoration(color: '#E0E2E4');
+  Decoration get interface => const Decoration(color: '#678CB1');
+  Decoration get javadoc => const Decoration(color: '#7D8C93');
+  Decoration get javadocKeyword => const Decoration(color: '#A082BD');
+  Decoration get javadocLink => const Decoration(color: '#678CB1');
+  Decoration get javadocTag => const Decoration(color: '#E0E2E4');
+  Decoration get keyword => const Decoration(color: '#a57b61');
+  Decoration get lineNumber => const Decoration(color: '#81969A');
+  Decoration get localVariable => const Decoration(color: '#E0E2E4');
+  Decoration get localVariableDeclaration => const Decoration(color: '#E0E2E4');
+  Decoration get method => const Decoration(color: '#678CB1');
+  Decoration get methodDeclaration => const Decoration(color: '#95bed8');
+  Decoration get multiLineComment => const Decoration(color: '#7D8C93');
+  Decoration get number => const Decoration(color: '#c78d9b');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#E8E2B7');
+  Decoration get parameterVariable => const Decoration(color: '#E0E2E4');
+  Decoration get searchResultIndication => const Decoration(color: '#616161');
+  Decoration get selectionBackground => const Decoration(color: '#95bed8');
+  Decoration get selectionForeground => const Decoration(color: '#E0E2E4');
+  Decoration get singleLineComment => const Decoration(color: '#7D8C93');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
+  Decoration get staticField => const Decoration(color: '#678CB1');
+  Decoration get staticFinalField => const Decoration(color: '#E0E2E4');
+  Decoration get staticMethod => const Decoration(color: '#E0E2E4');
+  Decoration get string => const Decoration(color: '#c78d9b');
+  Decoration get typeArgument => const Decoration(color: '#E0E2E4');
+  Decoration get typeParameter => const Decoration(color: '#E0E2E4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#616161');
+}
+
+/// RecognEyes theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/recogneyes.xml.
+/// Author: Dan.
+class RecognEyesTheme extends Theme {
+  const RecognEyesTheme();
+
+  String get name => 'RecognEyes';
+
+  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
+  Decoration get annotation => const Decoration(color: '#FFFFFF');
+  Decoration get background => const Decoration(color: '#101020');
+  Decoration get bracket => const Decoration(color: '#D0D0D0');
+  Decoration get className => const Decoration(color: '#FF8080');
+  Decoration get commentTaskTag => const Decoration(color: '#00FF00');
+  Decoration get constant => const Decoration(color: '#FFFF00');
+  Decoration get currentLine => const Decoration(color: '#202030');
+  Decoration get deletionIndication => const Decoration(color: '#FFFFFF');
+  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
+  Decoration get dynamicType => const Decoration(color: '#79ABFF');
+  Decoration get enumName => const Decoration(color: '#FFFFFF');
+  Decoration get field => const Decoration(color: '#BED6FF');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#606080');
+  Decoration get findScope => const Decoration(color: '#FFFFFF');
+  Decoration get foreground => const Decoration(color: '#D0D0D0');
+  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
+  Decoration get interface => const Decoration(color: '#D197D9');
+  Decoration get javadoc => const Decoration(color: '#CCDF32');
+  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
+  Decoration get javadocLink => const Decoration(color: '#D9E577');
+  Decoration get javadocTag => const Decoration(color: '#D9E577');
+  Decoration get keyword => const Decoration(color: '#00D0D0');
+  Decoration get lineNumber => const Decoration(color: '#2B91AF');
+  Decoration get localVariable => const Decoration(color: '#79ABFF');
+  Decoration get localVariableDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get method => const Decoration(color: '#D0D0D0');
+  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
+  Decoration get multiLineComment => const Decoration(color: '#00E000');
+  Decoration get number => const Decoration(color: '#FFFF00');
+  Decoration get occurrenceIndication => const Decoration(color: '#000000');
+  Decoration get operator => const Decoration(color: '#D0D0D0');
+  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
+  Decoration get searchResultIndication => const Decoration(color: '#006080');
+  Decoration get selectionBackground => const Decoration(color: '#0000FF');
+  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
+  Decoration get singleLineComment => const Decoration(color: '#00E000');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
+  Decoration get staticField => const Decoration(color: '#EFC090');
+  Decoration get staticFinalField => const Decoration(color: '#EFC090');
+  Decoration get staticMethod => const Decoration(color: '#BED6FF');
+  Decoration get string => const Decoration(color: '#DC78DC');
+  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
+  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
+}
+
+/// Retta theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/retta.xml.
+/// Author: Eric.
+class RettaTheme extends Theme {
+  const RettaTheme();
+
+  String get name => 'Retta';
+
+  Decoration get abstractMethod => const Decoration(color: '#A4B0C0');
+  Decoration get annotation => const Decoration(color: '#FFFFFF');
+  Decoration get background => const Decoration(color: '#000000');
+  Decoration get bracket => const Decoration(color: '#F8E1AA');
+  Decoration get className => const Decoration(color: '#DE6546', bold: true);
+  Decoration get commentTaskTag => const Decoration(color: '#83786E');
+  Decoration get constant => const Decoration(color: '#EFC090');
+  Decoration get currentLine => const Decoration(color: '#2A2A2A');
+  Decoration get deletionIndication => const Decoration(color: '#DE6546');
+  Decoration get deprecatedMember => const Decoration(color: '#DE6546');
+  Decoration get dynamicType => const Decoration(color: '#F8E1AA');
+  Decoration get enumName => const Decoration(color: '#527D5D', bold: true);
+  Decoration get field => const Decoration(color: '#DE6546');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#395EB1');
+  Decoration get findScope => const Decoration(color: '#FFFF00');
+  Decoration get foreground => const Decoration(color: '#F8E1AA');
+  Decoration get inheritedMethod => const Decoration(color: '#A4B0C0');
+  Decoration get interface => const Decoration(color: '#527D5D', bold: true);
+  Decoration get javadoc => const Decoration(color: '#83786E');
+  Decoration get javadocKeyword => const Decoration(color: '#83786E');
+  Decoration get javadocLink => const Decoration(color: '#83786E');
+  Decoration get javadocTag => const Decoration(color: '#A19387');
+  Decoration get keyword => const Decoration(color: '#E79E3C', bold: true);
+  Decoration get lineNumber => const Decoration(color: '#C97138');
+  Decoration get localVariable => const Decoration(color: '#F8E1AA');
+  Decoration get localVariableDeclaration => const Decoration(color: '#F8E1AA');
+  Decoration get method => const Decoration(color: '#A4B0C0');
+  Decoration get methodDeclaration => const Decoration(color: '#A4B0C0');
+  Decoration get multiLineComment => const Decoration(color: '#83786E');
+  Decoration get number => const Decoration(color: '#D6C248');
+  Decoration get occurrenceIndication => const Decoration(color: '#5E5C56');
+  Decoration get operator => const Decoration(color: '#D6C248');
+  Decoration get parameterVariable => const Decoration(color: '#A4B0C0');
+  Decoration get searchResultIndication => const Decoration(color: '#395EB1');
+  Decoration get selectionBackground => const Decoration(color: '#527D5D');
+  Decoration get selectionForeground => const Decoration(color: '#F8E1AA');
+  Decoration get singleLineComment => const Decoration(color: '#83786E');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FF00FF');
+  Decoration get staticField => const Decoration(color: '#F8E1A3');
+  Decoration get staticFinalField => const Decoration(color: '#F8E1A3');
+  Decoration get staticMethod => const Decoration(color: '#A4B0C0');
+  Decoration get string => const Decoration(color: '#D6C248');
+  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
+  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#527D5D');
+}
+
+/// Roboticket theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/roboticket.xml.
+/// Author: Robopuff.
+class RoboticketTheme extends Theme {
+  const RoboticketTheme();
+
+  String get name => 'Roboticket';
+
+  Decoration get abstractMethod => const Decoration(color: '#2C577C');
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#F5F5F5');
+  Decoration get bracket => const Decoration(color: '#B05A65');
+  Decoration get className => const Decoration(color: '#AB2525');
+  Decoration get commentTaskTag => const Decoration(color: '#295F94');
+  Decoration get constant => const Decoration(color: '#0A0B0C');
+  Decoration get currentLine => const Decoration(color: '#E0E0FF');
+  Decoration get deletionIndication => const Decoration(color: '#9B5656');
+  Decoration get deprecatedMember => const Decoration(color: '#AB2525');
+  Decoration get enumName => const Decoration(color: '#885D3B');
+  Decoration get field => const Decoration(color: '#566874');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#FFDF99');
+  Decoration get findScope => const Decoration(color: '#BDD8F2');
+  Decoration get foreground => const Decoration(color: '#585858');
+  Decoration get inheritedMethod => const Decoration(color: '#2C577C');
+  Decoration get interface => const Decoration(color: '#9B5656');
+  Decoration get javadoc => const Decoration(color: '#AD95AF');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#AD95AF');
+  Decoration get javadocTag => const Decoration(color: '#566874');
+  Decoration get keyword => const Decoration(color: '#295F94');
+  Decoration get lineNumber => const Decoration(color: '#AFBFCF');
+  Decoration get localVariable => const Decoration(color: '#55aa55');
+  Decoration get localVariableDeclaration => const Decoration(color: '#B05A65');
+  Decoration get method => const Decoration(color: '#BC5A65', bold: true);
+  Decoration get methodDeclaration => const Decoration(color: '#B05A65');
+  Decoration get multiLineComment => const Decoration(color: '#AD95AF');
+  Decoration get number => const Decoration(color: '#AF0F91');
+  Decoration get occurrenceIndication => const Decoration(color: '#FFCFBB');
+  Decoration get operator => const Decoration(color: '#000000');
+  Decoration get parameterVariable => const Decoration(color: '#55aa55');
+  Decoration get searchResultIndication => const Decoration(color: '#FFDF99');
+  Decoration get selectionBackground => const Decoration(color: '#BDD8F2');
+  Decoration get selectionForeground => const Decoration(color: '#484848');
+  Decoration get singleLineComment => const Decoration(color: '#AD95AF');
+  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
+  Decoration get staticField => const Decoration(color: '#885D3B');
+  Decoration get staticFinalField => const Decoration(color: '#885D3B');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#317ECC');
+  Decoration get typeArgument => const Decoration(color: '#885D3B');
+  Decoration get typeParameter => const Decoration(color: '#885D3B');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#FFCFBB');
+}
+
+/// Schuss theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/schuss.xml.
+/// Author: Vasil Stoychev.
+class SchussTheme extends Theme {
+  const SchussTheme();
+
+  String get name => 'Schuss';
+
+  Decoration get abstractMethod => const Decoration(color: '#2c577c');
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#FFFFFF');
+  Decoration get bracket => const Decoration(color: '#000f6a');
+  Decoration get className => const Decoration(color: '#ca3349');
+  Decoration get commentTaskTag => const Decoration(color: '#d7d3cc');
+  Decoration get constant => const Decoration(color: '#ae25ab');
+  Decoration get currentLine => const Decoration(color: '#fff7cd');
+  Decoration get deletionIndication => const Decoration(color: '#9b5656');
+  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
+  Decoration get enumName => const Decoration(color: '#135a20');
+  Decoration get field => const Decoration(color: '#566874');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#CC6633');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#430400');
+  Decoration get inheritedMethod => const Decoration(color: '#2c577c');
+  Decoration get interface => const Decoration(color: '#ca3349');
+  Decoration get javadoc => const Decoration(color: '#05314d');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#05314d');
+  Decoration get javadocTag => const Decoration(color: '#05314d');
+  Decoration get keyword => const Decoration(color: '#606060');
+  Decoration get lineNumber => const Decoration(color: '#999999');
+  Decoration get localVariable => const Decoration(color: '#2b6488');
+  Decoration get localVariableDeclaration => const Decoration(color: '#ca3349');
+  Decoration get method => const Decoration(color: '#797a8a');
+  Decoration get methodDeclaration => const Decoration(color: '#4f6d8f');
+  Decoration get multiLineComment => const Decoration(color: '#d5d9e5');
+  Decoration get number => const Decoration(color: '#d0321f');
+  Decoration get occurrenceIndication => const Decoration(color: '#CC6633');
+  Decoration get operator => const Decoration(color: '#5f97a9');
+  Decoration get parameterVariable => const Decoration(color: '#5c8198');
+  Decoration get searchResultIndication => const Decoration(color: '#CC6633');
+  Decoration get selectionBackground => const Decoration(color: '#f4fdff');
+  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
+  Decoration get singleLineComment => const Decoration(color: '#d7d3cc');
+  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
+  Decoration get staticField => const Decoration(color: '#464646');
+  Decoration get staticFinalField => const Decoration(color: '#464646');
+  Decoration get staticMethod => const Decoration(color: '#797a8a');
+  Decoration get string => const Decoration(color: '#585545');
+  Decoration get typeArgument => const Decoration(color: '#d07fcd');
+  Decoration get typeParameter => const Decoration(color: '#d07fcd');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#CC6633');
+}
+
+/// Sublime Text 2 theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/sublime-text-2.xml.
+/// Author: Filip Minev.
+class Sublime_Text_2Theme extends Theme {
+  const Sublime_Text_2Theme();
+
+  String get name => 'Sublime Text 2';
+
+  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
+  Decoration get annotation => const Decoration(color: '#FFFFFF');
+  Decoration get background => const Decoration(color: '#272822');
+  Decoration get bracket => const Decoration(color: '#F9FAF4');
+  Decoration get className => const Decoration(color: '#52E3F6');
+  Decoration get commentTaskTag => const Decoration(color: '#FFFFFF');
+  Decoration get currentLine => const Decoration(color: '#5B5A4E');
+  Decoration get deletionIndication => const Decoration(color: '#FF0000');
+  Decoration get deprecatedMember => const Decoration(color: '#FF0000');
+  Decoration get dynamicType => const Decoration(color: '#CFBFAD');
+  Decoration get field => const Decoration(color: '#CFBFAD');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get findScope => const Decoration(color: '#000000');
+  Decoration get foreground => const Decoration(color: '#CFBFAD');
+  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
+  Decoration get interface => const Decoration(color: '#52E3F6');
+  Decoration get javadoc => const Decoration(color: '#FFFFFF');
+  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
+  Decoration get javadocLink => const Decoration(color: '#CFBFAD');
+  Decoration get javadocTag => const Decoration(color: '#CFBFAD');
+  Decoration get keyword => const Decoration(color: '#FF007F');
+  Decoration get lineNumber => const Decoration(color: '#999999');
+  Decoration get localVariable => const Decoration(color: '#CFBFAD');
+  Decoration get localVariableDeclaration => const Decoration(color: '#CFBFAD');
+  Decoration get method => const Decoration(color: '#A7EC21');
+  Decoration get methodDeclaration => const Decoration(color: '#A7EC21');
+  Decoration get multiLineComment => const Decoration(color: '#FFFFFF');
+  Decoration get number => const Decoration(color: '#C48CFF');
+  Decoration get occurrenceIndication => const Decoration(color: '#000000');
+  Decoration get operator => const Decoration(color: '#FF007F');
+  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
+  Decoration get searchResultIndication => const Decoration(color: '#D8D8D8');
+  Decoration get selectionBackground => const Decoration(color: '#CC9900');
+  Decoration get selectionForeground => const Decoration(color: '#404040');
+  Decoration get singleLineComment => const Decoration(color: '#FFFFFF');
+  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
+  Decoration get staticField => const Decoration(color: '#CFBFAD');
+  Decoration get staticFinalField => const Decoration(color: '#CFBFAD');
+  Decoration get staticMethod => const Decoration(color: '#A7EC21');
+  Decoration get string => const Decoration(color: '#ECE47E');
+  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
+  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
+}
+
+/// Sunburst theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/sunburst.xml.
+/// Author: Viorel Craescu.
+class SunburstTheme extends Theme {
+  const SunburstTheme();
+
+  String get name => 'Sunburst';
+
+  Decoration get abstractMethod => const Decoration(color: '#F9F9F9');
+  Decoration get annotation => const Decoration(color: '#A020F0');
+  Decoration get background => const Decoration(color: '#000000');
+  Decoration get bracket => const Decoration(color: '#F9F9F9');
+  Decoration get className => const Decoration(color: '#F9F9F9');
+  Decoration get commentTaskTag => const Decoration(color: '#A8A8A8');
+  Decoration get constant => const Decoration(color: '#3D9AD6');
+  Decoration get currentLine => const Decoration(color: '#2F2F2F');
+  Decoration get deletionIndication => const Decoration(color: '#D25252');
+  Decoration get deprecatedMember => const Decoration(color: '#F9F9F9');
+  Decoration get dynamicType => const Decoration(color: '#4B9CE9');
+  Decoration get enumName => const Decoration(color: '#7FB347');
+  Decoration get field => const Decoration(color: '#4B9CE9');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#5A5A5A');
+  Decoration get findScope => const Decoration(color: '#DDF0FF');
+  Decoration get foreground => const Decoration(color: '#F9F9F9');
+  Decoration get inheritedMethod => const Decoration(color: '#F9F9F9');
+  Decoration get interface => const Decoration(color: '#F9F9F9');
+  Decoration get javadoc => const Decoration(color: '#A8A8A8');
+  Decoration get javadocKeyword => const Decoration(color: '#EA9C77');
+  Decoration get javadocLink => const Decoration(color: '#548FA0');
+  Decoration get javadocTag => const Decoration(color: '#A8A8A8');
+  Decoration get keyword => const Decoration(color: '#EA9C77');
+  Decoration get lineNumber => const Decoration(color: '#F9F9F9');
+  Decoration get localVariable => const Decoration(color: '#4B9CE9');
+  Decoration get localVariableDeclaration => const Decoration(color: '#4B9CE9');
+  Decoration get method => const Decoration(color: '#F9F9F9');
+  Decoration get methodDeclaration => const Decoration(color: '#F9F9F9');
+  Decoration get multiLineComment => const Decoration(color: '#A8A8A8');
+  Decoration get number => const Decoration(color: '#F9F9F9');
+  Decoration get occurrenceIndication => const Decoration(color: '#5A5A5A');
+  Decoration get operator => const Decoration(color: '#F9F9F9');
+  Decoration get parameterVariable => const Decoration(color: '#4B9CE9');
+  Decoration get searchResultIndication => const Decoration(color: '#5A5A5A');
+  Decoration get selectionBackground => const Decoration(color: '#DDF0FF');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get singleLineComment => const Decoration(color: '#A8A8A8');
+  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
+  Decoration get staticField => const Decoration(color: '#4B9CE9');
+  Decoration get staticFinalField => const Decoration(color: '#4B9CE9');
+  Decoration get staticMethod => const Decoration(color: '#F9F9F9');
+  Decoration get string => const Decoration(color: '#76BA53');
+  Decoration get typeArgument => const Decoration(color: '#4B9CE9');
+  Decoration get typeParameter => const Decoration(color: '#4B9CE9');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#5A5A5A');
+}
+
+/// Tango theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/tango.xml.
+/// Author: Roger Dudler.
+class TangoTheme extends Theme {
+  const TangoTheme();
+
+  String get name => 'Tango';
+
+  Decoration get abstractMethod => const Decoration(color: '#2c577c');
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#FFFFFF');
+  Decoration get bracket => const Decoration(color: '#444444');
+  Decoration get className => const Decoration(color: '#37550d');
+  Decoration get commentTaskTag => const Decoration(color: '#17608f');
+  Decoration get currentLine => const Decoration(color: '#EEEEEE');
+  Decoration get deletionIndication => const Decoration(color: '#9b5656');
+  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
+  Decoration get dynamicType => const Decoration(color: '#5c8198');
+  Decoration get enumName => const Decoration(color: '#885d3b');
+  Decoration get field => const Decoration(color: '#566874');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#EFEFEF');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#000000');
+  Decoration get inheritedMethod => const Decoration(color: '#2c577c');
+  Decoration get interface => const Decoration(color: '#9b5656');
+  Decoration get javadoc => const Decoration(color: '#05314d');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#05314d');
+  Decoration get javadocTag => const Decoration(color: '#05314d');
+  Decoration get keyword => const Decoration(color: '#688046');
+  Decoration get lineNumber => const Decoration(color: '#999999');
+  Decoration get localVariable => const Decoration(color: '#5c8198');
+  Decoration get localVariableDeclaration => const Decoration(color: '#5c8198');
+  Decoration get method => const Decoration(color: '#444444');
+  Decoration get methodDeclaration => const Decoration(color: '#222222');
+  Decoration get multiLineComment => const Decoration(color: '#17608f');
+  Decoration get number => const Decoration(color: '#801f91');
+  Decoration get occurrenceIndication => const Decoration(color: '#EFEFEF');
+  Decoration get operator => const Decoration(color: '#000000');
+  Decoration get parameterVariable => const Decoration(color: '#5c8198');
+  Decoration get searchResultIndication => const Decoration(color: '#EFEFEF');
+  Decoration get selectionBackground => const Decoration(color: '#EEEEEE');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get singleLineComment => const Decoration(color: '#17608f');
+  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
+  Decoration get staticField => const Decoration(color: '#885d3b');
+  Decoration get staticFinalField => const Decoration(color: '#885d3b');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#92679a');
+  Decoration get typeArgument => const Decoration(color: '#885d3b');
+  Decoration get typeParameter => const Decoration(color: '#885d3b');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#EFEFEF');
+}
+
+/// Vibrant Ink theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/vibrantink.xml.
+/// Author: indiehead.
+class Vibrant_InkTheme extends Theme {
+  const Vibrant_InkTheme();
+
+  String get name => 'Vibrant Ink';
+
+  Decoration get abstractMethod => const Decoration(color: '#F1C436');
+  Decoration get background => const Decoration(color: '#191919');
+  Decoration get bracket => const Decoration(color: '#FFFFFF');
+  Decoration get className => const Decoration(color: '#9CF828');
+  Decoration get commentTaskTag => const Decoration(color: '#800080');
+  Decoration get currentLine => const Decoration(color: '#222220');
+  Decoration get deletionIndication => const Decoration(color: '#FF0000');
+  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
+  Decoration get dynamicType => const Decoration(color: '#3C758D');
+  Decoration get enumName => const Decoration(color: '#408000');
+  Decoration get field => const Decoration(color: '#357A8F');
+  Decoration get findScope => const Decoration(color: '#191919');
+  Decoration get foreground => const Decoration(color: '#FFFFFF');
+  Decoration get inheritedMethod => const Decoration(color: '#E3B735');
+  Decoration get interface => const Decoration(color: '#87F025');
+  Decoration get javadoc => const Decoration(color: '#8C3FC8');
+  Decoration get javadocKeyword => const Decoration(color: '#800080');
+  Decoration get javadocLink => const Decoration(color: '#814582');
+  Decoration get javadocTag => const Decoration(color: '#800080');
+  Decoration get keyword => const Decoration(color: '#EC691E');
+  Decoration get lineNumber => const Decoration(color: '#666666');
+  Decoration get localVariable => const Decoration(color: '#3C758D');
+  Decoration get localVariableDeclaration => const Decoration(color: '#357A92');
+  Decoration get method => const Decoration(color: '#F7C527');
+  Decoration get methodDeclaration => const Decoration(color: '#F1C438');
+  Decoration get multiLineComment => const Decoration(color: '#8C3FC8');
+  Decoration get number => const Decoration(color: '#477488');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#FFFFFF');
+  Decoration get parameterVariable => const Decoration(color: '#408000');
+  Decoration get selectionBackground => const Decoration(color: '#414C3B');
+  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
+  Decoration get singleLineComment => const Decoration(color: '#8146A2');
+  Decoration get staticField => const Decoration(color: '#FFFFFF');
+  Decoration get staticFinalField => const Decoration(color: '#80FF00');
+  Decoration get staticMethod => const Decoration(color: '#FFFFFF');
+  Decoration get string => const Decoration(color: '#477488');
+  Decoration get typeArgument => const Decoration(color: '#D9B0AC');
+  Decoration get typeParameter => const Decoration(color: '#CDB1AD');
+}
+
+/// Wombat theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/wombat.xml.
+/// Author: Lars H. Nielsen.
+class WombatTheme extends Theme {
+  const WombatTheme();
+
+  String get name => 'Wombat';
+
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#242424');
+  Decoration get bracket => const Decoration(color: '#f3f6ee');
+  Decoration get className => const Decoration(color: '#cae682');
+  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
+  Decoration get currentLine => const Decoration(color: '#656565');
+  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
+  Decoration get dynamicType => const Decoration(color: '#D4C4A9');
+  Decoration get field => const Decoration(color: '#cae682');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#3f3f6a');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#f6f3e8');
+  Decoration get interface => const Decoration(color: '#CAE682');
+  Decoration get javadoc => const Decoration(color: '#b3b5af');
+  Decoration get javadocKeyword => const Decoration(color: '#f08080');
+  Decoration get javadocLink => const Decoration(color: '#a7a7d1');
+  Decoration get javadocTag => const Decoration(color: '#a7a7d1');
+  Decoration get keyword => const Decoration(color: '#8ac6f2');
+  Decoration get lineNumber => const Decoration(color: '#656565');
+  Decoration get localVariable => const Decoration(color: '#D4C4A9');
+  Decoration get localVariableDeclaration => const Decoration(color: '#D4C4A9');
+  Decoration get method => const Decoration(color: '#f3f6ee');
+  Decoration get methodDeclaration => const Decoration(color: '#f3f6ee');
+  Decoration get multiLineComment => const Decoration(color: '#99968b');
+  Decoration get number => const Decoration(color: '#f08080');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#f3f6ee');
+  Decoration get searchResultIndication => const Decoration(color: '#464467');
+  Decoration get selectionBackground => const Decoration(color: '#898941');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get singleLineComment => const Decoration(color: '#99968b');
+  Decoration get sourceHoverBackground => const Decoration(color: '#a19879');
+  Decoration get staticField => const Decoration(color: '#93A2CC');
+  Decoration get staticFinalField => const Decoration(color: '#53dccd');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#95e454');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
+}
+
+/// Zenburn theme extracted from
+/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/zenburn.xml.
+/// Author: Janni Nurminen.
+class ZenburnTheme extends Theme {
+  const ZenburnTheme();
+
+  String get name => 'Zenburn';
+
+  Decoration get annotation => const Decoration(color: '#808080');
+  Decoration get background => const Decoration(color: '#404040');
+  Decoration get bracket => const Decoration(color: '#FFFFFF');
+  Decoration get className => const Decoration(color: '#CAE682');
+  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
+  Decoration get currentLine => const Decoration(color: '#505050');
+  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
+  Decoration get dynamicType => const Decoration(color: '#D4C4A9');
+  Decoration get field => const Decoration(color: '#B3B784');
+  Decoration get filteredSearchResultIndication => const Decoration(color: '#3F3F6A');
+  Decoration get findScope => const Decoration(color: '#BCADAD');
+  Decoration get foreground => const Decoration(color: '#F6F3E8');
+  Decoration get interface => const Decoration(color: '#CAE682');
+  Decoration get javadoc => const Decoration(color: '#B3B5AF');
+  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
+  Decoration get javadocLink => const Decoration(color: '#A893CC');
+  Decoration get javadocTag => const Decoration(color: '#9393CC');
+  Decoration get keyword => const Decoration(color: '#EFEFAF');
+  Decoration get lineNumber => const Decoration(color: '#C0C0C0');
+  Decoration get localVariable => const Decoration(color: '#D4C4A9');
+  Decoration get localVariableDeclaration => const Decoration(color: '#D4C4A9');
+  Decoration get method => const Decoration(color: '#DFBE95');
+  Decoration get methodDeclaration => const Decoration(color: '#DFBE95');
+  Decoration get multiLineComment => const Decoration(color: '#7F9F7F');
+  Decoration get number => const Decoration(color: '#8ACCCF');
+  Decoration get occurrenceIndication => const Decoration(color: '#616161');
+  Decoration get operator => const Decoration(color: '#F0EFD0');
+  Decoration get searchResultIndication => const Decoration(color: '#464467');
+  Decoration get selectionBackground => const Decoration(color: '#898941');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get singleLineComment => const Decoration(color: '#7F9F7F');
+  Decoration get sourceHoverBackground => const Decoration(color: '#A19879');
+  Decoration get staticField => const Decoration(color: '#93A2CC');
+  Decoration get staticFinalField => const Decoration(color: '#53DCCD');
+  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
+  Decoration get string => const Decoration(color: '#CC9393');
+  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
+}
+
+/// List of known themes. The default is the first theme.
+const List<Theme> THEMES = const <Theme> [
+    const Theme(),
+    const Black_PastelTheme(),
+    const DartboardTheme(),
+    const DebuggingTheme(),
+    const Dart_EditorTheme(),
+    const frontenddevTheme(),
+    const Gedit_Original_OblivionTheme(),
+    const HavenjarkTheme(),
+    const Hot_PinkTheme(),
+    const InkpotTheme(),
+    const minimalTheme(),
+    const MonokaiTheme(),
+    const MrTheme(),
+    const NightLion_Aptana_ThemeTheme(),
+    const Notepad___LikeTheme(),
+    const OblivionTheme(),
+    const ObsidianTheme(),
+    const PastelTheme(),
+    const RecognEyesTheme(),
+    const RettaTheme(),
+    const RoboticketTheme(),
+    const SchussTheme(),
+    const Sublime_Text_2Theme(),
+    const SunburstTheme(),
+    const TangoTheme(),
+    const Vibrant_InkTheme(),
+    const WombatTheme(),
+    const ZenburnTheme(),
+];
diff --git a/site/try/src/isolate_legacy.dart b/site/try/src/isolate_legacy.dart
new file mode 100644
index 0000000..17bc00c
--- /dev/null
+++ b/site/try/src/isolate_legacy.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 trydart.isolate_legacy;
+
+import 'dart:isolate';
+import 'dart:async';
+
+ReceivePort spawnFunction(void function(SendPort port)) {
+  ReceivePort port = new ReceivePort();
+  Isolate.spawn(function, port.sendPort);
+  return port;
+}
+
+ReceivePort spawnDomFunction(void function(SendPort port)) {
+  throw 'spawnDomFunction is no more';
+}
diff --git a/site/try/src/leap.dart b/site/try/src/leap.dart
new file mode 100644
index 0000000..3b6c08f
--- /dev/null
+++ b/site/try/src/leap.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library trydart.main;
+
+import 'dart:html' show
+    HttpRequest,
+    LinkElement,
+    query,
+    window;
+
+import 'dart:isolate' show
+    ReceivePort,
+    SendPort;
+
+import 'compilation.dart' show
+    compilerIsolate,
+    compilerPort;
+
+import 'editor.dart' show
+    onMutation;
+
+import 'isolate_legacy.dart' show
+    spawnDomFunction,
+    spawnFunction;
+
+import 'samples.dart' show
+    EXAMPLE_HELLO;
+
+import 'ui.dart' show
+    buildUI,
+    observer;
+
+int count = 0;
+
+const String HAS_NON_DOM_HTTP_REQUEST = 'spawnFunction supports HttpRequest';
+const String NO_NON_DOM_HTTP_REQUEST =
+    'spawnFunction does not support HttpRequest';
+
+checkHttpRequest(SendPort replyTo) {
+  try {
+    new HttpRequest();
+    replyTo.send(HAS_NON_DOM_HTTP_REQUEST);
+  } catch (e, trace) {
+    replyTo.send(NO_NON_DOM_HTTP_REQUEST);
+  }
+}
+
+main() {
+  if (window.localStorage['currentSource'] == null) {
+    window.localStorage['currentSource'] = EXAMPLE_HELLO;
+  }
+
+  buildUI();
+  spawnFunction(checkHttpRequest).first.then((reply) {
+    ReceivePort port;
+    if (reply == HAS_NON_DOM_HTTP_REQUEST) {
+      port = spawnFunction(compilerIsolate);
+    } else {
+      port = spawnDomFunction(compilerIsolate);
+    }
+    LinkElement link = query('link[rel="dart-sdk"]');
+    String sdk = link.href;
+    print('Using Dart SDK: $sdk');
+    int messageCount = 0;
+    SendPort sendPort;
+    port.listen((message) {
+      messageCount++;
+      switch (messageCount) {
+        case 1:
+          sendPort = message as SendPort;
+          sendPort.send([sdk, port.sendPort]);
+          break;
+        case 2:
+          // Acknowledged Receiving the SDK URI.
+          compilerPort = sendPort;
+          onMutation([], observer);
+          break;
+        default:
+          // TODO(ahe): Close [port]?
+          print('Unexpected message received: $message');
+          break;
+      }
+    });
+  });
+}
diff --git a/site/try/src/run.dart b/site/try/src/run.dart
new file mode 100644
index 0000000..a5cc88c
--- /dev/null
+++ b/site/try/src/run.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library trydart.run;
+
+import 'dart:html' show
+    Blob,
+    IFrameElement,
+    Url;
+
+makeOutputFrame(String scriptUrl) {
+  final String outputHtml = '''
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>JavaScript output</title>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+</head>
+<body>
+<script type="application/javascript" src="$outputHelper"></script>
+<script type="application/javascript" src="$scriptUrl"></script>
+</body>
+</html>
+''';
+
+  return new IFrameElement()
+      ..src = Url.createObjectUrl(new Blob([outputHtml], "text/html"))
+      ..style.width = '100%'
+      ..style.height = '0px'
+      ..seamless = false;
+}
+
+final String outputHelper =
+    Url.createObjectUrl(new Blob([OUTPUT_HELPER], 'application/javascript'));
+
+const String OUTPUT_HELPER = r'''
+function dartPrint(msg) {
+  window.parent.postMessage(String(msg), "*");
+}
+
+function dartMainRunner(main) {
+  main();
+}
+
+window.onerror = function (message, url, lineNumber) {
+  window.parent.postMessage(
+      ["error", {message: message, url: url, lineNumber: lineNumber}], "*");
+};
+
+(function () {
+
+function postScrollHeight() {
+  window.parent.postMessage(["scrollHeight", document.documentElement.scrollHeight], "*");
+}
+
+var observer = new (window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver)(function(mutations) {
+  postScrollHeight()
+  window.setTimeout(postScrollHeight, 500);
+});
+
+observer.observe(
+    document.body,
+    { attributes: true,
+      childList: true,
+      characterData: true,
+      subtree: true });
+})();
+''';
diff --git a/site/try/src/samples.dart b/site/try/src/samples.dart
new file mode 100644
index 0000000..f2807c6
--- /dev/null
+++ b/site/try/src/samples.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library trydart.samples;
+
+const String EXAMPLE_HELLO = r'''
+// Go ahead and modify this example.
+
+var greeting = "Hello, World!";
+
+// Prints a greeting.
+void main() {
+  // The [print] function displays a message in the "Console" box.
+  // Try modifying the greeting above and watch the "Console" box change.
+  print(greeting);
+}
+''';
+
+const String EXAMPLE_HELLO_HTML = r'''
+// Go ahead and modify this example.
+
+import "dart:html";
+
+var greeting = "Hello, World!";
+
+// Displays a greeting.
+void main() {
+  // This example uses HTML to display the greeting and it will appear
+  // in a nested HTML frame (an iframe).
+  document.body.append(new HeadingElement.h1()..appendText(greeting));
+}
+''';
+
+const String EXAMPLE_FIBONACCI = r'''
+// Go ahead and modify this example.
+
+// Computes the nth Fibonacci number.
+int fibonacci(int n) {
+  if (n < 2) return n;
+  return fibonacci(n - 1) + fibonacci(n - 2);
+}
+
+// Prints a Fibonacci number.
+void main() {
+  int i = 20;
+  String message = "fibonacci($i) = ${fibonacci(i)}";
+  // Print the result in the "Console" box.
+  print(message);
+}
+''';
+
+const String EXAMPLE_FIBONACCI_HTML = r'''
+// Go ahead and modify this example.
+
+import "dart:html";
+
+// Computes the nth Fibonacci number.
+int fibonacci(int n) {
+  if (n < 2) return n;
+  return fibonacci(n - 1) + fibonacci(n - 2);
+}
+
+// Displays a Fibonacci number.
+void main() {
+  int i = 20;
+  String message = "fibonacci($i) = ${fibonacci(i)}";
+
+  // This example uses HTML to display the result and it will appear
+  // in a nested HTML frame (an iframe).
+  document.body.append(new HeadingElement.h1()..appendText(message));
+}
+''';
+
+// Test that math.png is displayed correctly (centered without 3d border).
+// Test that slider works and changes size of sunflower.
+const String EXAMPLE_SUNFLOWER = '''
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 sunflower;
+
+import "dart:html";
+import "dart:math";
+
+const String ORANGE = "orange";
+const int SEED_RADIUS = 2;
+const int SCALE_FACTOR = 4;
+const num TAU = PI * 2;
+const int MAX_D = 300;
+const num centerX = MAX_D / 2;
+const num centerY = centerX;
+
+final InputElement slider = query("#slider");
+final Element notes = query("#notes");
+final num PHI = (sqrt(5) + 1) / 2;
+int seeds = 0;
+final CanvasRenderingContext2D context =
+  (query("#canvas") as CanvasElement).context2D;
+
+void main() {
+  document.head.append(new StyleElement()..appendText(STYLE));
+  document.body.innerHtml = BODY;
+  ImageElement img = document.querySelector("#math_png");
+  img.src = MATH_PNG;
+  slider.onChange.listen((e) => draw());
+  draw();
+}
+
+/// Draw the complete figure for the current number of seeds.
+void draw() {
+  seeds = int.parse(slider.value);
+  context.clearRect(0, 0, MAX_D, MAX_D);
+  for (var i = 0; i < seeds; i++) {
+    final num theta = i * TAU / PHI;
+    final num r = sqrt(i) * SCALE_FACTOR;
+    drawSeed(centerX + r * cos(theta), centerY - r * sin(theta));
+  }
+  notes.text = "\${seeds} seeds";
+}
+
+/// Draw a small circle representing a seed centered at (x,y).
+void drawSeed(num x, num y) {
+  context..beginPath()
+         ..lineWidth = 2
+         ..fillStyle = ORANGE
+         ..strokeStyle = ORANGE
+         ..arc(x, y, SEED_RADIUS, 0, TAU, false)
+         ..fill()
+         ..closePath()
+         ..stroke();
+}
+
+const String MATH_PNG =
+    "https://dart.googlecode.com/svn/trunk/dart/samples/sunflower/web/math.png";
+const String BODY = """
+    <h1>drfibonacci\'s Sunflower Spectacular</h1>
+
+    <p>A canvas 2D demo.</p>
+
+    <div id="container">
+      <canvas id="canvas" width="300" height="300" class="center"></canvas>
+      <form class="center">
+        <input id="slider" type="range" max="1000" value="500"/>
+      </form>
+      <br/>
+      <img id="math_png" width="350px" height="42px" class="center">
+    </div>
+
+    <footer>
+      <p id="summary"> </p>
+      <p id="notes"> </p>
+    </footer>
+""";
+
+const String STYLE = r"""
+body {
+  background-color: #F8F8F8;
+  font-family: \'Open Sans\', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.2em;
+  margin: 15px;
+}
+
+p {
+  color: #333;
+}
+
+#container {
+  width: 100%;
+  height: 400px;
+  position: relative;
+  border: 1px solid #ccc;
+  background-color: #fff;
+}
+
+#summary {
+  float: left;
+}
+
+#notes {
+  float: right;
+  width: 120px;
+  text-align: right;
+}
+
+.error {
+  font-style: italic;
+  color: red;
+}
+
+img {
+  border: 1px solid #ccc;
+  margin: auto;
+}
+
+.center {
+  display: block;
+  margin: 0px auto;
+  text-align: center;
+}
+""";
+''';
diff --git a/site/try/src/theme_default.dart b/site/try/src/theme_default.dart
new file mode 100644
index 0000000..c761ef6
--- /dev/null
+++ b/site/try/src/theme_default.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of trydart.themes;
+
+/// Default theme extracted from
+/// editor/tools/plugins/com.google.dart.tools.deploy/themes/default.xml
+class Theme {
+  static named(String name) {
+    if (name == null) return THEMES[0];
+    return THEMES.firstWhere(
+        (theme) => name == theme.name,
+        orElse: () => THEMES[0]);
+  }
+
+  const Theme();
+
+  String get name => 'Default';
+
+  Decoration get abstractMethod => const Decoration(color: '#000000');
+  Decoration get annotation => const Decoration(color: '#000000');
+  Decoration get background => const Decoration(color: '#ffffff');
+  Decoration get bracket => const Decoration(color: '#000000');
+  Decoration get builtin => const Decoration(color: '#7e0854', bold: true);
+  Decoration get className => const Decoration(color: '#000000');
+  Decoration get commentTaskTag => const Decoration(color: '#606060');
+  Decoration get constant => const Decoration(color: '#000000');
+  Decoration get currentLine => const Decoration(color: '#F0F0F0');
+  Decoration get deletionIndication => const Decoration(color: '#000000');
+  Decoration get deprecatedMember => const Decoration(color: '#000000');
+  Decoration get directive => const Decoration(color: '#7e0854', bold: true);
+  Decoration get dynamicType => const Decoration(color: '#000000');
+  Decoration get enumName => const Decoration(color: '#000000');
+  Decoration get field => const Decoration(color: '#0618bd');
+  Decoration get filteredSearchResultIndication =>
+      const Decoration(color: '#000000');
+  Decoration get findScope => const Decoration(color: '#000000');
+  Decoration get foreground => const Decoration(color: '#000000');
+  Decoration get getter => const Decoration(color: '#0618bd');
+  Decoration get inheritedMethod => const Decoration(color: '#000000');
+  Decoration get interface => const Decoration(color: '#000000');
+  Decoration get javadoc => const Decoration(color: '#4162bc');
+  Decoration get javadocKeyword => const Decoration(color: '#4162bc');
+  Decoration get javadocLink => const Decoration(color: '#4162bc');
+  Decoration get javadocTag => const Decoration(color: '#7f809e');
+  Decoration get keyword => const Decoration(color: '#7e0854', bold: true);
+  Decoration get keywordReturn =>
+      const Decoration(color: '#7e0854', bold: true);
+  Decoration get lineNumber => const Decoration(color: '#000000');
+  Decoration get localVariable => const Decoration(color: '#7f1cc9');
+  Decoration get localVariableDeclaration =>
+      const Decoration(color: '#7f1cc9');
+  Decoration get method => const Decoration(color: '#000000');
+  Decoration get methodDeclaration =>
+      const Decoration(color: '#0b5bd2', bold: true);
+  Decoration get multiLineComment => const Decoration(color: '#4162bc');
+  Decoration get multiLineString => const Decoration(color: '#2d24fb');
+  Decoration get number => const Decoration(color: '#0c6f0e');
+  Decoration get occurrenceIndication => const Decoration(color: '#e0e0e0');
+  Decoration get operator => const Decoration(color: '#000000');
+  Decoration get parameterVariable => const Decoration(color: '#87312e');
+  Decoration get searchResultIndication => const Decoration(color: '#D0D0D0');
+  Decoration get selectionBackground => const Decoration(color: '#b6d6fd');
+  Decoration get selectionForeground => const Decoration(color: '#000000');
+  Decoration get setter => const Decoration(color: '#0618bd');
+  Decoration get singleLineComment => const Decoration(color: '#417e60');
+  Decoration get sourceHoverBackground => const Decoration(color: '#fbfbc8');
+  Decoration get staticField => const Decoration(color: '#0618bd');
+  Decoration get staticFinalField => const Decoration(color: '#0618bd');
+  Decoration get staticMethod => const Decoration(color: '#000000');
+  Decoration get staticMethodDeclaration =>
+      const Decoration(color: '#404040', bold: true);
+  Decoration get string => const Decoration(color: '#2d24fb');
+  Decoration get typeArgument => const Decoration(color: '#033178');
+  Decoration get typeParameter => const Decoration(color: '#033178');
+  Decoration get writeOccurrenceIndication =>
+      const Decoration(color: '#e0e0e0');
+}
diff --git a/site/try/src/themes.dart b/site/try/src/themes.dart
new file mode 100644
index 0000000..464f23c
--- /dev/null
+++ b/site/try/src/themes.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.
+
+library trydart.themes;
+
+import 'decoration.dart';
+
+part 'theme_default.dart';
+
+part 'extracted_themes.dart';
diff --git a/site/try/src/ui.dart b/site/try/src/ui.dart
new file mode 100644
index 0000000..65d66201
--- /dev/null
+++ b/site/try/src/ui.dart
@@ -0,0 +1,419 @@
+// 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 trydart.ui;
+
+import 'dart:html';
+
+import 'dart:async' show
+    scheduleMicrotask;
+
+import 'cache.dart' show
+    onLoad,
+    updateCacheStatus;
+
+import 'editor.dart' show
+    onKeyUp,
+    onMutation;
+
+import 'run.dart' show
+    makeOutputFrame;
+
+import 'themes.dart' show
+    THEMES,
+    Theme;
+
+import 'samples.dart' show
+    EXAMPLE_FIBONACCI,
+    EXAMPLE_FIBONACCI_HTML,
+    EXAMPLE_HELLO,
+    EXAMPLE_HELLO_HTML,
+    EXAMPLE_SUNFLOWER;
+
+DivElement inputPre;
+PreElement outputDiv;
+DivElement hackDiv;
+IFrameElement outputFrame;
+MutationObserver observer;
+SpanElement cacheStatusElement;
+bool alwaysRunInWorker = window.localStorage['alwaysRunInWorker'] == 'true';
+bool verboseCompiler = window.localStorage['verboseCompiler'] == 'true';
+bool minified = window.localStorage['minified'] == 'true';
+bool onlyAnalyze = window.localStorage['onlyAnalyze'] == 'true';
+final String rawCodeFont = window.localStorage['codeFont'];
+String codeFont = rawCodeFont == null ? '' : rawCodeFont;
+String currentSample = window.localStorage['currentSample'];
+Theme currentTheme = Theme.named(window.localStorage['theme']);
+bool applyingSettings = false;
+
+buildButton(message, action) {
+  if (message is String) {
+    message = new Text(message);
+  }
+  return new ButtonElement()
+      ..onClick.listen(action)
+      ..append(message);
+}
+
+buildTab(message, id, action) {
+  if (message is String) {
+    message = new Text(message);
+  }
+
+  onClick(MouseEvent event) {
+    event.preventDefault();
+    Element e = event.target;
+    LIElement parent = e.parent;
+    parent.parent.query('li[class="active"]').classes.remove('active');
+    parent.classes.add('active');
+    action(event);
+  }
+
+  inspirationCallbacks[id] = action;
+
+  return new OptionElement()..append(message)..id = id;
+}
+
+Map<String, Function> inspirationCallbacks = new Map<String, Function>();
+
+void onInspirationChange(Event event) {
+  SelectElement select = event.target;
+  String id = select.queryAll('option')[select.selectedIndex].id;
+  Function action = inspirationCallbacks[id];
+  if (action != null) action(event);
+  outputFrame.style.display = 'none';
+}
+
+buildUI() {
+  window.localStorage['currentSample'] = '$currentSample';
+
+  var inspirationTabs = document.getElementById('inspiration');
+  var htmlGroup = new OptGroupElement()..label = 'HTML';
+  var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';
+  inspirationTabs.append(new OptionElement()..appendText('Pick an example'));
+  inspirationTabs.onChange.listen(onInspirationChange);
+  // inspirationTabs.classes.addAll(['nav', 'nav-tabs']);
+  inspirationTabs.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
+    inputPre
+        ..nodes.clear()
+        ..appendText(EXAMPLE_HELLO);
+  }));
+  inspirationTabs.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
+    inputPre
+        ..nodes.clear()
+        ..appendText(EXAMPLE_FIBONACCI);
+  }));
+  inspirationTabs.append(htmlGroup);
+  // TODO(ahe): Restore benchmarks.
+  // inspirationTabs.append(benchmarkGroup);
+
+  htmlGroup.append(
+      buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
+    inputPre
+        ..nodes.clear()
+        ..appendText(EXAMPLE_HELLO_HTML);
+  }));
+  htmlGroup.append(
+      buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
+    inputPre
+        ..nodes.clear()
+        ..appendText(EXAMPLE_FIBONACCI_HTML);
+  }));
+  htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
+    inputPre
+        ..nodes.clear()
+        ..appendText(EXAMPLE_SUNFLOWER);
+  }));
+
+  benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
+    inputPre.contentEditable = 'false';
+    LinkElement link = query('link[rel="benchmark-DeltaBlue"]');
+    String deltaBlueUri = link.href;
+    link = query('link[rel="benchmark-base"]');
+    String benchmarkBaseUri = link.href;
+    HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
+      HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
+        benchmarkBase = benchmarkBase.replaceFirst(
+            'part of benchmark_harness;', '// part of benchmark_harness;');
+        deltaBlue = deltaBlue.replaceFirst(
+            "import 'package:benchmark_harness/benchmark_harness.dart';",
+            benchmarkBase);
+        inputPre
+            ..nodes.clear()
+            ..appendText(deltaBlue)
+            ..contentEditable = 'true';
+      });
+    });
+  }));
+
+  benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
+    inputPre.contentEditable = 'false';
+    LinkElement link = query('link[rel="benchmark-Richards"]');
+    String richardsUri = link.href;
+    link = query('link[rel="benchmark-base"]');
+    String benchmarkBaseUri = link.href;
+    HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
+      HttpRequest.getString(richardsUri).then((String richards) {
+        benchmarkBase = benchmarkBase.replaceFirst(
+            'part of benchmark_harness;', '// part of benchmark_harness;');
+        richards = richards.replaceFirst(
+            "import 'package:benchmark_harness/benchmark_harness.dart';",
+            benchmarkBase);
+        inputPre
+            ..nodes.clear()
+            ..appendText(richards)
+            ..contentEditable = 'true';
+      });
+    });
+  }));
+
+  // TODO(ahe): Update currentSample.  Or try switching to a drop-down menu.
+  var active = inspirationTabs.query('[id="$currentSample"]');
+  if (active == null) {
+    // inspirationTabs.query('li').classes.add('active');
+  }
+
+  (inputPre = new DivElement())
+      ..classes.add('well')
+      ..style.backgroundColor = currentTheme.background.color
+      ..style.color = currentTheme.foreground.color
+      ..style.overflow = 'auto'
+      ..style.whiteSpace = 'pre'
+      ..style.font = codeFont
+      ..spellcheck = false;
+
+  inputPre.contentEditable = 'true';
+  inputPre.onKeyDown.listen(onKeyUp);
+
+  var inputWrapper = new DivElement()
+      ..append(inputPre)
+      ..style.position = 'relative';
+
+  var inputHeader = new DivElement()..appendText('Code');
+
+  inputHeader.style
+      ..right = '3px'
+      ..top = '0px'
+      ..position = 'absolute';
+  inputWrapper.append(inputHeader);
+
+  outputFrame =
+      makeOutputFrame(
+          Url.createObjectUrl(new Blob([''], 'application/javascript')));
+
+  outputDiv = new PreElement();
+  outputDiv.style
+      ..backgroundColor = currentTheme.background.color
+      ..color = currentTheme.foreground.color
+      ..overflow = 'auto'
+      ..padding = '1em'
+      ..minHeight = '10em'
+      ..whiteSpace = 'pre-wrap';
+
+  var outputWrapper = new DivElement()
+      ..append(outputDiv)
+      ..style.position = 'relative';
+
+  var consoleHeader = new DivElement()..appendText('Console');
+
+  consoleHeader.style
+      ..right = '3px'
+      ..top = '0px'
+      ..position = 'absolute';
+  outputWrapper.append(consoleHeader);
+
+  hackDiv = new DivElement();
+
+  var saveButton = new ButtonElement()
+      ..onClick.listen((_) {
+        var blobUrl =
+            Url.createObjectUrl(new Blob([inputPre.text], 'text/plain'));
+        var save = new AnchorElement(href: blobUrl);
+        save.target = '_blank';
+        save.download = 'untitled.dart';
+        save.dispatchEvent(new Event.eventType('Event', 'click'));
+      })
+      ..style.position = 'absolute'
+      ..style.right = '0px'
+      ..appendText('Save');
+
+  cacheStatusElement = document.getElementById('appcache-status');
+  updateCacheStatus();
+
+  // TODO(ahe): Switch to two column layout so the console is on the right.
+  var section = document.query('article[class="homepage"]>section');
+
+  DivElement tryColumn = document.getElementById('try-dart-column');
+  DivElement runColumn = document.getElementById('run-dart-column');
+
+  tryColumn.append(inputWrapper);
+  outputFrame.style.display = 'none';
+  runColumn.append(outputFrame);
+  runColumn.append(outputWrapper);
+  runColumn.append(hackDiv);
+
+  var settingsElement = document.getElementById('settings');
+  settingsElement.onClick.listen(openSettings);
+
+  window.onMessage.listen((MessageEvent event) {
+    if (event.data is List) {
+      List message = event.data;
+      if (message.length > 0) {
+        switch (message[0]) {
+        case 'error':
+          Map diagnostics = message[1];
+          String url = diagnostics['url'];
+          outputDiv.appendText('${diagnostics["message"]}\n');
+          return;
+        case 'scrollHeight':
+          int scrollHeight = message[1];
+          if (scrollHeight > 0) {
+            outputFrame.style.height = '${scrollHeight}px';
+          }
+          return;
+        }
+      }
+    }
+    outputDiv.appendText('${event.data}\n');
+  });
+
+  observer = new MutationObserver(onMutation)
+      ..observe(inputPre, childList: true, characterData: true, subtree: true);
+
+  scheduleMicrotask(() {
+    inputPre.appendText(window.localStorage['currentSource']);
+  });
+
+  // You cannot install event handlers on window.applicationCache
+  // until the window has loaded.  In dartium, that's later than this
+  // method is called.
+  window.onLoad.listen(onLoad);
+
+  // However, in dart2js, the window has already loaded, and onLoad is
+  // never called.
+  onLoad(null);
+}
+
+void openSettings(MouseEvent event) {
+  event.preventDefault();
+
+  var backdrop = new DivElement()..classes.add('modal-backdrop');
+  document.body.append(backdrop);
+
+  void updateCodeFont(Event e) {
+    TextInputElement target = e.target;
+    codeFont = target.value;
+    inputPre.style.font = codeFont;
+    backdrop.style.opacity = '0.0';
+  }
+
+  void updateTheme(Event e) {
+    var select = e.target;
+    String theme = select.queryAll('option')[select.selectedIndex].text;
+    window.localStorage['theme'] = theme;
+    currentTheme = Theme.named(theme);
+
+    inputPre.style
+        ..backgroundColor = currentTheme.background.color
+        ..color = currentTheme.foreground.color;
+
+    outputDiv.style
+        ..backgroundColor = currentTheme.background.color
+        ..color = currentTheme.foreground.color;
+
+    backdrop.style.opacity = '0.0';
+
+    applyingSettings = true;
+    onMutation([], observer);
+    applyingSettings = false;
+  }
+
+
+  var body = document.getElementById('settings-body');
+
+  body.nodes.clear();
+
+  var form = new FormElement();
+  var fieldSet = new FieldSetElement();
+  body.append(form);
+  form.append(fieldSet);
+
+  buildCheckBox(String text, bool defaultValue, void action(Event e)) {
+    var checkBox = new CheckboxInputElement()
+        // TODO(ahe): Used to be ..defaultChecked = defaultValue
+        ..checked = defaultValue
+        ..onChange.listen(action);
+    return new LabelElement()
+        ..classes.add('checkbox')
+        ..append(checkBox)
+        ..appendText(' $text');
+  }
+
+  bool isChecked(CheckboxInputElement checkBox) => checkBox.checked;
+
+  // TODO(ahe): Build abstraction for flags/options.
+  fieldSet.append(
+      buildCheckBox(
+          'Always run in Worker thread.', alwaysRunInWorker,
+          (Event e) { alwaysRunInWorker = isChecked(e.target); }));
+
+  fieldSet.append(
+      buildCheckBox(
+          'Verbose compiler output.', verboseCompiler,
+          (Event e) { verboseCompiler = isChecked(e.target); }));
+
+  fieldSet.append(
+      buildCheckBox(
+          'Generate compact (minified) JavaScript.', minified,
+          (Event e) { minified = isChecked(e.target); }));
+
+  fieldSet.append(
+      buildCheckBox(
+          'Only analyze program.', onlyAnalyze,
+          (Event e) { onlyAnalyze = isChecked(e.target); }));
+
+  fieldSet.append(new LabelElement()..appendText('Code font:'));
+  var textInput = new TextInputElement();
+  textInput.classes.add('input-block-level');
+  if (codeFont != null && codeFont != '') {
+    textInput.value = codeFont;
+  }
+  textInput.placeholder = 'Enter a size and font, for example, 11pt monospace';
+  textInput.onChange.listen(updateCodeFont);
+  fieldSet.append(textInput);
+
+  fieldSet.append(new LabelElement()..appendText('Theme:'));
+  var themeSelector = new SelectElement();
+  themeSelector.classes.add('input-block-level');
+  for (Theme theme in THEMES) {
+    OptionElement option = new OptionElement()..appendText(theme.name);
+    if (theme == currentTheme) option.selected = true;
+    themeSelector.append(option);
+  }
+  themeSelector.onChange.listen(updateTheme);
+  fieldSet.append(themeSelector);
+
+  var dialog = document.getElementById('settings-dialog');
+
+  dialog.style.display = 'block';
+  dialog.classes.add('in');
+
+  onSubmit(Event event) {
+    event.preventDefault();
+
+    window.localStorage['alwaysRunInWorker'] = '$alwaysRunInWorker';
+    window.localStorage['verboseCompiler'] = '$verboseCompiler';
+    window.localStorage['minified'] = '$minified';
+    window.localStorage['onlyAnalyze'] = '$onlyAnalyze';
+    window.localStorage['codeFont'] = '$codeFont';
+
+    dialog.style.display = 'none';
+    dialog.classes.remove('in');
+    backdrop.remove();
+  }
+  form.onSubmit.listen(onSubmit);
+
+  var doneButton = document.getElementById('settings-done');
+  doneButton.onClick.listen(onSubmit);
+}
diff --git a/site/try/testing.txt b/site/try/testing.txt
new file mode 100644
index 0000000..331148b
--- /dev/null
+++ b/site/try/testing.txt
@@ -0,0 +1,35 @@
+Things to test manually:
+
+1. Each sample compiles and run as expected.
+
+2. Check that "add to home screen" works on iOS:
+
+   - Check that "add to home screen" creates a new icon in Safari (Dart logo on
+     white background with rounded corners). The suggested name should be "Try
+     Dart!".
+
+   - Check that the app launches as a full screen app which must be killed
+     separately from Safari.
+
+   - Check that the splash screen shows (Dart logo on white background).
+
+   - Check that the initial view port displays the full page, but that it can
+     be zoomed.
+
+3. Check that "add to home screen" works on Chrome Mobile (Android):
+
+   - Check the menu item "add to home screen" is enabled in Chrome.
+
+   - Check that an icon (Dart logo with transparent background) is added to the
+     Android home screen. The suggested name should be "Try Dart!".
+
+   - Check that the app launches full screen and is separate from Chrome in the
+     task viewer. For now, expect that the icon in task manager is Chrome and
+     the name is just "web app".
+
+4. Check that the site has a nice screen shot on Google+.
+
+   - Validate using http://www.google.com/webmasters/tools/richsnippets
+
+   - Try sharing on Google+. The screen shot should appear before you actually
+     share, so you don't need to actually share.
diff --git a/site/try/try-dart-screenshot.png b/site/try/try-dart-screenshot.png
new file mode 100644
index 0000000..d1546de
--- /dev/null
+++ b/site/try/try-dart-screenshot.png
Binary files differ
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index 7c23629..43ff3a5 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -4,6 +4,8 @@
 
 [ $compiler == dartanalyzer ]
 
+LibTest/core/RegExp/firstMatch_A01_t01: Fail
+
 # invalid argument for constant constructor
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: fail
 
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 5c77349..464640f 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -72,7 +72,7 @@
 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_A01_t01: StaticWarning
 LibTest/isolate/SendPort/send_A02_t01: Fail
 LibTest/isolate/SendPort/send_A02_t04: Fail
 LibTest/isolate/SendPort/send_A02_t05: Fail
@@ -83,7 +83,6 @@
 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
 
@@ -130,7 +129,6 @@
 
 Language/07_Classes/10_Superinterfaces_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
 LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
-LibTest/async/Zone/operator_subscript_A01_t01: StaticWarning # co19-roll r672: Please triage this failure
 
 # co19 issue 656
 LibTest/typed_data/Float32x4/equal_A01_t01: Skip # co19 issue 656
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index c126519..0378dd2 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -10,36 +10,27 @@
 
 [ $runtime == vm || $runtime != vm ]
 # Tests that fail everywhere, including the analyzer.
-LibTest/core/RegExp/firstMatch_A01_t01: Fail, OK # Issue 635
-LibTest/core/Stopwatch/start_A01_t01: PASS, FAIL, OK # co19 issue 657
-LibTest/core/Stopwatch/start_A01_t02: PASS, FAIL, OK # co19 issue 657
-LibTest/core/Stopwatch/elapsedTicks_A01_t01: PASS, FAIL, OK # co19 issue 657
+
+LibTest/isolate/IsolateStream/contains_A02_t01: Fail # co19 issue 668
 
 [ $runtime == vm || $runtime == dartium || $compiler == dart2dart || $compiler == dart2js ]
-Language/12_Expressions/30_Identifier_Reference_A02_t01: fail, pass, ok # co19 issue 649
-
 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/collection/LinkedList/forEach_A02_t01: RuntimeError, OK # co19 issue 662
+LibTest/collection/LinkedList/forEach_A02_t01: RuntimeError, OK # co19 issue 662 (fixed in r673)
 
 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
-LibTest/core/Set/intersection_A02_t01: Fail, OK # Issue 659
+LibTest/core/Set/intersection_A02_t01: Fail, OK # Issue 659 (fixed in r675)
 
 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, OK # co19 issue 663
+LibTest/collection/HashSet/HashSet_class_A01_t01: RuntimeError, OK # co19 issue 663 (fixed in r675)
 LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: RuntimeError, OK # co19 issue 663
 LibTest/core/Set/IterableBase_A01_t01: RuntimeError, OK # co19 issue 663
 
-LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
-
-LibTest/collection/ListBase/ListBase_class_A01_t01: Skip, OK # co19 issue 661
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip, OK # co19 issue 661
-
 [ $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
@@ -48,40 +39,27 @@
 LibTest/math/cos_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_t03: FAIL, OK # co19 issue 389 (not fixed in r672)
 LibTest/core/double/ceil_A01_t04: FAIL, OK # co19 issue 389
 LibTest/core/double/floor_A01_t03: FAIL, OK # co19 issue 389
 LibTest/core/double/floor_A01_t04: FAIL, OK # co19 issue 389
 LibTest/core/double/round_A01_t02: FAIL, OK # co19 issue 389
 LibTest/core/double/round_A01_t04: FAIL, OK # co19 issue 389
 
+LibTest/isolate/SendPort/send_A02_t02: SKIP # co19 issue 493 (not fixed in r672)
+LibTest/isolate/SendPort/send_A02_t03: SKIP # co19 issue 495 (not fixed in r672)
+
+
+[ $runtime == dartium || $compiler == dart2js ]
 LibTest/async/Future/Future.delayed_A01_t02: Pass, Fail # Issue 15524
 
-LibTest/async/Stream/Stream.periodic_A01_t01: 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
-
-
 [ $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/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/sin_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
-LibTest/async/Timer/Timer_A02_t01: PASS, FAIL, OK # co19 issue 538
-LibTest/async/Timer/Timer.periodic_A01_t01: PASS, FAIL, OK # co19 issue 537
-LibTest/async/Timer/Timer.periodic_A02_t01: PASS, FAIL, OK # co19 issue 538
-
-LibTest/isolate/IsolateStream/contains_A02_t01: FAIL, OK # co19 issue 540
-
 
 [ $runtime == vm || $compiler == none || $compiler == dart2js ]
-LibTest/isolate/IsolateStream/any_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/any_A01_t01: Fail # Co19 issue 639 (Fixed in r674)
 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
@@ -118,6 +96,5 @@
 ### CHECKED MODE FAILURES ###
 
 [ ($runtime == vm || $runtime == dartium || $compiler == dart2js) && $checked]
-Language/13_Statements/09_Switch_A09_t01: PASS, FAIL, OK # co19 issue 633
 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
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index f42fb63..5240fac 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -18,7 +18,6 @@
 Language/12_Expressions/12_Instance_Creation/1_New_A04_t02: RuntimeError # co19-roll r607: Please triage this failure
 Language/12_Expressions/17_Getter_Invocation_A07_t02: Pass, RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Invocation/memberName_A01_t01: Pass, RuntimeError # co18-roll r607: Please triage this failure
-LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
@@ -45,7 +44,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_A02_t01: Fail # http://dartbug.com/5519
 Language/12_Expressions/01_Constants_A03_t01: Fail # Issue 13652
 
 LibTest/core/Match/operator_subscript_A01_t01: Fail # inherited from VM
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 92d3ba4..c3f701f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -99,6 +99,8 @@
 LibTest/isolate/ReceivePort/toSendPort_A01_t01: RuntimeError # Issue: 8920
 LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Skip # http://dartbug.com/12635
 LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Pass, Timeout # co19-roll r651: Please triage this failure
+LibTest/async/Stream/Stream.periodic_A01_t01: Fail, Pass # Issue 16106
+LibTest/async/Timer/Timer.periodic_A01_t01: Fail, Pass # Issue 16110
 
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
@@ -113,6 +115,7 @@
 Language/15_Types/1_Static_Types_A03_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/core/Map/Map_class_A01_t04: Slow, Pass
 LibTest/core/Uri/Uri_A06_t03: Slow, Pass
+Language/13_Statements/09_Switch_A09_t01: RuntimeError # Issue 16089
 
 [ $compiler == dart2js ]
 LibTest/core/int/operator_GT_A01_t01: RuntimeError, OK # co19 issue 200
@@ -532,6 +535,9 @@
 LibTest/typed_data/Uint8List/Uint8List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
 Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
 
+LibTest/collection/ListBase/ListBase_class_A01_t01: RuntimeError # Please triage this failure
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: RuntimeError # Please triage this failure
+
 [ $compiler == dart2js && $checked ]
 Language/12_Expressions/03_Numbers_A05_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/19_Conditional_A04_t03: fail # co19-roll r546: Please triage this failure
@@ -598,6 +604,14 @@
 LibTest/core/Stopwatch/start_A01_t03: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/typed_data/Int32x4/operator_OR_A01_t01: RuntimeError # co19-roll r672: Please triage this failure
+LibTest/core/Stopwatch/start_A01_t01: RuntimeError # Please triage this failure
+LibTest/core/Stopwatch/start_A01_t02: RuntimeError # Please triage this failure
+LibTest/core/Stopwatch/elapsedTicks_A01_t01: RuntimeError # Please triage this failure
+
+LibTest/async/Stream/Stream.periodic_A01_t01: RuntimeError # No Periodic timer
+LibTest/async/Stream/Stream.periodic_A03_t01: RuntimeError # No Periodic timer
+LibTest/async/Timer/Timer.periodic_A01_t01: RuntimeError # No Periodic timer
+LibTest/async/Timer/Timer.periodic_A02_t01: RuntimeError # No Periodic timer
 
 [ $compiler == dart2js && $runtime == d8 ]
 LibTest/core/Stopwatch/elapsedInMs_A01_t01: RuntimeError # co19-roll r672: Please triage this failure
@@ -607,7 +621,6 @@
 LibTest/core/Stopwatch/elapsed_A01_t01: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/core/Stopwatch/elapsed_A01_t02: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/core/Stopwatch/elapsed_A01_t03: RuntimeError # co19-roll r672: Please triage this failure
-LibTest/core/Stopwatch/start_A01_t03: RuntimeError # co19-roll r672: Please triage this failure
 LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # co19-roll r672: Please triage this failure
 
 [ $compiler == dart2js && $minified ]
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 1dabd9c..08c9e21 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -36,5 +36,4 @@
 LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError # co19-roll r667: Please triage this failure
 
 [ $compiler == none && $runtime == dartium && $checked ]
-Language/13_Statements/09_Switch_A09_t01: 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 9f1ca00..c02132b 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -29,43 +29,32 @@
 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/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
+LibTest/isolate/IsolateStream/any_A02_t01: fail # co19 issue 668
+LibTest/isolate/IsolateStream/contains_A02_t01: fail # co19 issue 668
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # VM triage, check spec.
 
+LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t03: Skip # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError # Dart issue 15617
-LibTest/isolate/Isolate/spawnUri_A02_t02: Timeout # co19-roll r672: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A02_t03: Timeout # co19-roll r672: Please triage this failure
+LibTest/isolate/Isolate/spawnUri_A02_t02: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A02_t03: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
 LibTest/isolate/Isolate/spawn_A02_t02: RuntimeError # Dart issue 15617
 
-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/equal_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/notEqual_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/greaterThan_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/greaterThanOrEqual_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/lessThan_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/lessThanOrEqual_A01_t01: Skip # co19 issue 656
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # Issue 12508
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
 
 [ $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
+LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # co19 issue 599
+LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # co19 issue 599
 
 [ $compiler == none && $runtime == vm && $checked ]
-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
-LibTest/async/Completer/complete_A02_t02: Pass # No AsyncError anymore. Issue 407 and 463
-LibTest/async/Future/catchError_A01_t01: Pass # No AsyncError anymore. Issue 407 and 463
-LibTest/async/Future/catchError_A01_t02: Pass # No AsyncError anymore. Issue 407 and 463
+LibTest/core/List/removeAt_A02_t01: Fail # co19 issue 670
 
 #end [ $compiler == none && $runtime == vm && $checked ]
 
 [ $compiler == none && $runtime == vm && $mode == debug ]
-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
 
@@ -77,13 +66,14 @@
 LibTest/core/double/toInt_A01_t01: Fail
 
 [ $compiler == none && $runtime == vm && ($arch == simarm || $arch == simmips) ]
-LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # co19-roll r576: Please triage this failure
+LibTest/core/Uri/Uri_A06_t03: Skip # Timeouts, co19-roll r576: Please triage this failure
+
+[ $compiler == none && $runtime == vm ]
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # Timeouts
+LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # Timeouts
 
 [ $compiler == none && $runtime == vm && $arch == simarm ]
 LibTest/typed_data/Float32x4/sqrt_A01_t01: Pass, Fail # co19 issue 666.
 
-[ $compiler == none && $checked && ($runtime == vm || $runtime == dartium) ]
-Language/15_Types/1_Static_Types_A03_t01: RuntimeError # co19-roll r667: Please triage this failure
-
 [ $runtime == vm ]
-LibTest/isolate/Isolate/spawn_A02_t01: Timeout # co19-roll r672: Please triage this failure
+LibTest/isolate/Isolate/spawn_A02_t01: Skip # co19 issue 667
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index 2c2c02d..47deb90 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -4,7 +4,6 @@
 
 library analyze_helper;
 
-import "package:expect/expect.dart";
 import 'dart:async';
 import 'dart:io';
 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api;
@@ -13,6 +12,7 @@
     hide Compiler;
 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/util/uri_extras.dart';
 
 /**
  * Map of whitelisted warnings and errors.
@@ -46,12 +46,10 @@
     });
   }
 
-  void checkResults() {
-    Expect.isFalse(hasWarnings);
-    Expect.isFalse(hasHint);
-    Expect.isFalse(hasErrors);
-    Expect.isTrue(checkWhiteListUse());
+  bool checkResults() {
+    bool validWhiteListUse = checkWhiteListUse();
     reportWhiteListUse();
+    return !hasWarnings && !hasHint && !hasErrors && validWhiteListUse;
   }
 
   bool checkWhiteListUse() {
@@ -126,6 +124,19 @@
 Future analyze(List<Uri> uriList,
                Map<String, List<String>> whiteList,
                {bool analyzeAll: true}) {
+  String testFileName =
+      relativize(Uri.base, Platform.script, Platform.isWindows);
+
+  print("""
+
+
+=== 
+=== NOTE: If this test fails, update [WHITE_LIST] in $testFileName
+===
+
+
+""");
+
   var libraryRoot = currentDirectory.resolve('sdk/');
   var provider = new CompilerSourceFileProvider();
   var handler = new CollectingDiagnosticHandler(whiteList, provider);
@@ -138,14 +149,27 @@
       libraryRoot, libraryRoot,
       options,
       {});
+  String MESSAGE = """
+
+
+=== 
+=== ERROR: Unexpected result of analysis.
+=== 
+=== Please update [WHITE_LIST] in $testFileName
+=== 
+""";
+
+  void onCompletion(_) {
+    bool result = handler.checkResults();
+    if (!result) {
+      print(MESSAGE);
+      exit(1);
+    }
+  }
   if (analyzeAll) {
     compiler.librariesToAnalyzeWhenRun = uriList;
-    return compiler.run(null).then((_) {
-      handler.checkResults();
-    });
+    return compiler.run(null).then(onCompletion);
   } else {
-    return compiler.run(uriList.single).then((_) {
-      handler.checkResults();
-    });
+    return compiler.run(uriList.single).then(onCompletion);
   }
 }
diff --git a/tests/compiler/dart2js/async_compiler_input_provider_test.dart b/tests/compiler/dart2js/async_compiler_input_provider_test.dart
index 6a45022..7f370c3 100644
--- a/tests/compiler/dart2js/async_compiler_input_provider_test.dart
+++ b/tests/compiler/dart2js/async_compiler_input_provider_test.dart
@@ -31,7 +31,7 @@
   var source = SOURCES[uri.path];
   if (source == null) {
     // Not one of our source files, so assume it's a built-in.
-    source = new File(uriPathToNative(uri.path)).readAsStringSync();
+    source = new File(uri.toFilePath()).readAsStringSync();
   }
 
   // Deliver the input asynchronously.
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/closure_tracer_test.dart
new file mode 100644
index 0000000..600f228
--- /dev/null
+++ b/tests/compiler/dart2js/closure_tracer_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+
+import 'compiler_helper.dart';
+import 'parser_helper.dart';
+
+const String TEST = '''
+testFunctionStatement() {
+  var res;
+  closure(a) => res = a;
+  closure(42);
+  return res;
+}
+
+testFunctionExpression() {
+  var res;
+  var closure = (a) => res = a;
+  closure(42);
+  return res;
+}
+
+var staticField;
+
+testStoredInStatic() {
+  var res;
+  closure(a) => res = a;
+  staticField = closure;
+  staticField(42);
+  return res;
+}
+
+class A {
+  var field;
+  A(this.field);
+  static foo(a) => topLevel3 = a;
+}
+
+testStoredInInstance() {
+  var res;
+  closure(a) => res = a;
+  var a = new A(closure);
+  a.field(42);
+  return res;
+}
+
+foo(closure) {
+  closure(42);
+}
+
+testPassedInParameter() {
+  var res;
+  closure(a) => res = a;
+  foo(closure);
+  return res;
+}
+
+var topLevel1;
+foo2(a) => topLevel1 = a;
+testStaticClosure1() {
+  var a = foo2;
+  a(42);
+  return topLevel1;
+}
+
+var topLevel2;
+bar(a) => topLevel2 = a;
+testStaticClosure2() {
+  var a = bar;
+  a(42);
+  var b = bar;
+  b(2.5);
+  return topLevel2;
+}
+
+var topLevel3;
+testStaticClosure3() {
+  var a = A.foo;
+  a(42);
+  return topLevel3;
+}
+
+var topLevel4;
+testStaticClosure4Helper(a) => topLevel4 = a;
+testStaticClosure4() {
+  var a = testStaticClosure4Helper;
+  // Test calling the static after tearing it off.
+  testStaticClosure4Helper(2.5);
+  a(42);
+  return topLevel4;
+}
+
+main() {
+  testFunctionStatement();
+  testFunctionExpression();
+  testStoredInStatic();
+  testStoredInInstance();
+  testPassedInParameter();
+  testStaticClosure1();
+  testStaticClosure2();
+  testStaticClosure3();
+  testStaticClosure4();
+}
+''';
+
+void main() {
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(TEST, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    var typesTask = compiler.typesTask;
+    var typesInferrer = typesTask.typesInferrer;
+
+    checkType(String name, type) {
+      var element = findElement(compiler, name);
+      var mask = typesInferrer.getReturnTypeOfElement(element);
+      Expect.equals(type.nullable(), mask.simplify(compiler), name);
+    }
+
+    checkType('testFunctionStatement', typesTask.uint31Type);
+    checkType('testFunctionExpression', typesTask.uint31Type);
+    checkType('testStoredInInstance', typesTask.uint31Type);
+    checkType('testStoredInStatic', typesTask.uint31Type);
+    checkType('testPassedInParameter', typesTask.uint31Type);
+    checkType('testStaticClosure1', typesTask.uint31Type);
+    checkType('testStaticClosure2', typesTask.numType);
+    checkType('testStaticClosure3', typesTask.uint31Type);
+    checkType('testStaticClosure4', typesTask.numType);
+  }));
+}
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 746a502..eddfdc2 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -36,9 +36,7 @@
         var parameter =
           printElement.computeSignature(compiler).requiredParameters.head;
         var type = compiler.typesTask.getGuaranteedTypeOfElement(parameter);
-        var inferrer = compiler.typesTask.typesInferrer;
-        Expect.identical(compiler.typesTask.dynamicType,
-                         type.simplify(compiler));
+        checkType(compiler, type);
       }));
 
   asyncTest(() => compileAndFind(
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 2751baf..7bbae64 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -6,8 +6,11 @@
 constant_folding_string_test: Fail
 boolified_operator_test: Fail # Issue 8001
 
-analyze_api_test: Pass, Slow
-analyze_dart2js_test: Pass, Slow
+# Don't mark these tests as failing. Instead, fix the errors/warnings that they
+# report or update the whitelist in the test-files to temporarily allow
+# digression.
+analyze_api_test: Pass, Slow # DON'T CHANGE THIS LINE -- SEE ABOVE.
+analyze_dart2js_test: Pass, Slow # DON'T CHANGE THIS LINE -- SEE ABOVE.
 
 # simple_function_subtype_test is temporarily(?) disabled due to new method for
 # building function type tests.
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart
new file mode 100644
index 0000000..5f21cc5
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.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.
+
+// Test of the graph segmentation algorithm used by deferred loading
+// to determine which elements can be deferred and which libraries
+// much be included in the initial download (loaded eagerly).
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_source_file_helper.dart';
+import "dart:async";
+
+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
+       as dart2js;
+
+class FakeOutputStream<T> extends EventSink<T> {
+  void add(T event) {}
+  void addError(T event, [StackTrace stackTrace]) {}
+  void close() {}
+}
+
+void main() {
+  Uri script = currentDirectory.resolveUri(Platform.script);
+  Uri libraryRoot = script.resolve('../../../sdk/');
+  Uri packageRoot = script.resolve('./packages/');
+
+  var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
+  var handler = new FormattingDiagnosticHandler(provider);
+
+  Compiler compiler = new Compiler(provider.readStringFromUri,
+                                   (name, extension) => new FakeOutputStream(),
+                                   handler.diagnosticHandler,
+                                   libraryRoot,
+                                   packageRoot,
+                                   [],
+                                   {});
+  asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    var outputUnitForElement = compiler.deferredLoadTask.outputUnitForElement;
+    var mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
+    var lib = compiler.libraries["memory:lib.dart"];
+    var f1 = lib.find("f1");
+    var f2 = lib.find("f2");
+    Expect.notEquals(mainOutputUnit, outputUnitForElement(f1));
+    Expect.equals(mainOutputUnit, outputUnitForElement(f2));
+  }));
+}
+
+// The main library imports lib1 and lib2 deferred and use lib1.foo1 and
+// lib2.foo2.  This should trigger seperate outputunits for main, lib1 and lib2.
+//
+// Both lib1 and lib2 import lib3 directly and
+// both use lib3.foo3.  Therefore a shared output unit for lib1 and lib2 should
+// be created.
+//
+// lib1 and lib2 also import lib4 deferred, but lib1 uses lib4.bar1 and lib2
+// uses lib4.bar2.  So two output units should be created for lib4, one for each
+// import.
+const Map MEMORY_SOURCE_FILES = const {"main.dart": """
+import "dart:async";
+
+@def import 'lib.dart' show f1;
+import 'lib.dart' show f2;
+
+const def = const DeferredLibrary("deferred");
+
+void main() {
+  print(f2());
+  def.load().then((_) {
+    print(f1());
+  });
+}
+""", "lib.dart": """
+int f1 () {
+  return 1;
+}
+
+int f2 () {
+  return 2;
+}
+""",};
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index f753aad..dc3c7ae 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -9,10 +9,17 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'memory_source_file_helper.dart';
+import "dart:async";
 
 import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
        as dart2js;
 
+class FakeOutputStream<T> extends EventSink<T> {
+  void add(T event) {}
+  void addError(T event, [StackTrace stackTrace]) {}
+  void close() {}
+}
+
 void main() {
   Uri script = currentDirectory.resolveUri(Platform.script);
   Uri libraryRoot = script.resolve('../../../sdk/');
@@ -22,57 +29,126 @@
   var handler = new FormattingDiagnosticHandler(provider);
 
   Compiler compiler = new Compiler(provider.readStringFromUri,
-                                   (name, extension) => null,
+                                   (name, extension) => new FakeOutputStream(),
                                    handler.diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   ['--analyze-only'],
+                                   [],
                                    {});
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
     Expect.isNotNull(main, "Could not find 'main'");
     compiler.deferredLoadTask.onResolutionComplete(main);
 
-    var deferredClasses =
-        compiler.deferredLoadTask.allDeferredElements.where((e) => e.isClass())
-        .toSet();
+    var outputUnitForElement = compiler.deferredLoadTask.outputUnitForElement;
 
-    var dateTime = deferredClasses.where((e) => e.name == 'DateTime').single;
+    var mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
+    var classes = compiler.backend.emitter.neededClasses;
+    var inputElement = classes.where((e) => e.name == 'InputElement').single;
+    var lib1 = compiler.libraries["memory:lib1.dart"];
+    var foo1 = lib1.find("foo1");
+    var lib2 = compiler.libraries["memory:lib2.dart"];
+    var foo2 = lib2.find("foo2");
+    var lib3 = compiler.libraries["memory:lib3.dart"];
+    var foo3 = lib3.find("foo3");
+    var lib4 = compiler.libraries["memory:lib4.dart"];
+    var bar1 = lib4.find("bar1");
+    var bar2 = lib4.find("bar2");
+    var outputClassLists = compiler.backend.emitter.outputClassLists;
 
-    var myClass = deferredClasses.where((e) => e.name == 'MyClass').single;
-
-    var deferredLibrary = compiler.libraries['memory:deferred.dart'];
-
-    Expect.equals(deferredLibrary, myClass.getLibrary());
-    Expect.equals(compiler.coreLibrary, dateTime.declaration.getLibrary());
+    Expect.equals(mainOutputUnit, outputUnitForElement(main));
+    Expect.notEquals(mainOutputUnit, outputUnitForElement(foo1));
+    Expect.notEquals(outputUnitForElement(foo1), outputUnitForElement(foo3));
+    Expect.notEquals(outputUnitForElement(foo2), outputUnitForElement(foo3));
+    Expect.notEquals(outputUnitForElement(foo1), outputUnitForElement(foo2));
+    Expect.notEquals(outputUnitForElement(bar1), outputUnitForElement(bar2));
+    // InputElement is native, so it should not appear on a classList
+    Expect.isFalse(outputClassLists[outputUnitForElement(inputElement)]
+        .contains(inputElement));
   }));
 }
 
+// The main library imports lib1 and lib2 deferred and use lib1.foo1 and
+// lib2.foo2.  This should trigger seperate output units for main, lib1 and
+// lib2.
+//
+// Both lib1 and lib2 import lib3 directly and
+// both use lib3.foo3.  Therefore a shared output unit for lib1 and lib2 should
+// be created.
+//
+// lib1 and lib2 also import lib4 deferred, but lib1 uses lib4.bar1 and lib2
+// uses lib4.bar2.  So two output units should be created for lib4, one for each
+// import.
 const Map MEMORY_SOURCE_FILES = const {
-  'main.dart': """
-import 'dart:async';
+  "main.dart":"""
+import "dart:async";
+@def_main_1 import 'lib1.dart' as l1;
+@def_main_2 import 'lib2.dart' as l2;
 
-@lazy import 'deferred.dart';
+const def_main_1 = const DeferredLibrary("lib1");
+const def_main_2 = const DeferredLibrary("lib2");
 
-const lazy = const DeferredLibrary('deferred');
-
-main() {
-  lazy.load().then((_) {
-    if (42 != new MyClass().foo(87)) throw "not equal";
+void main() {
+  def_main_1.load().then((_) {
+        l1.foo1();
+        new l1.C();
+    def_main_2.load().then((_) {
+        l2.foo2();
+    });
   });
 }
-
 """,
-  'deferred.dart': """
-library deferred;
+  "lib1.dart":"""
+library lib1;
+import "dart:async";
+import "dart:html";
 
-class MyClass {
-  const MyClass();
+import "lib3.dart" as l3;
+@def_1_1 import "lib4.dart" as l4;
 
-  foo(x) {
-    new DateTime.now();
-    return (x - 3) ~/ 2;
-  }
+const def_1_1 = const DeferredLibrary("lib4_1");
+
+class C {}
+
+foo1() {
+  new InputElement();
+  def_1_1.load().then((_) {
+    l4.bar1();
+  });
+  return () {return 1 + l3.foo3();} ();
+}
+""",
+  "lib2.dart":"""
+library lib2;
+import "dart:async";
+import "lib3.dart" as l3;
+@def_2_1 import "lib4.dart" as l4;
+
+const def_2_1 = const DeferredLibrary("lib4_2");
+
+foo2() {
+  def_2_1.load().then((_) {
+    l4.bar2();
+  });
+  return () {return 2+l3.foo3();} ();
+}
+""",
+  "lib3.dart":"""
+library lib3;
+
+foo3() {
+  return () {return 3;} ();
+}
+""",
+  "lib4.dart":"""
+library lib4;
+
+bar1() {
+  return "hello";
+}
+
+bar2() {
+  return 2;
 }
 """,
 };
diff --git a/tests/compiler/dart2js/deferred_mirrors_test.dart b/tests/compiler/dart2js/deferred_mirrors_test.dart
new file mode 100644
index 0000000..2f18a84
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_mirrors_test.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test of the graph segmentation algorithm used by deferred loading
+// to determine which elements can be deferred and which libraries
+// much be included in the initial download (loaded eagerly).
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_source_file_helper.dart';
+import "dart:async";
+
+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
+       as dart2js;
+
+class FakeOutputStream<T> extends EventSink<T> {
+  void add(T event) {}
+  void addError(T event, [StackTrace stackTrace]) {}
+  void close() {}
+}
+
+void main() {
+  Uri script = currentDirectory.resolveUri(Platform.script);
+  Uri libraryRoot = script.resolve('../../../sdk/');
+  Uri packageRoot = script.resolve('./packages/');
+
+  var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
+  var handler = new FormattingDiagnosticHandler(provider);
+
+  Compiler compiler = new Compiler(provider.readStringFromUri,
+                                   (name, extension) => new FakeOutputStream(),
+                                   handler.diagnosticHandler,
+                                   libraryRoot,
+                                   packageRoot,
+                                   [],
+                                   {});
+  asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
+    var outputUnitForElement = compiler.deferredLoadTask.outputUnitForElement;
+
+    var mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
+    var classes = compiler.backend.emitter.neededClasses;
+    var lib1 = compiler.libraries["memory:lib1.dart"];
+    var lib2 = compiler.libraries["memory:lib2.dart"];
+    var mathLib = compiler.libraries["dart:math"];
+    var sin = mathLib.find('sin');
+    var foo1 = lib1.find("foo1");
+    var foo2 = lib2.find("foo2");
+
+    var outputClassLists = compiler.backend.emitter.outputClassLists;
+
+    Expect.notEquals(mainOutputUnit, outputUnitForElement(foo1));
+    Expect.equals(outputUnitForElement(foo1), outputUnitForElement(sin));
+  }));
+}
+
+// "lib1.dart" uses mirrors without a MirrorsUsed annotation, so everything
+// should be put in the "lib1" output unit.
+const Map MEMORY_SOURCE_FILES = const {
+  "main.dart":"""
+import "dart:async";
+import "dart:math";
+
+@def1 import 'lib1.dart' as lib1;
+@def2 import 'lib2.dart' as lib2;
+
+const def1 = const DeferredLibrary("lib1");
+const def2 = const DeferredLibrary("lib2");
+
+void main() {
+  def1.load().then((_) {
+    lib1.foo1();
+  });
+  def2.load().then((_) {
+    lib2.foo2();
+  });
+}
+""",
+  "lib1.dart":"""
+library lib1;
+import "dart:mirrors";
+
+const field1 = 42;
+
+void foo1() {
+  var mirror = reflect(field1);
+  mirror.invoke(null, null);
+}
+""",
+  "lib2.dart":"""
+library lib2;
+@MirrorsUsed(targets: "field2") import "dart:mirrors";
+
+const field2 = 42;
+
+void foo2() {
+  var mirror = reflect(field2);
+  mirror.invoke(null, null);
+}
+""",
+};
diff --git a/tests/compiler/dart2js/deferred_not_in_main_test.dart b/tests/compiler/dart2js/deferred_not_in_main_test.dart
new file mode 100644
index 0000000..e27e689
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_not_in_main_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test of the graph segmentation algorithm used by deferred loading
+// to determine which elements can be deferred and which libraries
+// much be included in the initial download (loaded eagerly).
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_source_file_helper.dart';
+import "dart:async";
+
+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
+       as dart2js;
+
+class FakeOutputStream<T> extends EventSink<T> {
+  void add(T event) {}
+  void addError(T event, [StackTrace stackTrace]) {}
+  void close() {}
+}
+
+void main() {
+  Uri script = currentDirectory.resolveUri(Platform.script);
+  Uri libraryRoot = script.resolve('../../../sdk/');
+  Uri packageRoot = script.resolve('./packages/');
+
+  var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
+  var handler = new FormattingDiagnosticHandler(provider);
+
+  Compiler compiler = new Compiler(provider.readStringFromUri,
+                                   (name, extension) => new FakeOutputStream(),
+                                   handler.diagnosticHandler,
+                                   libraryRoot,
+                                   packageRoot,
+                                   [],
+                                   {});
+  asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
+    var outputUnitForElement = compiler.deferredLoadTask.outputUnitForElement;
+
+    var mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
+    var classes = compiler.backend.emitter.neededClasses;
+    var lib1 = compiler.libraries["memory:lib1.dart"];
+    var lib2 = compiler.libraries["memory:lib2.dart"];
+    var foo1 = lib1.find("foo1");
+    var foo2 = lib2.find("foo2");
+
+    var outputClassLists = compiler.backend.emitter.outputClassLists;
+
+    Expect.equals(mainOutputUnit, outputUnitForElement(foo2));
+  }));
+}
+
+// lib1 imports lib2 deferred. But mainlib never uses DeferredLibrary.
+// Therefore we should not split the program.
+const Map MEMORY_SOURCE_FILES = const {
+  "main.dart":"""
+library mainlib;
+
+import 'lib1.dart' as lib1;
+
+void main() {
+  lib1.foo1();
+}
+""",
+  "lib1.dart":"""
+library lib1;
+
+import 'dart:async';
+@def import 'lib2.dart';
+
+const def = const DeferredLibrary('lib2');
+
+void foo1() {
+  def.load().then((_) => foo2());
+}
+""",
+  "lib2.dart":"""
+library lib2;
+
+void foo2() {}
+""",
+};
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index b7181c4..54c718a 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -276,7 +276,7 @@
       } else {
         a = g;
       }
-      a();
+      a(this);
     }
   }
   main() {
diff --git a/tests/compiler/dart2js/literal_map_test.dart b/tests/compiler/dart2js/literal_map_test.dart
index 0e30d4e..1b51336 100644
--- a/tests/compiler/dart2js/literal_map_test.dart
+++ b/tests/compiler/dart2js/literal_map_test.dart
@@ -19,5 +19,7 @@
   Expect.isFalse(generated.contains('bailout'));
   Expect.isFalse(generated.contains('interceptor'));
   // Make sure we don't go through an interceptor.
-  Expect.isTrue(generated.contains('a.\$indexSet'));
+  Expect.isTrue(
+      generated.contains(r'a.$indexSet(a') ||
+      generated.contains(r'.$indexSet(0'));
 }
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 5a9cb74..a91eeff 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -26,8 +26,8 @@
     hide TreeElementMapping;
 
 import '../../../sdk/lib/_internal/compiler/implementation/deferred_load.dart'
-    show DeferredLoadTask;
-
+    show DeferredLoadTask,
+         OutputUnit;
 
 class WarningMessage {
   Spannable node;
@@ -548,11 +548,12 @@
   }
 }
 
+// The mock compiler does not split the program in output units.
 class MockDeferredLoadTask extends DeferredLoadTask {
   MockDeferredLoadTask(Compiler compiler) : super(compiler);
 
-  void registerMainApp(LibraryElement mainApp) {
-    // Do nothing.
+  OutputUnit getElementOutputUnit(dynamic dependency) {
+    return mainOutputUnit;
   }
 }
 
diff --git a/tests/compiler/dart2js/path with spaces/file with spaces.dart b/tests/compiler/dart2js/path with spaces/file with spaces.dart
new file mode 100644
index 0000000..b0cc204
--- /dev/null
+++ b/tests/compiler/dart2js/path with spaces/file with spaces.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 'library space/lib with spaces.dart';
+
+main() {
+  if (foo() != 499) throw "bad value";
+}
diff --git a/tests/compiler/dart2js/path with spaces/library space/lib with spaces.dart b/tests/compiler/dart2js/path with spaces/library space/lib with spaces.dart
new file mode 100644
index 0000000..16da6e3
--- /dev/null
+++ b/tests/compiler/dart2js/path with spaces/library space/lib with spaces.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 spaces;
+
+part "part space/part space.dart";
+
+foo() => bar();
diff --git a/tests/compiler/dart2js/path with spaces/library space/part space/part space.dart b/tests/compiler/dart2js/path with spaces/library space/part space/part space.dart
new file mode 100644
index 0000000..58aff0f
--- /dev/null
+++ b/tests/compiler/dart2js/path with spaces/library space/part space/part space.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 spaces;
+
+bar() => 499;
diff --git a/tests/compiler/dart2js/space_test.dart b/tests/compiler/dart2js/space_test.dart
new file mode 100644
index 0000000..6eeafcd
--- /dev/null
+++ b/tests/compiler/dart2js/space_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import '../../../sdk/lib/_internal/compiler/implementation/dart2js.dart'
+  as dart2js;
+
+main() {
+  Uri currentDirectory = Uri.base;
+  Uri script = currentDirectory.resolveUri(Platform.script);
+  Uri libraryRoot = script.resolve('../../../sdk/');
+  Directory.current = script.resolve("path with spaces").toFilePath();
+
+  return dart2js.main(["--library-root=${libraryRoot.toFilePath()}",
+                       "--analyze-only",
+                       "file with spaces.dart"]);
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index f9eed72..32b71a3 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -7,6 +7,7 @@
 statements_test: Fail
 typed_locals_test: Fail
 no_such_method_test: Fail # Wrong Invocation.memberName.
+deferred/deferred_constant_test: Fail # http://dartbug.com/11138
 
 constant_javascript_semantics4_test: Fail, OK
 
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_class_library.dart b/tests/compiler/dart2js_extra/deferred/deferred_class_library.dart
index 14bb1e6..138036c 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_class_library.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_class_library.dart
@@ -20,4 +20,5 @@
   const Constant(this.value);
 
   operator==(other) => other is Constant && value == other.value;
+  get hashCode => 0;
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_class_library2.dart b/tests/compiler/dart2js_extra/deferred/deferred_class_library2.dart
new file mode 100644
index 0000000..82359bc
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_class_library2.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Imported by deferred_class_test.dart.
+
+library deferred_class_library2;
+
+class MyClass {
+  const MyClass();
+
+  foo(x) {
+    print('MyClass.foo($x)');
+    return (x - 3) ~/ 2;
+  }
+}
+
+class Constant {
+  final value;
+  const Constant(this.value);
+
+  operator==(other) => other is Constant && value == other.value;
+  get hashCode => 0;
+}
+
+const C1 = const Constant(499);
+const C2 = const [const Constant(99)];
+
+foo([x = const Constant(42)]) => x;
+bar() => const Constant(777);
+
+class Gee {
+  get value => c.value;
+  final c;
+
+  Gee([this.c = const Constant(111)]);
+  const Gee.n321([this.c = const Constant(321)]);
+  Gee.n135({ arg: const Constant(135) }) : this.c = arg;
+  const Gee.n246({ arg: const Constant(246) }) : this.c = arg;
+  const Gee.n888() : this.c = const Constant(888);
+  const Gee.constant(this.c);
+}
+
+class Gee2 extends Gee {
+  Gee2() : super(const Constant(979));
+  const Gee2.n321(): super.n321();
+  const Gee2.n151(): super.constant(const Constant(151));
+  const Gee2.n888() : super.n888();
+}
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
new file mode 100644
index 0000000..db7e9eb
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+@lazy import 'deferred_class_library2.dart';
+
+const lazy = const DeferredLibrary('deferred_class_library2');
+
+main() {
+  asyncStart();
+  lazy.load().then((bool didLoad) {
+    Expect.isTrue(didLoad);
+    Expect.equals(499, C1.value);
+    asyncEnd();
+  });
+}
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
new file mode 100644
index 0000000..8ae2b12
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+@lazy import 'deferred_class_library2.dart';
+
+const lazy = const DeferredLibrary('deferred_class_library2');
+
+main() {
+  asyncStart();
+  lazy.load().then((bool didLoad) {
+    Expect.isTrue(didLoad);
+    Expect.equals(499, C1.value);
+    Expect.equals(99, C2[0].value);
+    Expect.equals(42, foo().value);
+    Expect.equals(777, bar().value);
+    Expect.equals(111, new Gee().value);
+    Expect.equals(321, new Gee.n321().value);
+    Expect.equals(135, new Gee.n135().value);
+    Expect.equals(246, new Gee.n246().value);
+    Expect.equals(888, new Gee.n888().value);
+    Expect.equals(979, new Gee2().value);
+    Expect.equals(321, new Gee2.n321().value);
+    Expect.equals(151, new Gee2.n151().value);
+    Expect.equals(888, new Gee2.n888().value);
+    asyncEnd();
+  });
+}
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
new file mode 100644
index 0000000..7d0cc91
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+@lazy import 'deferred_class_library2.dart';
+
+const lazy = const DeferredLibrary('deferred_class_library2');
+
+main() {
+  asyncStart();
+  lazy.load().then((bool didLoad) {
+    Expect.isTrue(didLoad);
+    // Only Gee2.n888 to make sure no other constant pulls in its super.
+    Expect.equals(888, new Gee2.n888().value);
+    asyncEnd();
+  });
+}
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart
new file mode 100644
index 0000000..14abc76
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant5_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+@lazy import 'deferred_class_library2.dart';
+
+const lazy = const DeferredLibrary('deferred_class_library2');
+
+main() {
+  asyncStart();
+  lazy.load().then((bool didLoad) {
+    Expect.isTrue(didLoad);
+    Expect.equals(321, const Gee.n321().value);
+    Expect.equals(246, const Gee.n246().value);
+    Expect.equals(888, const Gee.n888().value);
+    Expect.equals(321, const Gee2.n321().value);
+    Expect.equals(151, const Gee2.n151().value);
+    Expect.equals(888, const Gee2.n888().value);
+    asyncEnd();
+  });
+}
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant_test.dart
index 22e7265..163234c 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant_test.dart
@@ -13,10 +13,9 @@
 
 main() {
   var x;
-  Expect.isNull(const MyClass());
-  Expect.isNull(const Constant(42));
-  Expect.isNull(const [const Constant(42)]);
-  Expect.isNull(x);
+  Expect.throws(() => const MyClass());
+  Expect.throws(() => const Constant(42));
+  Expect.throws(() => const [const Constant(42)]);
   int counter = 0;
   asyncStart();
   lazy.load().then((bool didLoad) {
@@ -42,7 +41,7 @@
   });
   Expect.equals(0, counter);
   Expect.isNull(x);
-  Expect.isNull(const Constant(42));
-  Expect.isNull(const [const Constant(42)]);
+  Expect.throws(() => const Constant(42));
+  Expect.throws(() => const [const Constant(42)]);
   Expect.isNull(x);
 }
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_semantics_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_semantics_test.dart
deleted file mode 100644
index 140faca..0000000
--- a/tests/compiler/dart2js_extra/deferred/deferred_semantics_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that deferred loading requires same library names.
-
-import 'dart:async';
-
-@lazy  /// 01: compile-time error
-import 'deferred_function_library.dart';
-
-const lazy = const DeferredLibrary('fisk');
-
-main() {
-}
diff --git a/tests/corelib/duration_test.dart b/tests/corelib/duration_test.dart
index 6111615..306873d 100644
--- a/tests/corelib/duration_test.dart
+++ b/tests/corelib/duration_test.dart
@@ -225,4 +225,46 @@
 
   d = const Duration(hours: -1999, minutes: -17, seconds: -42);
   Expect.equals("-1999:17:42.000000", d.toString());
+
+  // Edge conditions for toString of microseconds.
+  // Regression test for http://dartbug.com/15678
+
+  d = const Duration(microseconds: 1);
+  Expect.equals("0:00:00.000001", d.toString());
+
+  d = const Duration(microseconds: 9);
+  Expect.equals("0:00:00.000009", d.toString());
+
+  d = const Duration(microseconds: 10);
+  Expect.equals("0:00:00.000010", d.toString());
+
+  d = const Duration(microseconds: 99);
+  Expect.equals("0:00:00.000099", d.toString());
+
+  d = const Duration(microseconds: 100);
+  Expect.equals("0:00:00.000100", d.toString());
+
+  d = const Duration(microseconds: 999);
+  Expect.equals("0:00:00.000999", d.toString());
+
+  d = const Duration(microseconds: 1000);
+  Expect.equals("0:00:00.001000", d.toString());
+
+  d = const Duration(microseconds: 9999);
+  Expect.equals("0:00:00.009999", d.toString());
+
+  d = const Duration(microseconds: 10000);
+  Expect.equals("0:00:00.010000", d.toString());
+
+  d = const Duration(microseconds: 99999);
+  Expect.equals("0:00:00.099999", d.toString());
+
+  d = const Duration(microseconds: 100000);
+  Expect.equals("0:00:00.100000", d.toString());
+
+  d = const Duration(microseconds: 999999);
+  Expect.equals("0:00:00.999999", d.toString());
+
+  d = const Duration(microseconds: 1000000);
+  Expect.equals("0:00:01.000000", d.toString());
 }
diff --git a/tests/html/audiobuffersourcenode_test.dart b/tests/html/audiobuffersourcenode_test.dart
index 10fecc9..15bba1e 100644
--- a/tests/html/audiobuffersourcenode_test.dart
+++ b/tests/html/audiobuffersourcenode_test.dart
@@ -18,8 +18,8 @@
       if(AudioContext.supported) {
         var ctx = new AudioContext();
         AudioBufferSourceNode node = ctx.createBufferSource();
+        expect(node is AudioBufferSourceNode, isTrue);
         node.start(ctx.currentTime, 0, 2);
-        node.stop(ctx.currentTime + 2);
         expect(node is AudioBufferSourceNode, isTrue);
       }
     });
diff --git a/tests/html/canvas_pixel_array_type_alias_test.dart b/tests/html/canvas_pixel_array_type_alias_test.dart
index 250824d..7cdbb24 100644
--- a/tests/html/canvas_pixel_array_type_alias_test.dart
+++ b/tests/html/canvas_pixel_array_type_alias_test.dart
@@ -1,50 +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 CanvasTest;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
+import 'dart:typed_data';
 
 // We have aliased the legacy type CanvasPixelArray with the new type
 // Uint8ClampedArray by mapping the CanvasPixelArray type tag to
 // Uint8ClampedArray.  It is not a perfect match since CanvasPixelArray is
 // missing the ArrayBufferView members.  These should appear to be null.
 
-Object confuseType(x) => [1, x, [x], 's'] [1];
+var inscrutable;
 
 main() {
-  CanvasElement canvas;
-  CanvasRenderingContext2D context;
+
+  useHtmlIndividualConfiguration();
+
+  inscrutable = (x) => x;
+
   int width = 100;
   int height = 100;
 
-  canvas = new Element.tag('canvas');
-  canvas.width = width;
-  canvas.height = height;
+  CanvasElement canvas = new CanvasElement(width: width, height: height);
   document.body.append(canvas);
 
-  context = canvas.getContext('2d');
+  CanvasRenderingContext2D context = canvas.context2D;
 
-  useHtmlConfiguration();
+  group('basic', () {
+    test('CreateImageData', () {
+      ImageData image = context.createImageData(canvas.width,
+                                                canvas.height);
+      List<int> data = image.data;
+      // It is legal for the dart2js compiler to believe the type of the native
+      //   ImageData.data and elides the check, so check the type explicitly:
+      expect(inscrutable(data) is List<int>, isTrue,
+          reason: 'canvas array type');
 
-  test('CreateImageData', () {
-    ImageData image = context.createImageData(canvas.width,
-                                              canvas.height);
-    List<int> data = image.data;
-    // It is legal for the dart2js compiler to believe the type of the native
-    // ImageData.data and elides the check, so check the type explicitly:
-    expect(confuseType(data) is List<int>, isTrue,
-        reason: 'canvas array type');
+      expect(data, hasLength(40000));
+      checkPixel(data, 0, [0, 0, 0, 0]);
+      checkPixel(data, width * height - 1, [0, 0, 0, 0]);
 
-    expect(data, hasLength(40000));
-    checkPixel(data, 0, [0, 0, 0, 0]);
-    checkPixel(data, width * height - 1, [0, 0, 0, 0]);
+      data[100] = 200;
+      expect(data[100], equals(200));
+    });
+  });
 
-    data[100] = 200;
-    expect(data[100], equals(200));
+  group('types1', () {
+    test('isList', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is List, true);
+    });
+
+    test('isListT_pos', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is List<int>, true);
+    });
+  });
+
+  group('types2', () {
+    test('isListT_neg', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is List<String>, false);
+    });
+
+    test('isUint8ClampedList', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data) is Uint8ClampedList, true);
+    });
+
+    test('consistent_isUint8ClampedList', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      // Static and dynamic values consistent?  Type inference should be able to
+      // constant-fold 'data is Uint8ClampedList' to 'true'.
+      expect(inscrutable(data) is Uint8ClampedList == data is Uint8ClampedList,
+             isTrue);
+    });
+
+    // TODO(sra): Why does this fail on Dartium? There are two types with the
+    // same print string:
+    //
+    //     Expected: ?:<Uint8ClampedList> Actual: ?:<Uint8ClampedList>
+    /*
+    test('runtimeType', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data).runtimeType, Uint8ClampedList);
+    });
+    */
+
+    test('consistent_runtimeType', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data).runtimeType == data.runtimeType, isTrue);
+    });
+
+    test('runtimeTypeName', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect('${inscrutable(data).runtimeType}', 'Uint8ClampedList');
+    });
+  });
+
+  group('typed_data', () {
+    test('elementSizeInBytes', () {
+      var data = context.createImageData(canvas.width, canvas.height).data;
+      expect(inscrutable(data).elementSizeInBytes, 1);
+    });
   });
 }
 
-void checkPixel(List<int> data, int offset, List<int> rgba)
-{
+void checkPixel(List<int> data, int offset, List<int> rgba) {
   offset *= 4;
   for (var i = 0; i < 4; ++i) {
     expect(rgba[i], equals(data[offset + i]));
diff --git a/tests/html/custom/mirrors_test.dart b/tests/html/custom/mirrors_test.dart
index ea6b091..9cf892b 100644
--- a/tests/html/custom/mirrors_test.dart
+++ b/tests/html/custom/mirrors_test.dart
@@ -4,6 +4,7 @@
 
 library tests.html.mirrors_test;
 
+@MirrorsUsed(targets: const [A, B])
 import 'dart:mirrors';
 import 'dart:html';
 import 'package:unittest/unittest.dart';
diff --git a/tests/html/html.status b/tests/html/html.status
index a983939..e2ca971 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -21,9 +21,6 @@
 [ $compiler == dart2js && $browser ]
 custom/created_callback_test: Fail # Support for created constructor.
 
-[ $compiler == dart2js && ($runtime == drt || $runtime == dartium) ]
-audiobuffersourcenode_test/functional: Fail # 15913
-
 [ $compiler == none && ($runtime == drt || $runtime == dartium) && $mode == debug && $system == macos]
 audiobuffersourcenode_test: Pass, Fail, Crash # http://crbug.com/256601
 
@@ -74,10 +71,6 @@
 [ $compiler == dart2js && ( $runtime == ie9 || $runtime == ie10 ) ]
 worker_api_test: Fail # IE does not support URL.createObjectURL in web workers.
 
-[ $compiler == dart2js && $browser && $checked ]
-postmessage_structured_test/typed_arrays: Fail # Issue 10097
-postmessage_structured_test/primitives: Fail # Issue 10097
-
 [ $compiler == dart2js && $runtime == chrome ]
 selectelement_test: Skip # http://dartbug.com/15516
 
@@ -85,7 +78,7 @@
 canvasrenderingcontext2d_test/drawImage_video_element: Pass,Fail # Issue 11836
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Pass,Fail # Issue 11836
 
-touchevent_test/supported: Fail
+touchevent_test/supported: Pass, Fail # Passing on 32.
 
 xhr_test: Pass, Fail # Issue 11884
 xhr_cross_origin_test: Pass, Fail # Issue 11884
@@ -401,7 +394,6 @@
 [ $compiler == none && $runtime == dartium ]
 async_test: Timeout # Issue 13719: Please triage this failure.
 element_offset_test/offset: Pass, Fail # Issue 13719, 13296
-touchevent_test/supported: Fail # Issue 13719: Please triage this failure.
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 audiocontext_test: StaticWarning
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index 0ff9665..c41c335 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -137,7 +137,7 @@
   });
 
   group('typed_arrays', () {
-    var array_buffer = new Uint8List(16);
+    var array_buffer = new Uint8List(16).buffer;
     var view_a = new Float32List.view(array_buffer, 0, 4);
     var view_b = new Uint8List.view(array_buffer, 1, 13);
     var typed_arrays_list = [view_a, array_buffer, view_b];
diff --git a/tests/language/arithmetic_test.dart b/tests/language/arithmetic_test.dart
index e43dc4a..64ab133 100644
--- a/tests/language/arithmetic_test.dart
+++ b/tests/language/arithmetic_test.dart
@@ -435,10 +435,15 @@
   
   static double sinCosSub(double a) => sin(a) - cos(a);
   
+  static double sinCosAddCos(double a)  => sin(a) * cos(a) + cos(a);
+
   static void testSinCos() {
     var e = sin(1.234) - cos(1.234);
+    var f = sin(1.234) * cos(1.234) + cos(1.234);
+    
     for (var i = 0; i < 20; i++) {
       Expect.approxEquals(e, sinCosSub(1.234));
+      Expect.approxEquals(f, sinCosAddCos(1.234));
     }
     Expect.approxEquals(1.0, sinCosSub(3.14159265));
     Expect.approxEquals(1.0, sinCosSub(3.14159265 / 2.0));
diff --git a/tests/language/cyclic_type2_test.dart b/tests/language/cyclic_type2_test.dart
new file mode 100644
index 0000000..84787c7
--- /dev/null
+++ b/tests/language/cyclic_type2_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.
+
+// Tests self referencing types.
+
+import "package:expect/expect.dart";
+
+class Base<U, V> {
+  get u => U;
+  get v => V;
+}
+
+class Derived1<U, V> extends Base<Derived1<U, V>,
+                                  Derived1<Derived2<V, U>, Derived2>> {}
+
+class Derived2<U, V> extends Base<Derived2<U, V>,
+                                  Derived2<Derived1<V, U>, Derived1>> {}
+
+main() {
+  var d = new Derived1<Derived1, Derived2>();
+  Expect.equals("Derived1<Derived1, Derived2>", d.u.toString());
+  Expect.equals("Derived1<Derived2<Derived2, Derived1>, Derived2>",
+                d.v.toString());
+  Expect.isTrue(d is Derived1<Derived1, Derived2>);
+  Expect.isFalse(d is Derived1<Derived1, Derived1>);
+  Expect.isTrue(d is Base<Derived1<Derived1, Derived2>,
+                          Derived1<Derived2<Derived2, Derived1>, Derived2>>);
+  Expect.isFalse(d is Base<Derived1<Derived1, Derived2>,
+                           Derived1<Derived2<Derived2, Derived2>, Derived2>>);
+}
diff --git a/tests/language/fixed_type_variable2_test.dart b/tests/language/fixed_type_variable2_test.dart
new file mode 100644
index 0000000..157fae3
--- /dev/null
+++ b/tests/language/fixed_type_variable2_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that type variables are passed on from subtypes that fixed the type
+// variable in inheritance.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+  B<T> createB() => new B<T>();
+}
+
+class NumA extends A<num> {
+}
+
+class B<T> {
+  T value;
+
+  void test(var o, bool expect) {
+    Expect.equals(expect, o is T);
+  }
+}
+
+class StringB extends B<String> {
+}
+
+class C<T> extends A<T> {
+}
+
+class IntC extends C<int> {
+}
+
+void main() {
+  testA(); /// 01: ok
+  testNumA(); /// 02: ok
+  testB(); /// 03: ok
+  testStringB(); /// 04: ok
+  testC(); /// 05: ok
+  testIntC(); /// 06: ok
+}
+
+void testA() {
+  var instanceA = new A<String>();
+  var instanceB = instanceA.createB();
+  instanceB.test(0.5, false);
+  instanceB.test(0, false);
+  instanceB.test('', true);
+}
+
+void testNumA() {
+  var instanceA = new NumA();
+  var instanceB = instanceA.createB();
+  instanceB.test(0.5, true);
+  instanceB.test(0, true);
+  instanceB.test('', false);
+}
+
+void testB() {
+  var instanceB = new B<int>();
+  instanceB.test(0.5, false);
+  instanceB.test(0, true);
+  instanceB.test('', false);
+}
+
+void testStringB() {
+  var instanceB = new StringB();
+  instanceB.test(0.5, false);
+  instanceB.test(0, false);
+  instanceB.test('', true);
+}
+
+void testC() {
+  var instanceA = new C<String>();
+  var instanceB = instanceA.createB();
+  instanceB.test(0.5, false);
+  instanceB.test(0, false);
+  instanceB.test('', true);
+}
+
+void testIntC() {
+  var instanceA = new IntC();
+  var instanceB = instanceA.createB();
+  instanceB.test(0.5, false);
+  instanceB.test(0, true);
+  instanceB.test('', false);
+}
\ No newline at end of file
diff --git a/tests/language/fixed_type_variable_test.dart b/tests/language/fixed_type_variable_test.dart
new file mode 100644
index 0000000..e032faf
--- /dev/null
+++ b/tests/language/fixed_type_variable_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that type variables are passed on from subtypes that fixed the type
+// variable in inheritance.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+  B<T> createB() => new B<T>();
+}
+
+class NumA extends A<num> {
+}
+
+class B<T> {
+  T value;
+
+  void test(var type, bool expect) {
+    Expect.equals(expect, T == type);
+  }
+}
+
+class StringB extends B<String> {
+}
+
+class C<T> extends A<T> {
+}
+
+class IntC extends C<int> {
+}
+
+void main() {
+  testA(); /// 01: ok
+  testNumA(); /// 02: ok
+  testB(); /// 03: ok
+  testStringB(); /// 04: ok
+  testC(); /// 05: ok
+  testIntC(); /// 06: ok
+}
+
+void testA() {
+  var instanceA = new A<String>();
+  var instanceB = instanceA.createB();
+  instanceB.test(num, false);
+  instanceB.test(int, false);
+  instanceB.test(String, true);
+}
+
+void testNumA() {
+  var instanceA = new NumA();
+  var instanceB = instanceA.createB();
+  instanceB.test(num, true);
+  instanceB.test(int, false);
+  instanceB.test(String, false);
+}
+
+void testB() {
+  var instanceB = new B<int>();
+  instanceB.test(num, false);
+  instanceB.test(int, true);
+  instanceB.test(String, false);
+}
+
+void testStringB() {
+  var instanceB = new StringB();
+  instanceB.test(num, false);
+  instanceB.test(int, false);
+  instanceB.test(String, true);
+}
+
+void testC() {
+  var instanceA = new C<String>();
+  var instanceB = instanceA.createB();
+  instanceB.test(num, false);
+  instanceB.test(int, false);
+  instanceB.test(String, true);
+}
+
+void testIntC() {
+  var instanceA = new IntC();
+  var instanceB = instanceA.createB();
+  instanceB.test(num, false);
+  instanceB.test(int, true);
+  instanceB.test(String, false);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_bound_closure5a_test.dart b/tests/language/function_subtype_bound_closure5a_test.dart
new file mode 100644
index 0000000..106f113
--- /dev/null
+++ b/tests/language/function_subtype_bound_closure5a_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for bound closures on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+class C<T> {
+  int foo(bool a, [String b]) => null;
+  int baz(bool a, {String b}) => null;
+
+  void test(String nameOfT, bool expectedResult) {
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+    Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+    Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+  }
+}
+
+class Cm<T> extends C<T> {}
+
+class D<S, T> extends Cm<T> {}
+
+main() {
+  new D<String, bool>().test('bool', true);
+  new D<bool, int>().test('int', false);
+  new D().test('dynamic', true);
+}
\ No newline at end of file
diff --git a/tests/language/import_private_test.dart b/tests/language/import_private_test.dart
index e269c7a..85eccde 100644
--- a/tests/language/import_private_test.dart
+++ b/tests/language/import_private_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Check that private dart:_ libraries cannot be imported.
 
-import "dart:_collection-dev";  /// 01: compile-time error
+import "dart:_internal";  /// 01: compile-time error
 
 main() {
   print("Done.");
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index b10f1a2..c4886a9 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -336,6 +336,9 @@
 mixin_type_parameters_super_extends_test: StaticWarning
 mixin_type_parameters_super_test: StaticWarning
 mixin_with_two_implicit_constructors_test: StaticWarning
+mixin_bound_test: StaticWarning
+mixin_invalid_bound_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
+mixin_invalid_bound2_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
 named_constructor_test/01: StaticWarning
 named_constructor_test/03: StaticWarning
 named_parameters2_test: StaticWarning
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 3ce7bcc..0cdd781 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -317,7 +317,6 @@
 malbounded_type_literal_test: StaticWarning
 malformed_type_test: StaticWarning
 malformed2_test/01: MissingCompileTimeError
-map_literal11_test: StaticWarning
 map_literal2_negative_test: CompileTimeError
 map_literal3_test: StaticWarning
 map_literal4_test: StaticWarning
@@ -464,3 +463,4 @@
 vm/type_cast_vm_test: StaticWarning
 vm/type_vm_test: StaticWarning
 void_type_test: StaticWarning
+
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 18a5a57..5407092 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -52,6 +52,7 @@
 default_factory2_test/01: Fail # Issue 14121
 typevariable_substitution2_test/01: CompileTimeError # Issue 15875
 typevariable_substitution2_test/02: CompileTimeError # Issue 15875
+mixin_bound_test: CompileTimeError # Issue 15875
 
 [ $compiler == dart2js && $unchecked ]
 type_checks_in_factory_method_test: RuntimeError # Issue 12746
@@ -85,6 +86,7 @@
 
 [ $compiler == dart2js && $minified ]
 cyclic_type_test: Fail # Issue 12605.
+cyclic_type2_test: Fail # Issue 12605.
 f_bounded_quantification4_test: Fail # Issue 12605.
 f_bounded_quantification5_test: Fail # Issue 12605.
 mixin_generic_test: Fail # Issue 12605.
@@ -93,6 +95,8 @@
 mixin_mixin4_test: Fail # Issue 12605.
 mixin_mixin5_test: Fail # Issue 12605.
 mixin_mixin6_test: Fail # Issue 12605.
+mixin_mixin_bound_test: RuntimeError # Issue 12605.
+mixin_mixin_bound2_test: RuntimeError # Issue 12605.
 
 [ $compiler == dart2js ]
 function_type_alias9_test/00: Crash
@@ -300,12 +304,14 @@
 
 [ $compiler == dart2dart && $minified ]
 cyclic_type_test: Fail # Issue 12605.
+cyclic_type2_test: Fail # Issue 12605.
 super_getter_setter_test: Fail # Issue 11065.
 f_bounded_quantification4_test: Fail # Issue 12605.
 f_bounded_quantification5_test: Fail # Issue 12605.
 many_overridden_no_such_method_test: Pass, Fail # Issue 13078
 overridden_no_such_method_test: Pass, Fail # Issue 13078
 no_such_method_test: Pass, Fail # Issue 13078
+type_variable_typedef_test: Fail # Issue 11467
 
 import_core_prefix_test: Pass
 prefix22_test: Pass
diff --git a/tests/language/mixin_bound_test.dart b/tests/language/mixin_bound_test.dart
new file mode 100644
index 0000000..a4d7d46
--- /dev/null
+++ b/tests/language/mixin_bound_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// library abstract_expressions;
+
+abstract class AbstractExpression {}
+
+abstract class AbstractAddition<E> {
+  E operand1, operand2;
+  AbstractAddition(this.operand1, this.operand2);
+}
+
+abstract class AbstractSubtraction<E> {
+  E operand1, operand2;
+  AbstractSubtraction(this.operand1, this.operand2);
+}
+
+abstract class AbstractNumber {
+  int val;
+  AbstractNumber(this.val);
+}
+
+// library evaluator;
+
+abstract class ExpressionWithEval {
+ int get eval;
+}
+
+abstract class AdditionWithEval<E extends ExpressionWithEval> {
+ E get operand1;
+ E get operand2;
+ int get eval => operand1.eval + operand2.eval;
+}
+
+abstract class SubtractionWithEval<E extends ExpressionWithEval>{
+  E get operand1;
+  E get operand2;
+  int get eval => operand1.eval - operand2.eval;
+}
+
+abstract class NumberWithEval {
+  int get val;
+  int get eval => val;
+}
+
+// library multiplication;
+
+abstract class AbstractMultiplication<E> {
+  E operand1, operand2;
+  AbstractMultiplication(this.operand1, this.operand2);
+
+}
+
+// library multiplicationEvaluator;
+
+// import 'evaluator.dart' show ExpressionWithEval;
+
+abstract class MultiplicationWithEval<E extends ExpressionWithEval> {
+  E get operand1;
+  E get operand2;
+  int get eval => operand1.eval * operand2.eval;
+}
+
+// library string_converter;
+
+abstract class ExpressionWithStringConversion {
+ String toString();
+}
+
+abstract class AdditionWithStringConversion<E extends ExpressionWithStringConversion> {
+  E get operand1;
+  E get operand2;
+  String toString() =>'($operand1 + $operand2))';
+}
+
+abstract class SubtractionWithStringConversion<E extends ExpressionWithStringConversion> {
+  E get operand1;
+  E get operand2;
+  String toString() => '($operand1 - $operand2)';
+}
+
+abstract class NumberWithStringConversion {
+  int get val;
+  String toString() => val.toString();
+}
+
+abstract class MultiplicationWithStringConversion<E extends ExpressionWithStringConversion> {
+  E get operand1;
+  E get operand2;
+  String toString() => '($operand1 * $operand2)';
+}
+
+// library expressions;
+
+// import 'abstractExpressions.dart';
+// import 'evaluator.dart';
+// import 'multiplication.dart';
+// import 'multiplicationEvaluator.dart';
+// import 'stringConverter.dart';
+
+class Expression =
+  AbstractExpression with ExpressionWithEval, ExpressionWithStringConversion;
+
+class Addition =
+  AbstractAddition<Expression> with AdditionWithEval<Expression>,
+                                    AdditionWithStringConversion<Expression> implements Expression;
+
+class Subtraction =
+  AbstractSubtraction<Expression> with SubtractionWithEval<Expression>,
+                                       SubtractionWithStringConversion<Expression> implements Expression;
+
+class Number =
+  AbstractNumber with NumberWithEval,
+                      NumberWithStringConversion implements Expression;
+
+
+class Multiplication =
+  AbstractMultiplication<Expression> with MultiplicationWithEval<Expression>,
+                                          MultiplicationWithStringConversion<Expression> implements Expression;
+
+
+void main() {
+  Expression e = new Multiplication(new Addition(new Number(4), new Number(2)),
+                                    new Subtraction(new Number(10), new Number(7)));
+  Expect.equals('((4 + 2)) * (10 - 7)) = 18', '$e = ${e.eval}');
+}
diff --git a/tests/language/mixin_invalid_bound2_test.dart b/tests/language/mixin_invalid_bound2_test.dart
new file mode 100644
index 0000000..818a4aa
--- /dev/null
+++ b/tests/language/mixin_invalid_bound2_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 S0<T> { }
+
+class S<U extends num, V extends U> extends S0<String> { }
+
+class M<U extends num, V extends U> { }
+
+class A<U extends num, V extends U> extends S with M { }
+
+// A StaticWarning is reported here and in C, D, and E below, because U and V
+// are not bounded. The purpose of this test is to verify bound checking in S,
+// M, and A, the reason no bounds are declared for U and V here.
+class B<U, V> extends S<U, V> with M<int, int> { }
+
+class C<U, V> extends S<int, int> with M<U, V> { }
+
+class D<U, V> extends S<U, V> with M<double, int> { }
+
+class E<U, V> extends S<double, int> with M<U, V> { }
+
+main() {
+  new A<int, int>();  /// 01: static type warning
+  new A<double, int>();  /// 02: static type warning, dynamic type error
+  new A<bool, bool>();  /// 03: static type warning, dynamic type error
+  new B<int, int>();  /// 04: static type warning
+  new B<double, int>();  /// 05: static type warning, dynamic type error
+  new B<bool, bool>();  /// 06: static type warning, dynamic type error
+  new C<int, int>();  /// 07: static type warning
+  new C<double, int>();  /// 08: static type warning, dynamic type error
+  new C<bool, bool>();  /// 09: static type warning, dynamic type error
+  new D<int, int>();  /// 10: static type warning, dynamic type error
+  new D<double, int>();  /// 11: static type warning, dynamic type error
+  new D<bool, bool>();  /// 12: static type warning, dynamic type error
+  new E<int, int>();  /// 12: static type warning, dynamic type error
+  new E<double, int>();  /// 13: static type warning, dynamic type error
+  new E<bool, bool>();  /// 14: static type warning, dynamic type error
+}
diff --git a/tests/language/mixin_invalid_bound_test.dart b/tests/language/mixin_invalid_bound_test.dart
new file mode 100644
index 0000000..7e76d44
--- /dev/null
+++ b/tests/language/mixin_invalid_bound_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 S0<T> { }
+
+class S<T extends num> extends S0<String> { }
+
+class M<T extends num> { }
+
+class A<T extends num> extends S with M { }
+
+// A StaticWarning is reported here and in C, D, and E below, because T is not
+// bounded. The purpose of this test is to verify bound checking in S, M, and A,
+// the reason no bound is declared for T here.
+class B<T> extends S<T> with M<int> { }
+
+class C<T> extends S<int> with M<T> { }
+
+class D<T> extends S<T> with M<bool> { }
+
+class E<T> extends S<bool> with M<T> { }
+
+main() {
+  new A<int>();  /// 01: static type warning
+  new A<bool>();  /// 02: static type warning, dynamic type error
+  new B<int>();  /// 03: static type warning
+  new B<bool>();  /// 04: static type warning, dynamic type error
+  new C<int>();  /// 05: static type warning
+  new C<bool>();  /// 06: static type warning, dynamic type error
+  new D<int>();  /// 07: static type warning, dynamic type error
+  new D<bool>();  /// 08: static type warning, dynamic type error
+  new E<int>();  /// 09: static type warning, dynamic type error
+  new E<bool>();  /// 10: static type warning, dynamic type error
+}
diff --git a/tests/language/mixin_mixin_bound2_test.dart b/tests/language/mixin_mixin_bound2_test.dart
new file mode 100644
index 0000000..726a200
--- /dev/null
+++ b/tests/language/mixin_mixin_bound2_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<T> { }
+
+class J<T> { }
+
+class K<T> { }
+
+class S<U extends Set<V>, V> { }
+
+class M<U, V, T extends Map<U, V>> {
+  m() { return T; }
+}
+
+class A<U, V extends Set<U>> = Object with M<U, V, Map<U, V>> implements I<V>;
+
+class B<T extends List<num>> = Object with A<T, Set<T>> implements J<T>;
+
+class C<T extends num> = S<Set<T>, T> with B<List<T>> implements K<T>;
+
+main() {
+  var c = new C<int>();
+  Expect.equals("Map<List<int>, Set<List<int>>>", c.m().toString());
+  Expect.isTrue(c is K<int>);
+  Expect.isTrue(c is J<List<int>>);
+  Expect.isTrue(c is I<Set<List<int>>>);
+  Expect.isTrue(c is S<Set<int>, int>);
+  Expect.isTrue(c is A<List<int>, Set<List<int>>>);
+  Expect.isTrue(c is M<List<int>, Set<List<int>>, Map<List<int>, Set<List<int>>>>);
+}
diff --git a/tests/language/mixin_mixin_bound_test.dart b/tests/language/mixin_mixin_bound_test.dart
new file mode 100644
index 0000000..19f276f
--- /dev/null
+++ b/tests/language/mixin_mixin_bound_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<T> { }
+
+class J<T> { }
+
+class S<U extends Set<V>, V> { }
+
+class M<U, V, T extends Map<U, V>> {
+  t() { return T; }
+}
+
+class A<U, V extends List> = Object with M<U, V, Map<U, V>> implements I<V>;
+
+class C<T, K> = S<Set<T>, T> with A<T, List<K>> implements J<K>;
+
+main() {
+  var c = new C<int, bool>();
+  Expect.equals("Map<int, List<bool>>", c.t().toString());
+  Expect.isTrue(c is I<List<bool>>);
+  Expect.isTrue(c is J<bool>);
+  Expect.isTrue(c is S<Set<int>, int>);
+  Expect.isTrue(c is A<int, List<bool>>);
+  Expect.isTrue(c is M<int, List<bool>, Map<int, List<bool>>>);
+}
diff --git a/tests/language/modulo_test.dart b/tests/language/modulo_test.dart
index 6dc22cf..f14d3c5 100644
--- a/tests/language/modulo_test.dart
+++ b/tests/language/modulo_test.dart
@@ -24,7 +24,7 @@
     } else {
       Expect.equals(i ~/ 10, noDom(i));
     }
-    Expect.equals((i ~/ 10) + (i ~/ 10) + (i % 10), threeOp(i));
+    Expect.equals((i ~/ 10) + (i % 10) + (i % 10), threeOp(i));
     Expect.equals((i ~/ 10) + (i ~/ 12) + (i % 10) + (i % 12), fourOp(i));
     
     // Zero test is done outside the loop.
@@ -60,7 +60,7 @@
 
 threeOp(a) {
   var x = a ~/ 10;
-  var y = a ~/ 10;
+  var y = a % 10;
   var z = a % 10;
   return x + y + z;
 }
diff --git a/tests/language/optimized_string_charcodeat_test.dart b/tests/language/optimized_string_charcodeat_test.dart
index 26978e4..98f4397 100644
--- a/tests/language/optimized_string_charcodeat_test.dart
+++ b/tests/language/optimized_string_charcodeat_test.dart
@@ -9,7 +9,7 @@
 
 
 String one_byte = "hest";
-String two_byte = "høns";
+String two_byte = "h\u{2029}ns";
 
 int testOneByteCodeUnitAt(String x, int j) {
   int test() {
@@ -68,13 +68,13 @@
 main() {
   for (int j = 0; j < 10; j++) {
     Expect.equals(101, testOneByteCodeUnitAt(one_byte, 1));
-    Expect.equals(248, testTwoByteCodeUnitAt(two_byte, 1));
+    Expect.equals(8233, testTwoByteCodeUnitAt(two_byte, 1));
     Expect.equals(248, testConstantStringCodeUnitAt(1));
     Expect.equals(101, testConstantIndexCodeUnitAt(one_byte));
   }
   for (int j = 0; j < 20; j++) {
     Expect.equals(436, testOneByteCodeUnitAtInLoop(one_byte));
-    Expect.equals(577, testTwoByteCodeUnitAtInLoop(two_byte));
+    Expect.equals(8562, testTwoByteCodeUnitAtInLoop(two_byte));
   }
   Expect.throws(() => testOneByteCodeUnitAtInLoop(123));
   Expect.throws(() => testTwoByteCodeUnitAtInLoop(123));
diff --git a/tests/language/type_variable_typedef_test.dart b/tests/language/type_variable_typedef_test.dart
new file mode 100644
index 0000000..80cf1d5
--- /dev/null
+++ b/tests/language/type_variable_typedef_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that rti dependency registration takes type variables within typedefs
+// into account.
+
+import 'package:expect/expect.dart';
+
+typedef Foo<T>(T t);
+
+class A<T> {
+  m() => new B<Foo<T>>();
+}
+
+class B<T> {
+  m(o) => o is T;
+}
+
+foo(int i) {}
+bar(String s) {}
+
+void main() {
+  Expect.isTrue(new A<int>().m().m(foo));
+  Expect.isFalse(new A<int>().m().m(bar));
+  Expect.isFalse(new A<String>().m().m(foo));
+  Expect.isTrue(new A<String>().m().m(bar));
+  Expect.isFalse(new A<double>().m().m(foo));
+  Expect.isFalse(new A<double>().m().m(bar));
+}
\ No newline at end of file
diff --git a/tests/language/vm/allocation_sinking_vm_test.dart b/tests/language/vm/allocation_sinking_vm_test.dart
index 24d5895..619235a 100644
--- a/tests/language/vm/allocation_sinking_vm_test.dart
+++ b/tests/language/vm/allocation_sinking_vm_test.dart
@@ -4,6 +4,7 @@
 // Test allocation sinking optimization.
 // VMOptions=--optimization-counter-threshold=10 --no-use-osr
 
+import 'dart:typed_data';
 import 'package:expect/expect.dart';
 
 class Point {
@@ -21,6 +22,22 @@
   C(this.p);
 }
 
+
+class Pointx4 {
+  var x, y;
+
+  Pointx4(this.x, this.y);
+
+  operator * (other) {
+    return x * other.x + y * other.y;
+  }
+}
+
+class Cx4 {
+  var p;
+  Cx4(this.p);
+}
+
 class D {
   var p;
   D(this.p);
@@ -55,6 +72,13 @@
   return d * d;
 }
 
+test1x4(c, x, y, z, w) {
+  var a = new Pointx4(x - z, y + w);
+  var b = new Pointx4(x + w, y + z);
+  var d = new Pointx4(c.p * a, c.p * b);
+  return d * d;
+}
+
 effects() {
   // This function should not be inlinable.
   try { } catch (e) { }
@@ -144,12 +168,22 @@
 
   // Compute initial values.
   final x0 = test1(c, 11.11, 22.22);
+  var fc = new Cx4(new Pointx4(new Float32x4(1.0, 1.0, 1.0, 1.0),
+                               new Float32x4(1.0, 1.0, 1.0, 1.0)));
+  final fx0 = test1x4(fc, new Float32x4(1.0, 1.0, 1.0, 1.0),
+                          new Float32x4(1.0, 1.0, 1.0, 1.0),
+                          new Float32x4(1.0, 1.0, 1.0, 1.0),
+                          new Float32x4(1.0, 1.0, 1.0, 1.0));
   final y0 = testForwardingThroughEffects(c, 11.11, 22.22);
   final z0 = testIdentity(c.p);
 
   // Force optimization.
   for (var i = 0; i < 100; i++) {
     test1(c, i.toDouble(), i.toDouble());
+    test1x4(fc, new Float32x4(1.0, 1.0, 1.0, 1.0),
+                new Float32x4(1.0, 1.0, 1.0, 1.0),
+                new Float32x4(1.0, 1.0, 1.0, 1.0),
+                new Float32x4(1.0, 1.0, 1.0, 1.0));
     testForwardingThroughEffects(c, i.toDouble(), i.toDouble());
     testIdentity(c.p);
     foo2();
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index 5a398f4..5423577 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -25,14 +25,7 @@
 lib/_internal/dartdoc/lib/src/client/dropdown: CompileTimeError
 lib/_internal/dartdoc/lib/src/client/search: CompileTimeError
 lib/_internal/dartdoc/lib/universe_serializer: CompileTimeError
-lib/_internal/pub/lib/src/barback: Pass, CompileTimeError # Pass necessary, since CompileTimeError is valid for everything in that directory (not only for src/barback.dart)
 lib/_internal/pub/lib/src/command: Pass, CompileTimeError # Pass necessary, since CompileTimeError is valid for everything in that directory (not only for src/command.dart)
-lib/_internal/pub/test/descriptor: Pass, CompileTimeError # Pass necessary, since CompileTimeError is valid for everything in that directory (not only for test/descriptor.dart)
-lib/_internal/pub/test/lish/utils: CompileTimeError
-lib/_internal/pub/test/oauth2/utils: CompileTimeError
-lib/_internal/pub/test/serve/utils: CompileTimeError
-lib/_internal/pub/test/test_pub: CompileTimeError
-lib/_internal/pub/test/validator/utils: CompileTimeError
 lib/js/dart2js/js_dart2js: CompileTimeError
 lib/js/dartium/js_dartium: CompileTimeError
 lib/svg/dart2js/svg_dart2js: CompileTimeError
diff --git a/tests/lib/async/stream_iterator_test.dart b/tests/lib/async/stream_iterator_test.dart
new file mode 100644
index 0000000..56240cc
--- /dev/null
+++ b/tests/lib/async/stream_iterator_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:unittest/unittest.dart";
+
+main() {
+  test("stream iterator basic", () {
+    StreamController c = new StreamController();
+    Stream s = c.stream;
+    StreamIterator i = new StreamIterator(s);
+    i.moveNext().then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(42, i.current);
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(37, i.current);
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isFalse);
+    }));
+    c.add(42);
+    c.add(37);
+    c.close();
+  });
+
+  test("stream iterator prefilled", () {
+    StreamController c = new StreamController();
+    c.add(42);
+    c.add(37);
+    c.close();
+    Stream s = c.stream;
+    StreamIterator i = new StreamIterator(s);
+    i.moveNext().then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(42, i.current);
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(37, i.current);
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isFalse);
+    }));
+  });
+
+  test("stream iterator error", () {
+    StreamController c = new StreamController();
+    Stream s = c.stream;
+    StreamIterator i = new StreamIterator(s);
+    i.moveNext().then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(42, i.current);
+      return i.moveNext();
+    })).then((bool b) {
+      fail("Result not expected");
+    }, onError: expectAsync1((e) {
+      expect("BAD", e);
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isFalse);
+    }));
+    c.add(42);
+    c.addError("BAD");
+    c.add(37);
+    c.close();
+  });
+
+  test("stream iterator current/moveNext during move", () {
+    StreamController c = new StreamController();
+    Stream s = c.stream;
+    StreamIterator i = new StreamIterator(s);
+    i.moveNext().then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(42, i.current);
+      new Timer(const Duration(milliseconds:100), expectAsync0(() {
+        expect(i.current, null);
+        expect(() { i.moveNext(); }, throws);
+        c.add(37);
+        c.close();
+      }));
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isTrue);
+      expect(37, i.current);
+      return i.moveNext();
+    })).then(expectAsync1((bool b) {
+      expect(b, isFalse);
+    }));
+    c.add(42);
+  });
+}
diff --git a/tests/lib/json/json_test.dart b/tests/lib/convert/json_lib_test.dart
similarity index 100%
rename from tests/lib/json/json_test.dart
rename to tests/lib/convert/json_lib_test.dart
diff --git a/tests/corelib/json_test.dart b/tests/lib/convert/json_test.dart
similarity index 96%
rename from tests/corelib/json_test.dart
rename to tests/lib/convert/json_test.dart
index 86485e0..4470535 100644
--- a/tests/corelib/json_test.dart
+++ b/tests/lib/convert/json_test.dart
@@ -135,6 +135,13 @@
 
   testThrows("[2.,2]");
   testThrows("{2.:2}");
+
+  testThrows("NaN");
+  testThrows("Infinity");
+  testThrows("-Infinity");
+  Expect.throws(() => JSON.encode(double.NAN));
+  Expect.throws(() => JSON.encode(double.INFINITY));
+  Expect.throws(() => JSON.encode(double.NEGATIVE_INFINITY));
 }
 
 testStrings() {
diff --git a/tests/utils/json_test.dart b/tests/lib/convert/json_util_test.dart
similarity index 100%
rename from tests/utils/json_test.dart
rename to tests/lib/convert/json_util_test.dart
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 3b52d6d..85c81a8 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -15,7 +15,9 @@
 
 math/double_pow_test: RuntimeError
 math/low_test: RuntimeError
+math/random_big_test: RuntimeError  # Using bigint seeds for random.
 
+mirrors/abstract_class_test: RuntimeError # Issue 12826
 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
@@ -40,8 +42,6 @@
 mirrors/initializing_formals_test/01: RuntimeError # Issue 6490
 mirrors/initializing_formals_test/03: CompileTimeError # Issue 12164
 mirrors/instance_members_test: RuntimeError # Issue 14633
-mirrors/instance_members_with_override_test: RuntimeError # Issue 14633
-mirrors/instance_members_unimplemented_interface_test: RuntimeError # Issue 14633
 mirrors/instantiate_abstract_class_test: RuntimeError # Issue 6490
 mirrors/intercepted_superclass_test: RuntimeError # Issue 13644
 mirrors/invoke_test: RuntimeError # Issue 11954
@@ -127,6 +127,7 @@
 async/zone_empty_description2_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
 async/zone_create_timer2_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
 async/zone_create_periodic_timer_test: RuntimeError # Timer interface not supported: dartbug.com/7728.
+async/stream_iterator_test: RuntimeError, OK # Timer interface not supported: dartbug.com/7728.
 async/catch_errors12_test: Fail # Timer interface not supported: dartbug.com/7728.
 async/catch_errors13_test: Fail # Timer interface not supported: dartbug.com/7728.
 async/catch_errors14_test: Fail # Timer interface not supported: dartbug.com/7728.
@@ -161,7 +162,7 @@
 async/schedule_microtask6_test: Fail             # Issue 10957 - may be related to issue 10910
 
 [ $compiler == dart2dart && $minified ]
-json/json_test: Fail                            # Issue 10961
+convert/json_lib_test: Fail                      # Issue 10961
 
 [ $compiler == dart2js && $minified ]
 mirrors/typedef_test/01: Fail # http://dartbug.com/6490
@@ -186,6 +187,7 @@
 convert/streamed_conversion_utf8_decode_test: Pass, Timeout # http://dartbug.com/12768
 convert/utf85_test: Skip # Issue 12029.
 async/timer_isolate_test: Pass, Fail # Issue 14734
+convert/json_util_test: Fail # Issue 16109
 
 [ $compiler == dart2js ]
 typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
@@ -201,7 +203,6 @@
 [ $runtime == vm ]
 async/timer_not_available_test: Fail, OK
 mirrors/native_class_test: Fail, OK # This test is meant to run in a browser.
-mirrors/syntax_error_test/01: Fail # Issue 15886
 
 [ $compiler == none  ]
 mirrors/hierarchy_test: Fail # TODO(ahe): This test is slightly broken. http://dartbug.com/12464
@@ -218,7 +219,7 @@
 
 [ $compiler == none && ( $runtime == drt || $runtime == dartium ) ]
 async/schedule_microtask6_test: Fail # Issue 10910
-mirrors/immutable_collections_test: Fail # Issue 11857, Issue 14321
+mirrors/immutable_collections_test: Skip # Issue 16027
 mirrors/library_uri_io_test: Skip # Not intended for drt as it uses dart:io.
 mirrors/local_isolate_test: Skip # http://dartbug.com/12188
 
diff --git a/tests/lib/math/random_big_test.dart b/tests/lib/math/random_big_test.dart
new file mode 100644
index 0000000..1a22ea1
--- /dev/null
+++ b/tests/lib/math/random_big_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 Random can deal with a seed outside 64-bit range.
+
+// Library tag to allow Dartium to run the test.
+library random_big;
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+main() {
+  var results = [];
+  for(var i = 60; i < 80; i++) {
+    var rng = new Random(1<<i);
+    var val = rng.nextInt(100000);
+    print("$i: $val");
+    Expect.isFalse(results.contains(val));
+    results.add(val);
+  }
+}
diff --git a/tests/lib/mirrors/abstract_class_test.dart b/tests/lib/mirrors/abstract_class_test.dart
new file mode 100644
index 0000000..230097e
--- /dev/null
+++ b/tests/lib/mirrors/abstract_class_test.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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.abstract_class_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+void main() {
+  testSimple();
+  testFunctionType();
+  testFakeFunction();
+  testGeneric();
+  testAnonMixinApplication();
+  testNamedMixinApplication();
+}
+
+abstract class Foo {
+  foo();
+}
+class Bar extends Foo {
+  foo() {}
+}
+
+testSimple() {
+  Expect.isTrue(reflectClass(Foo).isAbstract);
+  Expect.isFalse(reflectClass(Bar).isAbstract);
+  Expect.isTrue(reflect(new Bar()).type.superclass.isAbstract);
+  Expect.isFalse(reflect(new Bar()).type.isAbstract);
+}
+
+
+void baz() {}
+
+testFunctionType() {
+  Expect.isFalse(reflect(baz).type.isAbstract);
+}
+
+abstract class FunctionFoo implements Function {
+  call();
+}
+class FunctionBar extends FunctionFoo {
+  call() {}
+}
+
+testFakeFunction() {
+  Expect.isTrue(reflectClass(FunctionFoo).isAbstract);
+  Expect.isFalse(reflectClass(FunctionBar).isAbstract);
+  Expect.isTrue(reflect(new FunctionBar()).type.superclass.isAbstract);
+  Expect.isFalse(reflect(new FunctionBar()).type.isAbstract);
+}
+
+abstract class GenericFoo<T> {
+  T genericFoo();
+}
+class GenericBar<T> extends GenericFoo<T> {
+  T genericFoo() {}
+}
+
+testGeneric() {
+  // Unbound.
+  Expect.isTrue(reflectClass(GenericFoo).isAbstract);
+  Expect.isFalse(reflectClass(GenericBar).isAbstract);
+  // Bound.
+  Expect.isTrue(reflect(new GenericBar<int>()).type.superclass.isAbstract);
+  Expect.isFalse(reflect(new GenericBar<int>()).type.isAbstract);
+}
+
+
+class S {}
+abstract class M {
+  mixinFoo();
+}
+abstract class MA extends S with M {
+}
+class SubMA extends MA {
+  mixinFoo() {}
+}
+class ConcreteMA extends S with M {
+  mixinFoo() {}
+}
+
+class M2 {
+  mixin2Foo() {}
+}
+abstract class MA2 extends S with M2 {
+  mixinBar();
+}
+class SubMA2 extends MA2 {
+  mixinBar() {}
+}
+class ConcreteMA2 extends S with M2 {
+  mixin2Foo() {}
+}
+
+testAnonMixinApplication() {
+  // Application is abstract.
+  {
+  // Mixin is abstract.
+  Expect.isFalse(reflectClass(SubMA).isAbstract);
+  Expect.isTrue(reflectClass(SubMA).superclass.isAbstract);
+  Expect.isFalse(reflectClass(SubMA).superclass.superclass.isAbstract);
+  Expect.isTrue(reflectClass(MA).isAbstract);
+  Expect.isFalse(reflectClass(MA).superclass.isAbstract);
+
+  // Mixin is concrete.
+  Expect.isFalse(reflectClass(SubMA2).isAbstract);
+  Expect.isTrue(reflectClass(SubMA2).superclass.isAbstract);
+  Expect.isFalse(reflectClass(SubMA2).superclass.superclass.isAbstract);
+  Expect.isTrue(reflectClass(MA2).isAbstract);
+  Expect.isFalse(reflectClass(MA2).superclass.isAbstract);
+  }
+
+  // Application is concrete.
+  {
+  // Mixin is abstract.
+  Expect.isFalse(reflectClass(ConcreteMA).isAbstract);
+  Expect.isFalse(reflectClass(ConcreteMA).superclass.isAbstract);
+  Expect.isFalse(reflectClass(ConcreteMA).superclass.superclass.isAbstract);
+
+  // Mixin is concrete.
+  Expect.isFalse(reflectClass(ConcreteMA2).isAbstract);
+  Expect.isFalse(reflectClass(ConcreteMA2).superclass.isAbstract);
+  Expect.isFalse(reflectClass(ConcreteMA2).superclass.superclass.isAbstract);
+  }
+}
+
+abstract class NamedMA = S with M;
+class SubNamedMA extends NamedMA {
+  mixinFoo() {}
+}
+class ConcreteNamedMA = S with M;
+
+abstract class NamedMA2 = S with M2;
+class SubNamedMA2 extends NamedMA2 {
+  mixinFoo() {}
+}
+class ConcreteNamedMA2 = S with M2;
+
+testNamedMixinApplication() {
+  // Application is abstract.
+  {
+  // Mixin is abstract.
+  Expect.isFalse(reflectClass(SubNamedMA).isAbstract);
+  Expect.isTrue(reflectClass(SubNamedMA).superclass.isAbstract);
+  Expect.isFalse(reflectClass(SubNamedMA).superclass.superclass.isAbstract);
+  Expect.isTrue(reflectClass(NamedMA).isAbstract);
+  Expect.isFalse(reflectClass(NamedMA).superclass.isAbstract);
+
+  // Mixin is concrete.
+  Expect.isFalse(reflectClass(SubNamedMA2).isAbstract);
+  Expect.isTrue(reflectClass(SubNamedMA2).superclass.isAbstract);
+  Expect.isFalse(reflectClass(SubNamedMA2).superclass.superclass.isAbstract);
+  Expect.isTrue(reflectClass(NamedMA2).isAbstract);
+  Expect.isFalse(reflectClass(NamedMA2).superclass.isAbstract);
+  }
+
+  // Application is concrete.
+  {
+  // Mixin is abstract.
+  Expect.isFalse(reflectClass(ConcreteNamedMA).isAbstract);
+  Expect.isFalse(reflectClass(ConcreteNamedMA).superclass.isAbstract);
+
+  // Mixin is concrete.
+  Expect.isFalse(reflectClass(ConcreteNamedMA2).isAbstract);
+  Expect.isFalse(reflectClass(ConcreteNamedMA2).superclass.isAbstract);
+  }
+}
diff --git a/tests/lib/mirrors/declarations_model_easier.dart b/tests/lib/mirrors/declarations_model_easier.dart
new file mode 100644
index 0000000..af655d6
--- /dev/null
+++ b/tests/lib/mirrors/declarations_model_easier.dart
@@ -0,0 +1,86 @@
+// 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;
+
+typedef bool Predicate(dynamic);
+
+abstract class Interface<I> {
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter;
+  set interfaceInstanceSetter(x);
+  interfaceInstanceMethod();
+
+  static var interfaceStaticVariable;
+  static get interfaceStaticGetter => null;
+  static set interfaceStaticSetter(x) => x;
+  static interfaceStaticMethod() => null;
+}
+
+class Superclass<S> {
+  operator -(x) => 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;
+
+  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> implements Interface<C> {
+  operator +(x) => null;
+
+  abstractMethod();
+
+  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;
+
+  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;
+
+  ConcreteClass(x) : super.generativeConstructor(x);
+}
diff --git a/tests/lib/mirrors/immutable_collections_test.dart b/tests/lib/mirrors/immutable_collections_test.dart
index 7f9ea0b..50fdd75 100644
--- a/tests/lib/mirrors/immutable_collections_test.dart
+++ b/tests/lib/mirrors/immutable_collections_test.dart
@@ -42,12 +42,16 @@
 
 checkClass(ClassMirror cm) {
   checkMap(cm.declarations, 'ClassMirror.declarations');
+  checkMap(cm.instanceMembers, 'ClassMirror.instanceMembers');
+  checkMap(cm.staticMembers, 'ClassMirror.staticMembers');
   checkList(cm.metadata, 'ClassMirror.metadata');
   checkList(cm.superinterfaces, 'ClassMirror.superinterfaces');
   checkList(cm.typeArguments, 'ClassMirror.typeArguments');
   checkList(cm.typeVariables, 'ClassMirror.typeVariables');
 
   cm.declarations.values.forEach(checkDeclaration);
+  cm.instanceMembers.values.forEach(checkDeclaration);
+  cm.staticMembers.values.forEach(checkDeclaration);
   cm.typeVariables.forEach(checkTypeVariable);
 }
 
@@ -65,9 +69,11 @@
 
 checkLibrary(LibraryMirror lm) {
   checkMap(lm.declarations, 'LibraryMirror.declarations');
+  checkMap(lm.topLevelMembers, 'LibraryMirror.topLevelMembers');
   checkList(lm.metadata, 'LibraryMirror.metadata');
 
   lm.declarations.values.forEach(checkDeclaration);
+  lm.topLevelMembers.values.forEach(checkDeclaration);
 }
 
 main() {
diff --git a/tests/lib/mirrors/instance_members_easier_test.dart b/tests/lib/mirrors/instance_members_easier_test.dart
new file mode 100644
index 0000000..530fa42
--- /dev/null
+++ b/tests/lib/mirrors/instance_members_easier_test.dart
@@ -0,0 +1,88 @@
+// 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.instance_members;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'declarations_model_easier.dart' as declarations_model;
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+class EasierSuperclass {
+  shuper() {}
+  static staticShuper() {}
+}
+class EasierMixin {
+  mixin() {}
+  static staticMixin() {}
+}
+class EasierMixinApplication extends EasierSuperclass with EasierMixin {
+  application() {}
+  static staticApplication() {}
+}
+class Derived extends EasierMixinApplication {
+  derived() {}
+  static staticDerived() {}
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+
+  Expect.setEquals(
+    [#+,
+     #instanceVariable,
+     const Symbol('instanceVariable='),
+     #instanceGetter,
+     const Symbol('instanceSetter='),
+     #instanceMethod,
+     #-,
+     #inheritedInstanceVariable,
+     const Symbol('inheritedInstanceVariable='),
+     #inheritedInstanceGetter,
+     const Symbol('inheritedInstanceSetter='),
+     #inheritedInstanceMethod,
+     #hashCode,
+     #runtimeType,
+     #==,
+     #noSuchMethod,
+     #toString],
+    selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  // Filter out private to avoid implementation-specific members of Object.
+
+  Expect.setEquals(
+    [#instanceVariable,
+     const Symbol('instanceVariable='),
+     #inheritedInstanceVariable,
+     const Symbol('inheritedInstanceVariable=')],
+    selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+
+  cm = reflectClass(Derived);
+  Expect.setEquals(
+    [#derived,
+     #shuper,
+     #mixin,
+     #application,
+     #hashCode,
+     #runtimeType,
+     #==,
+     #noSuchMethod,
+     #toString],
+    selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+
+  cm = reflectClass(EasierMixinApplication);
+  Expect.setEquals(
+    [#shuper,
+     #mixin,
+     #application,
+     #hashCode,
+     #runtimeType,
+     #==,
+     #noSuchMethod,
+     #toString],
+    selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+}
diff --git a/tests/lib/mirrors/mirrors_used_merge_test.dart b/tests/lib/mirrors/mirrors_used_merge_test.dart
new file mode 100644
index 0000000..534c5e7
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_used_merge_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.
+
+/// Test that two MirrorsUsed annotations can be merged with out crashing
+/// dart2js.
+
+@MirrorsUsed(symbols: const ['foo'])
+@MirrorsUsed(symbols: const ['bar'])
+import 'dart:mirrors';
+
+main() {
+  // Do nothing, just make sure that merging the annotations doesn't crash
+  // dart2js.
+}
diff --git a/tests/lib/mirrors/static_members_easier_test.dart b/tests/lib/mirrors/static_members_easier_test.dart
new file mode 100644
index 0000000..3cf98d7
--- /dev/null
+++ b/tests/lib/mirrors/static_members_easier_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.static_members;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model_easier.dart' as declarations_model;
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+  LibraryMirror lm = cm.owner;
+
+  Expect.setEquals(
+    [#staticVariable,
+     const Symbol('staticVariable='),
+     #staticGetter,
+     const Symbol('staticSetter='),
+     #staticMethod,
+     ],
+    selectKeys(cm.staticMembers, (dm) => true));
+
+  Expect.setEquals(
+    [#staticVariable,
+     const Symbol('staticVariable=')],
+    selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+}
diff --git a/tests/lib/typed_data/constructor_checks_test.dart b/tests/lib/typed_data/constructor_checks_test.dart
new file mode 100644
index 0000000..3842ac1
--- /dev/null
+++ b/tests/lib/typed_data/constructor_checks_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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:typed_data';
+
+checkLengthConstructors() {
+  check(creator) {
+    Expect.throws(() => creator(null));
+    Expect.throws(() => creator(8.5));
+    Expect.throws(() => creator('10'));
+    var a = creator(10);
+    Expect.equals(10, a.length);
+  }
+
+  check((a) => new Float32List(a));
+  check((a) => new Float64List(a));
+  check((a) => new Int8List(a));
+  check((a) => new Int8List(a));
+  check((a) => new Int16List(a));
+  check((a) => new Int32List(a));
+  check((a) => new Uint8List(a));
+  check((a) => new Uint16List(a));
+  check((a) => new Uint32List(a));
+}
+
+checkViewConstructors() {
+  var buffer = new Int8List(256).buffer;
+
+  check1(creator) {
+    Expect.throws(() => creator(10));
+    Expect.throws(() => creator(null));
+    var a = creator(buffer);
+    Expect.equals(buffer, a.buffer);
+  }
+
+  check2(creator) {
+    Expect.throws(() => creator(10, 0));
+    Expect.throws(() => creator(null, 0));
+    Expect.throws(() => creator(buffer, null));
+    Expect.throws(() => creator(buffer, '8'));
+    var a = creator(buffer, 8);
+    Expect.equals(buffer, a.buffer);
+  }
+
+  check1((a) => new Float32List.view(a));
+  check1((a) => new Float64List.view(a));
+  check1((a) => new Int8List.view(a));
+  check1((a) => new Int8List.view(a));
+  check1((a) => new Int16List.view(a));
+  check1((a) => new Int32List.view(a));
+  check1((a) => new Uint8List.view(a));
+  check1((a) => new Uint16List.view(a));
+  check1((a) => new Uint32List.view(a));
+
+  check2((a, b) => new Float32List.view(a, b));
+  check2((a, b) => new Float64List.view(a, b));
+  check2((a, b) => new Int8List.view(a, b));
+  check2((a, b) => new Int8List.view(a, b));
+  check2((a, b) => new Int16List.view(a, b));
+  check2((a, b) => new Int32List.view(a, b));
+  check2((a, b) => new Uint8List.view(a, b));
+  check2((a, b) => new Uint16List.view(a, b));
+  check2((a, b) => new Uint32List.view(a, b));
+}
+
+main() {
+  checkLengthConstructors();
+  checkViewConstructors();
+}
diff --git a/tests/lib/typed_data/setRange_5_test.dart b/tests/lib/typed_data/setRange_5_test.dart
new file mode 100644
index 0000000..66bbe1f
--- /dev/null
+++ b/tests/lib/typed_data/setRange_5_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 'setRange_lib.dart';
+import 'package:expect/expect.dart';
+import 'dart:typed_data';
+
+overlapTest() {
+  // buffer:  xxxxxxxxyyyyyyyyzzzzzzzz  // 3 * float32
+  // a0:       1 2 3 4 5 6 7 8 9101112  // 12 bytes
+  // a1:         a b c d e              //  5 bytes
+  // a2:           p q r s t            //  5 bytes
+  var buffer = new Float32List(3).buffer;
+  var a0 = new Int8List.view(buffer);
+  var a1 = new Int8List.view(buffer, 1, 5);
+  var a2 = new Int8List.view(buffer, 2, 5);
+  initialize(a0);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]', '$a0');
+  Expect.equals('[2, 3, 4, 5, 6]', '$a1');
+  Expect.equals('[3, 4, 5, 6, 7]', '$a2');
+  a1.setRange(0, 5, a2);
+  Expect.equals('[1, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12]', '$a0');
+
+  initialize(a0);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]', '$a0');
+  Expect.equals('[2, 3, 4, 5, 6]', '$a1');
+  Expect.equals('[3, 4, 5, 6, 7]', '$a2');
+  a2.setRange(0, 5, a1);
+  Expect.equals('[1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12]', '$a0');
+}
+
+main() {
+  overlapTest();
+}
diff --git a/tests/standalone/debugger/break_at_equals_test.dart b/tests/standalone/debugger/break_at_equals_test.dart
new file mode 100644
index 0000000..ab0cce3
--- /dev/null
+++ b/tests/standalone/debugger/break_at_equals_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "debug_lib.dart";
+
+class MyClass {
+  operator ==(other) {
+    print(other);
+    return true;  // Breakpoint #3.
+  }
+}
+
+main(List<String> arguments) {
+  if (RunScript(testScript, arguments)) return;
+  var a = new MyClass();
+  var b = null;
+  a == b;  // Breakpoint #1.
+  print("after 1");
+  b = 123;
+  a == b;  // Breakpoint #2.
+  print("after 2");
+  a == null;  // Breakpoint #4.
+  print("after 4");
+  if (null == a) {
+    throw "unreachable";
+  }
+  print("ok");
+}
+
+// Checks that debugger can stop at calls to == even if one
+// of the operands is null.
+
+var testScript = [
+  MatchFrames(["main"]),
+  MatchLine(15),
+  SetBreakpoint(18),
+  SetBreakpoint(21),
+  SetBreakpoint(10),
+  SetBreakpoint(23),
+  Resume(),
+  MatchFrames(["main"]),
+  MatchLine(18),  // At breakpoint #1.
+  Resume(),
+  MatchLine(21),  // At breakpoint #2; didn't hit breakpoint in MyClass.==.
+  Resume(),
+  MatchFrames(["MyClass.==", "main"]),
+  MatchLine(10),  // At breakpoint #3 in MyClass.==.
+  Resume(),
+  MatchLine(23),  // At breakpoint #4.
+  Resume()
+];
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index c1bf590..f352233 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -180,6 +180,67 @@
   }
 }
 
+class GetLineTableCmd extends Command {
+  GetLineTableCmd() {
+    template = {"id": 0,
+                "command": "getLineNumberTable",
+                "params": {"isolateId": 0, "libraryId": 0, "url": ""}};
+  }
+
+  void send(Debugger debugger) {
+    assert(debugger.scriptUrl != null);
+    template["params"]["url"] = debugger.scriptUrl;
+    template["params"]["libraryId"] = debugger.libraryId;
+    debugger.sendMessage(template);
+  }
+
+  void matchResponse(Debugger debugger) {
+    super.matchResponse(debugger);
+    List<List<int>> table = getJsonValue(debugger.currentMessage, "result:lines");
+    debugger.tokenToLine = {};
+    for (var line in table) {
+      // Each entry begins with a line number...
+      var lineNumber = line[0];
+      for (var pos = 1; pos < line.length; pos += 2) {
+        // ...and is followed by (token offset, col number) pairs.
+        var tokenOffset = line[pos];
+        debugger.tokenToLine[tokenOffset] = lineNumber;
+      }
+    }
+  }
+}
+
+
+class LineMatcher extends Command {
+  int expectedLineNumber;
+
+  LineMatcher(this.expectedLineNumber) {
+    template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}};
+  }
+
+  void matchResponse(Debugger debugger) {
+    assert(debugger.tokenToLine != null);
+    super.matchResponse(debugger);
+    var msg = debugger.currentMessage;
+    List frames = getJsonValue(msg, "result:callFrames");
+    assert(frames != null);
+    var tokenOffset = frames[0]["location"]["tokenOffset"];
+    assert(tokenOffset != null);
+    var lineNumber = debugger.tokenToLine[tokenOffset];
+    assert(lineNumber != null);
+    if (expectedLineNumber != lineNumber) {
+      debugger.error("Error: expected pause at line $expectedLineNumber "
+                     "but reported line is $lineNumber.");
+      return;
+    }
+    print("Matched line number $lineNumber");
+  }
+}
+
+MatchLine(lineNumber) {
+  return new LineMatcher(lineNumber);
+}
+
 
 class FrameMatcher extends Command {
   int frameIndex;
@@ -201,6 +262,8 @@
         // Extract script url of debugged script.
         debugger.scriptUrl = frames[0]["location"]["url"];
         assert(debugger.scriptUrl != null);
+        debugger.libraryId = frames[0]["location"]["libraryId"];
+        assert(debugger.libraryId != null);
       }
     }
     if (frames.length < functionNames.length) {
@@ -220,6 +283,7 @@
         return;
       }
     }
+    print("Matched frames: $functionNames");
   }
 }
 
@@ -264,6 +328,7 @@
         return;
       }
     }
+    print("Matched locals ${locals.keys}");
   }
 }
 
@@ -318,6 +383,10 @@
     debugger.sendMessage(template);
     debugger.isPaused = false;
   }
+  void matchResponse(Debugger debugger) {
+    super.matchResponse(debugger);
+    print("Command: ${template['command']}");
+  }
 }
 
 
@@ -342,6 +411,11 @@
     template["params"]["line"] = line;
     debugger.sendMessage(template);
   }
+
+  void matchResponse(Debugger debugger) {
+    super.matchResponse(debugger);
+    print("Set breakpoint at line $line");
+  }
 }
 
 SetBreakpoint(int line) => new SetBreakpointCommand(line);
@@ -362,6 +436,7 @@
   List entries;
   DebugScript(List scriptEntries) {
     entries = new List.from(scriptEntries.reversed);
+    entries.add(new GetLineTableCmd());
     entries.add(MatchFrame(0, "main"));
   }
   bool get isEmpty => entries.isEmpty;
@@ -388,6 +463,8 @@
   // Data collected from debug target.
   Map currentMessage = null;  // Currently handled message sent by target.
   String scriptUrl = null;
+  int libraryId = null;
+  Map<int,int> tokenToLine = null;
   bool shutdownEventSeen = false;
   int isolateId = 0;
   bool isPaused = false;
diff --git a/tests/standalone/debugger/step_in_equals_test.dart b/tests/standalone/debugger/step_in_equals_test.dart
deleted file mode 100644
index c99f416..0000000
--- a/tests/standalone/debugger/step_in_equals_test.dart
+++ /dev/null
@@ -1,59 +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.
-
-import "debug_lib.dart";
-
-class MyClass {
-  operator ==(other) {
-    print(other);
-    return true;  // Breakpoint #3.
-  }
-}
-
-main(List<String> arguments) {
-  if (RunScript(testScript, arguments)) return;
-  var a = new MyClass();
-  var b = null;
-  var x = a == b;  // Breakpoint #1.
-  print(x);
-  b = 123;
-  a == b;  // Breakpoint #2.
-  print("after 2");
-  if (a == null) {  // Breakpoint #4.
-    throw "unreachable";
-  }
-  print("after 4");
-  if (null == a) {
-    throw "unreachable";
-  }
-  print("ok");
-}
-
-var testScript = [
-  MatchFrames(["main"]),
-  SetBreakpoint(18),
-  SetBreakpoint(21),
-  SetBreakpoint(10),
-  SetBreakpoint(23),
-  Resume(),
-  MatchFrames(["main"]),  // At breakpoint #1.
-  StepInto(),
-  MatchFrames(["main"]),  // Don't step into == method because of null.
-  Resume(),
-  MatchFrames(["main"]), // At breakpoint #2.
-  StepInto(),
-  StepInto(),
-  MatchFrames(["MyClass.==", "main"]),  // At MyClass.== entry.
-  Resume(),
-  MatchFrames(["MyClass.==", "main"]),  // At breakpoint #3.
-  Resume(),
-  MatchFrames(["main"]), // At breakpoint #4.
-  StepInto(),
-  MatchFrames(["main"]), // After breakpoint #4.
-  Step(),
-  MatchFrames(["main"]), // At null == a.
-  StepInto(),
-  MatchFrames(["main"]), // After null == a.
-  Resume()
-];
diff --git a/tests/standalone/io/http_requested_uri_test.dart b/tests/standalone/io/http_requested_uri_test.dart
new file mode 100644
index 0000000..f573c03
--- /dev/null
+++ b/tests/standalone/io/http_requested_uri_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:async";
+import "dart:io";
+
+const PATH = '/path?a=b#c';
+
+void test(String expected, Map headers) {
+  asyncStart();
+  HttpServer.bind("localhost", 0).then((server) {
+    expected = expected.replaceAll('%PORT', server.port.toString());
+    server.listen((request) {
+      Expect.equals("$expected$PATH",
+                    request.requestedUri.toString());
+      request.response.close();
+    });
+    HttpClient client = new HttpClient();
+    client.get("localhost", server.port, PATH)
+      .then((request) {
+        for (var v in headers.keys) {
+          if (headers[v] != null) {
+            request.headers.set(v, headers[v]);
+          } else {
+            request.headers.removeAll(v);
+          }
+        }
+        return request.close();
+      })
+      .then((response) => response.drain())
+      .then((_) {
+        server.close();
+        asyncEnd();
+      });
+  });
+}
+
+
+void main() {
+  test('http://localhost:%PORT', {});
+  test('https://localhost:%PORT', {'x-forwarded-proto': 'https'});
+  test('ws://localhost:%PORT', {'x-forwarded-proto': 'ws'});
+  test('http://my-host:321', {'x-forwarded-host': 'my-host:321'});
+  test('http://localhost:%PORT', {'host': null});
+}
+
diff --git a/tests/standalone/io/http_server_response_test.dart b/tests/standalone/io/http_server_response_test.dart
index 3c5767e..baef9ba 100644
--- a/tests/standalone/io/http_server_response_test.dart
+++ b/tests/standalone/io/http_server_response_test.dart
@@ -288,6 +288,18 @@
 }
 
 
+void testWriteCharCode() {
+  testServerRequest((server, request) {
+    // Test that default is latin-1 (only 2 bytes).
+    request.response.writeCharCode(0xFF);
+    request.response.writeCharCode(0xFF);
+    request.response.close().then((_) {
+      server.close();
+    });
+  }, bytes: 2);
+}
+
+
 void main() {
   testResponseDone();
   testResponseAddStream();
@@ -297,4 +309,5 @@
   testBadResponseClose();
   testIgnoreRequestData();
   testBadHeaders();
+  testWriteCharCode();
 }
diff --git a/tests/standalone/io/link_test.dart b/tests/standalone/io/link_test.dart
index 279c0c8..6b409dc 100644
--- a/tests/standalone/io/link_test.dart
+++ b/tests/standalone/io/link_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
 import "package:path/path.dart";
 import "dart:async";
@@ -11,6 +12,7 @@
 // Test the dart:io Link class.
 
 testCreateSync() {
+  asyncStart();
   String base = Directory.systemTemp.createTempSync('dart_link').path;
   if (isRelative(base)) {
     Expect.fail(
@@ -20,10 +22,7 @@
   String link = join(base, 'link');
   String target = join(base, 'target');
   new Directory(target).createSync();
-  print("link: $link");
-  print("target: $target");
   new Link(link).createSync(target);
-  return;
   Expect.equals(FileSystemEntityType.DIRECTORY,
                 FileSystemEntity.typeSync(link));
   Expect.equals(FileSystemEntityType.DIRECTORY,
@@ -150,10 +149,12 @@
       }
     }
     baseDir.deleteSync(recursive: true);
+    asyncEnd();
   });
 }
 
 testCreateLoopingLink() {
+  asyncStart();
   String base = Directory.systemTemp.createTempSync('dart_link').path;
   new Directory(join(base, 'a', 'b', 'c')).create(recursive: true)
     .then((_) =>
@@ -174,8 +175,10 @@
         new Directory(join(base, 'a', 'b', 'c'))
         .list(recursive: true, followLinks: true)
         .last)
-    .then((_) =>
-        new Directory(base).delete(recursive: true));
+    .whenComplete(() {
+      new Directory(base).deleteSync(recursive: true);
+      asyncEnd();
+    });
 }
 
 testRenameSync() {
diff --git a/tests/standalone/io/process_environment_test.dart b/tests/standalone/io/process_environment_test.dart
index 4376aab..2eb4111 100644
--- a/tests/standalone/io/process_environment_test.dart
+++ b/tests/standalone/io/process_environment_test.dart
@@ -65,6 +65,7 @@
   asyncStart();
   var env = Platform.environment;
   Expect.isTrue(env.containsKey('PATH'));
+  env = new Map.from(env);
   env.remove('PATH');
   runEnvironmentProcess(env, "PATH", false, (output) {
     Expect.isTrue(output.startsWith("null"));
diff --git a/tools/VERSION b/tools/VERSION
index f4e2ca5..607c5c1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL dev
 MAJOR 1
-MINOR 1
+MINOR 2
 PATCH 0
-PRERELEASE 5
-PRERELEASE_PATCH 11
+PRERELEASE 1
+PRERELEASE_PATCH 0
diff --git a/tools/bots/pub.py b/tools/bots/pub.py
index 2d852d8..12c73c9 100755
--- a/tools/bots/pub.py
+++ b/tools/bots/pub.py
@@ -41,8 +41,17 @@
     print 'Building package-root: %s' % (' '.join(args))
     bot.RunProcess(args)
 
-  bot.RunTest('pub', build_info, ['pub', 'pkg', 'dartdoc', 'docs'])
+  bot.RunTest('pub', build_info, ['--write-test-outcome-log',
+      'pub', 'pkg', 'dartdoc', 'docs'])
 
+  pkgbuild_build_info = bot.BuildInfo('none', 'vm', 'release',
+      build_info.system, checked=False)
+  bot.RunTest('pkgbuild_repo_pkgs', pkgbuild_build_info,
+      ['--append_logs', '--write-test-outcome-log',
+       '--use-repository-packages', 'pkgbuild'])
+  bot.RunTest('pkgbuild_public_pkgs', pkgbuild_build_info,
+      ['--append_logs', '--write-test-outcome-log',
+       '--use-public-packages', 'pkgbuild'])
 
 if __name__ == '__main__':
   bot.RunBot(PubConfig, PubSteps)
diff --git a/tools/build.py b/tools/build.py
index e9134bb..1e83352 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -198,7 +198,7 @@
   process = subprocess.Popen(args)
   process.wait()
   if process.returncode != 0:
-    raise Exception(args[0] + " failed")  
+    raise Exception(args[0] + " failed")
 
 
 def CurrentDirectoryBaseName():
@@ -215,11 +215,12 @@
 Build settings from command line:
     SYMROOT = .../xcodebuild
 
-=== BUILD AGGREGATE TARGET samples OF PROJECT dart WITH CONFIGURATION ...
+=== BUILD TARGET samples OF PROJECT dart WITH CONFIGURATION ...
+
 Check dependencies
 
-
 === BUILD AGGREGATE TARGET upload_sdk OF PROJECT dart WITH CONFIGURATION ...
+
 Check dependencies
 
 PhaseScriptExecution "Action \"upload_sdk_py\"" xcodebuild/dart.build/...
@@ -232,7 +233,7 @@
   """
 
   def is_empty_chunk(chunk):
-    empty_chunk = ['Check dependencies', '', '']
+    empty_chunk = ['', 'Check dependencies', '']
     return not chunk or (len(chunk) == 4 and chunk[1:] == empty_chunk)
 
   def unbuffered(callable):
@@ -258,7 +259,7 @@
       is_fancy_tty = False
     except AttributeError:
       is_fancy_tty = False
-  pattern = re.compile(r'=== BUILD .* TARGET (.*) OF PROJECT (.*) WITH ' +
+  pattern = re.compile(r'=== BUILD.* TARGET (.*) OF PROJECT (.*) WITH ' +
                        r'CONFIGURATION (.*) ===')
   has_interesting_info = False
   for line in unbuffered(process.stdout.readline):
@@ -288,9 +289,11 @@
       print line
     else:
       length = len(chunk)
-      if length == 1 and line != 'Check dependencies':
+      if length == 2 and line != 'Check dependencies':
         has_interesting_info = True
-      elif (length == 2 or length == 3) and line:
+      elif (length == 1 or length == 3) and line:
+        has_interesting_info = True
+      elif length > 3:
         has_interesting_info = True
       if has_interesting_info:
         print '\n'.join(chunk)
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 5261e71..f32d552 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -30,10 +30,10 @@
 # ......_internal/
 # ......async/
 # ......collection/
-# ......_collection_dev/
 # ......convert/
 # ......core/
 # ......html/
+# ......internal/
 # ......io/
 # ......isolate/
 # ......js/
@@ -196,8 +196,8 @@
                   join('_internal', 'compiler'),
                   join('_internal', 'dartdoc'),
                   join('_internal', 'lib'),
-                  'async', 'collection', '_collection_dev', 'convert',
-                  'core', 'crypto', 'io', 'isolate',
+                  'async', 'collection', 'convert', 'core',
+                  'crypto', 'internal', 'io', 'isolate',
                   join('html', 'dart2js'), join('html', 'dartium'),
                   join('html', 'html_common'),
                   join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index 13f2307..20aff36 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -682,6 +682,9 @@
       "delete": {
         "support_level": "untriaged"
       },
+      "forEach": {
+        "support_level": "untriaged"
+      },
       "get": {
         "support_level": "untriaged"
       },
@@ -697,6 +700,10 @@
     },
     "support_level": "untriaged"
   },
+  "CSSVariablesMapForEachCallback": {
+    "members": {},
+    "support_level": "untriaged"
+  },
   "CSSViewportRule": {
     "members": {
       "style": {
@@ -759,6 +766,9 @@
         "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects",
         "support_level": "experimental"
       },
+      "currentTransform": {
+        "support_level": "untriaged"
+      },
       "drawCustomFocusRing": {
         "support_level": "untriaged"
       },
@@ -1786,6 +1796,12 @@
       "onbeforecut": {},
       "onbeforepaste": {},
       "onblur": {},
+      "oncanplay": {
+        "support_level": "untriaged"
+      },
+      "oncanplaythrough": {
+        "support_level": "untriaged"
+      },
       "onchange": {},
       "onclick": {},
       "oncontextmenu": {},
@@ -1802,6 +1818,15 @@
       "ondragover": {},
       "ondragstart": {},
       "ondrop": {},
+      "ondurationchange": {
+        "support_level": "untriaged"
+      },
+      "onemptied": {
+        "support_level": "untriaged"
+      },
+      "onended": {
+        "support_level": "untriaged"
+      },
       "onerror": {},
       "onfocus": {},
       "onfullscreenchange": {
@@ -1818,6 +1843,12 @@
       "onkeypress": {},
       "onkeyup": {},
       "onload": {},
+      "onloadeddata": {
+        "support_level": "untriaged"
+      },
+      "onloadedmetadata": {
+        "support_level": "untriaged"
+      },
       "onmousedown": {},
       "onmouseenter": {
         "support_level": "untriaged"
@@ -1831,12 +1862,24 @@
       "onmouseup": {},
       "onmousewheel": {},
       "onpaste": {},
+      "onpause": {
+        "support_level": "untriaged"
+      },
+      "onplay": {
+        "support_level": "untriaged"
+      },
+      "onplaying": {
+        "support_level": "untriaged"
+      },
       "onpointerlockchange": {
         "support_level": "untriaged"
       },
       "onpointerlockerror": {
         "support_level": "untriaged"
       },
+      "onratechange": {
+        "support_level": "untriaged"
+      },
       "onreadystatechange": {},
       "onreset": {},
       "onscroll": {},
@@ -1848,10 +1891,25 @@
         "comment": "https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation",
         "support_level": "experimental"
       },
+      "onseeked": {
+        "support_level": "untriaged"
+      },
+      "onseeking": {
+        "support_level": "untriaged"
+      },
       "onselect": {},
       "onselectionchange": {},
       "onselectstart": {},
+      "onstalled": {
+        "support_level": "untriaged"
+      },
       "onsubmit": {},
+      "onsuspend": {
+        "support_level": "untriaged"
+      },
+      "ontimeupdate": {
+        "support_level": "untriaged"
+      },
       "ontouchcancel": {
         "comment": "http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features",
         "support_level": "experimental"
@@ -1868,6 +1926,12 @@
         "comment": "http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features",
         "support_level": "experimental"
       },
+      "onvolumechange": {
+        "support_level": "untriaged"
+      },
+      "onwaiting": {
+        "support_level": "untriaged"
+      },
       "onwebkitfullscreenchange": {
         "comment": "https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html",
         "support_level": "experimental"
@@ -2196,6 +2260,12 @@
       "onbeforecut": {},
       "onbeforepaste": {},
       "onblur": {},
+      "oncanplay": {
+        "support_level": "untriaged"
+      },
+      "oncanplaythrough": {
+        "support_level": "untriaged"
+      },
       "onchange": {},
       "onclick": {},
       "oncontextmenu": {},
@@ -2212,6 +2282,15 @@
       "ondragover": {},
       "ondragstart": {},
       "ondrop": {},
+      "ondurationchange": {
+        "support_level": "untriaged"
+      },
+      "onemptied": {
+        "support_level": "untriaged"
+      },
+      "onended": {
+        "support_level": "untriaged"
+      },
       "onerror": {},
       "onfocus": {},
       "onfullscreenchange": {
@@ -2228,6 +2307,12 @@
       "onkeypress": {},
       "onkeyup": {},
       "onload": {},
+      "onloadeddata": {
+        "support_level": "untriaged"
+      },
+      "onloadedmetadata": {
+        "support_level": "untriaged"
+      },
       "onmousedown": {},
       "onmouseenter": {
         "support_level": "untriaged"
@@ -2244,18 +2329,45 @@
         "support_level": "nonstandard"
       },
       "onpaste": {},
+      "onpause": {
+        "support_level": "untriaged"
+      },
+      "onplay": {
+        "support_level": "untriaged"
+      },
+      "onplaying": {
+        "support_level": "untriaged"
+      },
+      "onratechange": {
+        "support_level": "untriaged"
+      },
       "onreset": {},
       "onscroll": {},
       "onsearch": {
         "comment": "http://www.w3.org/TR/html-markup/input.search.html",
         "support_level": "experimental"
       },
+      "onseeked": {
+        "support_level": "untriaged"
+      },
+      "onseeking": {
+        "support_level": "untriaged"
+      },
       "onselect": {},
       "onselectstart": {
         "dart_action": "experimental",
         "support_level": "nonstandard"
       },
+      "onstalled": {
+        "support_level": "untriaged"
+      },
       "onsubmit": {},
+      "onsuspend": {
+        "support_level": "untriaged"
+      },
+      "ontimeupdate": {
+        "support_level": "untriaged"
+      },
       "ontouchcancel": {
         "comment": "http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features",
         "support_level": "experimental"
@@ -2281,6 +2393,12 @@
         "support_level": "experimental"
       },
       "ontransitionend": {},
+      "onvolumechange": {
+        "support_level": "untriaged"
+      },
+      "onwaiting": {
+        "support_level": "untriaged"
+      },
       "onwebkitTransitionEnd": {
         "support_level": "deprecated"
       },
@@ -3034,6 +3152,167 @@
     },
     "support_level": "stable"
   },
+  "GlobalEventHandlers": {
+    "members": {
+      "onabort": {
+        "support_level": "untriaged"
+      },
+      "onblur": {
+        "support_level": "untriaged"
+      },
+      "oncanplay": {
+        "support_level": "untriaged"
+      },
+      "oncanplaythrough": {
+        "support_level": "untriaged"
+      },
+      "onchange": {
+        "support_level": "untriaged"
+      },
+      "onclick": {
+        "support_level": "untriaged"
+      },
+      "oncontextmenu": {
+        "support_level": "untriaged"
+      },
+      "ondblclick": {
+        "support_level": "untriaged"
+      },
+      "ondoubleclick": {
+        "support_level": "untriaged"
+      },
+      "ondrag": {
+        "support_level": "untriaged"
+      },
+      "ondragend": {
+        "support_level": "untriaged"
+      },
+      "ondragenter": {
+        "support_level": "untriaged"
+      },
+      "ondragleave": {
+        "support_level": "untriaged"
+      },
+      "ondragover": {
+        "support_level": "untriaged"
+      },
+      "ondragstart": {
+        "support_level": "untriaged"
+      },
+      "ondrop": {
+        "support_level": "untriaged"
+      },
+      "ondurationchange": {
+        "support_level": "untriaged"
+      },
+      "onemptied": {
+        "support_level": "untriaged"
+      },
+      "onended": {
+        "support_level": "untriaged"
+      },
+      "onerror": {
+        "support_level": "untriaged"
+      },
+      "onfocus": {
+        "support_level": "untriaged"
+      },
+      "oninput": {
+        "support_level": "untriaged"
+      },
+      "oninvalid": {
+        "support_level": "untriaged"
+      },
+      "onkeydown": {
+        "support_level": "untriaged"
+      },
+      "onkeypress": {
+        "support_level": "untriaged"
+      },
+      "onkeyup": {
+        "support_level": "untriaged"
+      },
+      "onload": {
+        "support_level": "untriaged"
+      },
+      "onloadeddata": {
+        "support_level": "untriaged"
+      },
+      "onloadedmetadata": {
+        "support_level": "untriaged"
+      },
+      "onmousedown": {
+        "support_level": "untriaged"
+      },
+      "onmouseenter": {
+        "support_level": "untriaged"
+      },
+      "onmouseleave": {
+        "support_level": "untriaged"
+      },
+      "onmousemove": {
+        "support_level": "untriaged"
+      },
+      "onmouseout": {
+        "support_level": "untriaged"
+      },
+      "onmouseover": {
+        "support_level": "untriaged"
+      },
+      "onmouseup": {
+        "support_level": "untriaged"
+      },
+      "onmousewheel": {
+        "support_level": "untriaged"
+      },
+      "onpause": {
+        "support_level": "untriaged"
+      },
+      "onplay": {
+        "support_level": "untriaged"
+      },
+      "onplaying": {
+        "support_level": "untriaged"
+      },
+      "onratechange": {
+        "support_level": "untriaged"
+      },
+      "onreset": {
+        "support_level": "untriaged"
+      },
+      "onscroll": {
+        "support_level": "untriaged"
+      },
+      "onseeked": {
+        "support_level": "untriaged"
+      },
+      "onseeking": {
+        "support_level": "untriaged"
+      },
+      "onselect": {
+        "support_level": "untriaged"
+      },
+      "onstalled": {
+        "support_level": "untriaged"
+      },
+      "onsubmit": {
+        "support_level": "untriaged"
+      },
+      "onsuspend": {
+        "support_level": "untriaged"
+      },
+      "ontimeupdate": {
+        "support_level": "untriaged"
+      },
+      "onvolumechange": {
+        "support_level": "untriaged"
+      },
+      "onwaiting": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
   "HTMLAllCollection": {
     "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all",
     "dart_action": "suppress",
@@ -3078,6 +3357,9 @@
         "dart_action": "suppress",
         "support_level": "nonstandard"
       },
+      "password": {
+        "support_level": "untriaged"
+      },
       "pathname": {},
       "ping": {
         "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-a-element",
@@ -3101,7 +3383,10 @@
       "target": {},
       "text": {},
       "toString": {},
-      "type": {}
+      "type": {},
+      "username": {
+        "support_level": "untriaged"
+      }
     },
     "support_level": "stable"
   },
@@ -3138,6 +3423,12 @@
         "dart_action": "suppress",
         "support_level": "deprecated"
       },
+      "origin": {
+        "support_level": "untriaged"
+      },
+      "password": {
+        "support_level": "untriaged"
+      },
       "pathname": {},
       "ping": {
         "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#HTMLAreaElement-partial",
@@ -3148,7 +3439,13 @@
       "protocol": {},
       "search": {},
       "shape": {},
-      "target": {}
+      "target": {},
+      "toString": {
+        "support_level": "untriaged"
+      },
+      "username": {
+        "support_level": "untriaged"
+      }
     },
     "support_level": "stable"
   },
@@ -3225,6 +3522,9 @@
       "ononline": {},
       "onpopstate": {},
       "onresize": {},
+      "onscroll": {
+        "support_level": "untriaged"
+      },
       "onstorage": {},
       "onunload": {},
       "text": {
@@ -3477,6 +3777,162 @@
       },
       "isContentEditable": {},
       "lang": {},
+      "onabort": {
+        "support_level": "untriaged"
+      },
+      "onblur": {
+        "support_level": "untriaged"
+      },
+      "oncanplay": {
+        "support_level": "untriaged"
+      },
+      "oncanplaythrough": {
+        "support_level": "untriaged"
+      },
+      "onchange": {
+        "support_level": "untriaged"
+      },
+      "onclick": {
+        "support_level": "untriaged"
+      },
+      "oncontextmenu": {
+        "support_level": "untriaged"
+      },
+      "ondblclick": {
+        "support_level": "untriaged"
+      },
+      "ondoubleclick": {
+        "support_level": "untriaged"
+      },
+      "ondrag": {
+        "support_level": "untriaged"
+      },
+      "ondragend": {
+        "support_level": "untriaged"
+      },
+      "ondragenter": {
+        "support_level": "untriaged"
+      },
+      "ondragleave": {
+        "support_level": "untriaged"
+      },
+      "ondragover": {
+        "support_level": "untriaged"
+      },
+      "ondragstart": {
+        "support_level": "untriaged"
+      },
+      "ondrop": {
+        "support_level": "untriaged"
+      },
+      "ondurationchange": {
+        "support_level": "untriaged"
+      },
+      "onemptied": {
+        "support_level": "untriaged"
+      },
+      "onended": {
+        "support_level": "untriaged"
+      },
+      "onerror": {
+        "support_level": "untriaged"
+      },
+      "onfocus": {
+        "support_level": "untriaged"
+      },
+      "oninput": {
+        "support_level": "untriaged"
+      },
+      "oninvalid": {
+        "support_level": "untriaged"
+      },
+      "onkeydown": {
+        "support_level": "untriaged"
+      },
+      "onkeypress": {
+        "support_level": "untriaged"
+      },
+      "onkeyup": {
+        "support_level": "untriaged"
+      },
+      "onload": {
+        "support_level": "untriaged"
+      },
+      "onloadeddata": {
+        "support_level": "untriaged"
+      },
+      "onloadedmetadata": {
+        "support_level": "untriaged"
+      },
+      "onmousedown": {
+        "support_level": "untriaged"
+      },
+      "onmouseenter": {
+        "support_level": "untriaged"
+      },
+      "onmouseleave": {
+        "support_level": "untriaged"
+      },
+      "onmousemove": {
+        "support_level": "untriaged"
+      },
+      "onmouseout": {
+        "support_level": "untriaged"
+      },
+      "onmouseover": {
+        "support_level": "untriaged"
+      },
+      "onmouseup": {
+        "support_level": "untriaged"
+      },
+      "onmousewheel": {
+        "support_level": "untriaged"
+      },
+      "onpause": {
+        "support_level": "untriaged"
+      },
+      "onplay": {
+        "support_level": "untriaged"
+      },
+      "onplaying": {
+        "support_level": "untriaged"
+      },
+      "onratechange": {
+        "support_level": "untriaged"
+      },
+      "onreset": {
+        "support_level": "untriaged"
+      },
+      "onscroll": {
+        "support_level": "untriaged"
+      },
+      "onseeked": {
+        "support_level": "untriaged"
+      },
+      "onseeking": {
+        "support_level": "untriaged"
+      },
+      "onselect": {
+        "support_level": "untriaged"
+      },
+      "onstalled": {
+        "support_level": "untriaged"
+      },
+      "onsubmit": {
+        "support_level": "untriaged"
+      },
+      "onsuspend": {
+        "support_level": "untriaged"
+      },
+      "ontimeupdate": {
+        "support_level": "untriaged"
+      },
+      "onvolumechange": {
+        "support_level": "untriaged"
+      },
+      "onwaiting": {
+        "support_level": "untriaged"
+      },
       "outerHTML": {},
       "outerText": {
         "dart_action": "suppress",
@@ -4558,6 +5014,9 @@
     "comment": "https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-element",
     "members": {
       "HTMLShadowElement": {},
+      "getDistributedNodes": {
+        "support_level": "untriaged"
+      },
       "olderShadowRoot": {},
       "resetStyleInheritance": {}
     },
@@ -4944,6 +5403,9 @@
     "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#the-video-element",
     "members": {
       "HTMLVideoElement": {},
+      "getVideoPlaybackQuality": {
+        "support_level": "untriaged"
+      },
       "height": {},
       "poster": {},
       "videoHeight": {},
@@ -5160,6 +5622,9 @@
       "keyPath": {},
       "name": {},
       "openCursor": {},
+      "openKeyCursor": {
+        "support_level": "untriaged"
+      },
       "put": {},
       "transaction": {}
     },
@@ -5222,6 +5687,9 @@
       "dataLoss": {
         "support_level": "untriaged"
       },
+      "dataLossMessage": {
+        "support_level": "untriaged"
+      },
       "newVersion": {},
       "oldVersion": {}
     },
@@ -5254,11 +5722,20 @@
   "InputMethodContext": {
     "comment": "http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext",
     "members": {
+      "addEventListener": {
+        "support_level": "untriaged"
+      },
       "composition": {},
       "confirmComposition": {},
+      "dispatchEvent": {
+        "support_level": "untriaged"
+      },
       "enabled": {},
       "locale": {},
       "open": {},
+      "removeEventListener": {
+        "support_level": "untriaged"
+      },
       "setCaretRectangle": {},
       "setExclusionRectangle": {},
       "target": {
@@ -5362,6 +5839,9 @@
         "support_level": "untriaged"
       },
       "metaKey": {},
+      "repeat": {
+        "support_level": "untriaged"
+      },
       "shiftKey": {}
     },
     "support_level": "stable"
@@ -5732,7 +6212,10 @@
       "onmute": {},
       "onunmute": {},
       "readyState": {},
-      "removeEventListener": {}
+      "removeEventListener": {},
+      "stop": {
+        "support_level": "untriaged"
+      }
     },
     "support_level": "experimental"
   },
@@ -5986,6 +6469,9 @@
       "language": {
         "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorlanguage"
       },
+      "maxTouchPoints": {
+        "support_level": "untriaged"
+      },
       "mimeTypes": {
         "dart_action": "experimental",
         "support_level": "nonstandard"
@@ -6803,12 +7289,21 @@
       "_any": {
         "support_level": "untriaged"
       },
+      "all": {
+        "support_level": "untriaged"
+      },
+      "cast": {
+        "support_level": "untriaged"
+      },
       "every": {
         "support_level": "untriaged"
       },
       "fulfill": {
         "support_level": "untriaged"
       },
+      "race": {
+        "support_level": "untriaged"
+      },
       "reject": {
         "support_level": "untriaged"
       },
@@ -7778,6 +8273,162 @@
         "support_level": "untriaged"
       },
       "id": {},
+      "onabort": {
+        "support_level": "untriaged"
+      },
+      "onblur": {
+        "support_level": "untriaged"
+      },
+      "oncanplay": {
+        "support_level": "untriaged"
+      },
+      "oncanplaythrough": {
+        "support_level": "untriaged"
+      },
+      "onchange": {
+        "support_level": "untriaged"
+      },
+      "onclick": {
+        "support_level": "untriaged"
+      },
+      "oncontextmenu": {
+        "support_level": "untriaged"
+      },
+      "ondblclick": {
+        "support_level": "untriaged"
+      },
+      "ondoubleclick": {
+        "support_level": "untriaged"
+      },
+      "ondrag": {
+        "support_level": "untriaged"
+      },
+      "ondragend": {
+        "support_level": "untriaged"
+      },
+      "ondragenter": {
+        "support_level": "untriaged"
+      },
+      "ondragleave": {
+        "support_level": "untriaged"
+      },
+      "ondragover": {
+        "support_level": "untriaged"
+      },
+      "ondragstart": {
+        "support_level": "untriaged"
+      },
+      "ondrop": {
+        "support_level": "untriaged"
+      },
+      "ondurationchange": {
+        "support_level": "untriaged"
+      },
+      "onemptied": {
+        "support_level": "untriaged"
+      },
+      "onended": {
+        "support_level": "untriaged"
+      },
+      "onerror": {
+        "support_level": "untriaged"
+      },
+      "onfocus": {
+        "support_level": "untriaged"
+      },
+      "oninput": {
+        "support_level": "untriaged"
+      },
+      "oninvalid": {
+        "support_level": "untriaged"
+      },
+      "onkeydown": {
+        "support_level": "untriaged"
+      },
+      "onkeypress": {
+        "support_level": "untriaged"
+      },
+      "onkeyup": {
+        "support_level": "untriaged"
+      },
+      "onload": {
+        "support_level": "untriaged"
+      },
+      "onloadeddata": {
+        "support_level": "untriaged"
+      },
+      "onloadedmetadata": {
+        "support_level": "untriaged"
+      },
+      "onmousedown": {
+        "support_level": "untriaged"
+      },
+      "onmouseenter": {
+        "support_level": "untriaged"
+      },
+      "onmouseleave": {
+        "support_level": "untriaged"
+      },
+      "onmousemove": {
+        "support_level": "untriaged"
+      },
+      "onmouseout": {
+        "support_level": "untriaged"
+      },
+      "onmouseover": {
+        "support_level": "untriaged"
+      },
+      "onmouseup": {
+        "support_level": "untriaged"
+      },
+      "onmousewheel": {
+        "support_level": "untriaged"
+      },
+      "onpause": {
+        "support_level": "untriaged"
+      },
+      "onplay": {
+        "support_level": "untriaged"
+      },
+      "onplaying": {
+        "support_level": "untriaged"
+      },
+      "onratechange": {
+        "support_level": "untriaged"
+      },
+      "onreset": {
+        "support_level": "untriaged"
+      },
+      "onscroll": {
+        "support_level": "untriaged"
+      },
+      "onseeked": {
+        "support_level": "untriaged"
+      },
+      "onseeking": {
+        "support_level": "untriaged"
+      },
+      "onselect": {
+        "support_level": "untriaged"
+      },
+      "onstalled": {
+        "support_level": "untriaged"
+      },
+      "onsubmit": {
+        "support_level": "untriaged"
+      },
+      "onsuspend": {
+        "support_level": "untriaged"
+      },
+      "ontimeupdate": {
+        "support_level": "untriaged"
+      },
+      "onvolumechange": {
+        "support_level": "untriaged"
+      },
+      "onwaiting": {
+        "support_level": "untriaged"
+      },
       "ownerSVGElement": {},
       "style": {
         "support_level": "untriaged"
@@ -8772,6 +9423,9 @@
       "getScreenCTM": {
         "support_level": "untriaged"
       },
+      "getStrokeBBox": {
+        "support_level": "untriaged"
+      },
       "getTransformToElement": {
         "support_level": "untriaged"
       },
@@ -10498,11 +11152,17 @@
       "getElementsByTagName": {},
       "getElementsByTagNameNS": {},
       "getSelection": {},
+      "host": {
+        "support_level": "untriaged"
+      },
       "innerHTML": {},
       "olderShadowRoot": {
         "support_level": "untriaged"
       },
-      "resetStyleInheritance": {}
+      "resetStyleInheritance": {},
+      "styleSheets": {
+        "support_level": "untriaged"
+      }
     },
     "support_level": "experimental"
   },
@@ -10728,11 +11388,20 @@
   "SpeechSynthesis": {
     "comment": "https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section",
     "members": {
+      "addEventListener": {
+        "support_level": "untriaged"
+      },
       "cancel": {},
+      "dispatchEvent": {
+        "support_level": "untriaged"
+      },
       "getVoices": {},
       "pause": {},
       "paused": {},
       "pending": {},
+      "removeEventListener": {
+        "support_level": "untriaged"
+      },
       "resume": {},
       "speak": {},
       "speaking": {}
@@ -10974,6 +11643,9 @@
       "activeCues": {},
       "addCue": {},
       "addEventListener": {},
+      "addRegion": {
+        "support_level": "untriaged"
+      },
       "cues": {},
       "dispatchEvent": {},
       "kind": {},
@@ -10981,8 +11653,14 @@
       "language": {},
       "mode": {},
       "oncuechange": {},
+      "regions": {
+        "support_level": "untriaged"
+      },
       "removeCue": {},
-      "removeEventListener": {}
+      "removeEventListener": {},
+      "removeRegion": {
+        "support_level": "untriaged"
+      }
     },
     "support_level": "experimental"
   },
@@ -11013,6 +11691,9 @@
         "dart_action": "experimental",
         "support_level": "nonstandard"
       },
+      "regionId": {
+        "support_level": "untriaged"
+      },
       "removeEventListener": {},
       "size": {
         "dart_action": "experimental",
@@ -11218,10 +11899,119 @@
       "createObjectUrlFromBlob": {},
       "createObjectUrlFromSource": {},
       "createObjectUrlFromStream": {},
-      "revokeObjectURL": {}
+      "hash": {
+        "support_level": "untriaged"
+      },
+      "host": {
+        "support_level": "untriaged"
+      },
+      "hostname": {
+        "support_level": "untriaged"
+      },
+      "href": {
+        "support_level": "untriaged"
+      },
+      "origin": {
+        "support_level": "untriaged"
+      },
+      "password": {
+        "support_level": "untriaged"
+      },
+      "pathname": {
+        "support_level": "untriaged"
+      },
+      "port": {
+        "support_level": "untriaged"
+      },
+      "protocol": {
+        "support_level": "untriaged"
+      },
+      "revokeObjectURL": {},
+      "search": {
+        "support_level": "untriaged"
+      },
+      "toString": {
+        "support_level": "untriaged"
+      },
+      "username": {
+        "support_level": "untriaged"
+      }
     },
     "support_level": "stable"
   },
+  "URLUtils": {
+    "members": {
+      "hash": {
+        "support_level": "untriaged"
+      },
+      "host": {
+        "support_level": "untriaged"
+      },
+      "hostname": {
+        "support_level": "untriaged"
+      },
+      "href": {
+        "support_level": "untriaged"
+      },
+      "origin": {
+        "support_level": "untriaged"
+      },
+      "password": {
+        "support_level": "untriaged"
+      },
+      "pathname": {
+        "support_level": "untriaged"
+      },
+      "port": {
+        "support_level": "untriaged"
+      },
+      "protocol": {
+        "support_level": "untriaged"
+      },
+      "search": {
+        "support_level": "untriaged"
+      },
+      "toString": {
+        "support_level": "untriaged"
+      },
+      "username": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
+  "URLUtilsReadOnly": {
+    "members": {
+      "hash": {
+        "support_level": "untriaged"
+      },
+      "host": {
+        "support_level": "untriaged"
+      },
+      "hostname": {
+        "support_level": "untriaged"
+      },
+      "href": {
+        "support_level": "untriaged"
+      },
+      "pathname": {
+        "support_level": "untriaged"
+      },
+      "port": {
+        "support_level": "untriaged"
+      },
+      "protocol": {
+        "support_level": "untriaged"
+      },
+      "search": {
+        "support_level": "untriaged"
+      },
+      "toString": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
   "Uint16Array": {
     "comment": "http://www.khronos.org/registry/typedarray/specs/latest/",
     "members": {
@@ -11261,6 +12051,53 @@
     },
     "support_level": "stable"
   },
+  "VTTRegion": {
+    "members": {
+      "VTTRegion": {},
+      "height": {
+        "support_level": "untriaged"
+      },
+      "id": {
+        "support_level": "untriaged"
+      },
+      "regionAnchorX": {
+        "support_level": "untriaged"
+      },
+      "regionAnchorY": {
+        "support_level": "untriaged"
+      },
+      "scroll": {
+        "support_level": "untriaged"
+      },
+      "track": {
+        "support_level": "untriaged"
+      },
+      "viewportAnchorX": {
+        "support_level": "untriaged"
+      },
+      "viewportAnchorY": {
+        "support_level": "untriaged"
+      },
+      "width": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
+  "VTTRegionList": {
+    "members": {
+      "getRegionById": {
+        "support_level": "untriaged"
+      },
+      "item": {
+        "support_level": "untriaged"
+      },
+      "length": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
   "ValidityState": {
     "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#validitystate",
     "members": {
@@ -11277,6 +12114,23 @@
     },
     "support_level": "stable"
   },
+  "VideoPlaybackQuality": {
+    "members": {
+      "corruptedVideoFrames": {
+        "support_level": "untriaged"
+      },
+      "creationTime": {
+        "support_level": "untriaged"
+      },
+      "droppedVideoFrames": {
+        "support_level": "untriaged"
+      },
+      "totalVideoFrames": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
   "VoidCallback": {
     "comment": "http://www.w3.org/TR/file-system-api/#the-voidcallback-interface",
     "members": {
@@ -12573,6 +13427,38 @@
     },
     "support_level": "untriaged"
   },
+  "WindowEventHandlers": {
+    "members": {
+      "onbeforeunload": {
+        "support_level": "untriaged"
+      },
+      "onhashchange": {
+        "support_level": "untriaged"
+      },
+      "onmessage": {
+        "support_level": "untriaged"
+      },
+      "onoffline": {
+        "support_level": "untriaged"
+      },
+      "ononline": {
+        "support_level": "untriaged"
+      },
+      "onpopstate": {
+        "support_level": "untriaged"
+      },
+      "onresize": {
+        "support_level": "untriaged"
+      },
+      "onstorage": {
+        "support_level": "untriaged"
+      },
+      "onunload": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
   "WindowTimers": {
     "members": {
       "clearInterval": {
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 726ae66..415b914 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -191,15 +191,15 @@
 // TODO(vsm): Define new names for these (see b/4436830).
 [Supplemental]
 interface IDBCursor {
-  [DartName=next, CallWith=ScriptExecutionContext, ImplementedAs=continueFunction, RaisesException] void continue([ForceOptional] optional any key);
+  [DartName=next, CallWith=ExecutionContext, ImplementedAs=continueFunction, RaisesException] void continue([ForceOptional] optional any key);
 };
 [Supplemental]
 interface IDBIndex {
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openCursor([Default=Undefined] optional any key, [ForceOptional] optional DOMString direction);
+    [CallWith=ExecutionContext, RaisesException] IDBRequest openCursor([Default=Undefined] optional any key, [ForceOptional] optional DOMString direction);
 
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openKeyCursor([Default=Undefined] optional any key, [ForceOptional] optional DOMString direction);
+    [CallWith=ExecutionContext, RaisesException] IDBRequest openKeyCursor([Default=Undefined] optional any key, [ForceOptional] optional DOMString direction);
 
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest count([Default=Undefined] optional any key);
+    [CallWith=ExecutionContext, RaisesException] IDBRequest count([Default=Undefined] optional any key);
 };
 
 [Supplemental]
@@ -219,9 +219,9 @@
 interface IDBObjectStore {
     [CallWith=ScriptState, RaisesException] IDBRequest put(any value, [ForceOptional] optional any key);
     [CallWith=ScriptState, RaisesException] IDBRequest add(any value, [ForceOptional] optional any key);
-    # [CallWith=ScriptExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest openCursor(any key, [ForceOptional] optional DOMString direction);
-    [CallWith=ScriptExecutionContext, RaisesException] IDBRequest count(any key);
+    # [CallWith=ExecutionContext, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key);
+    [CallWith=ExecutionContext, RaisesException] IDBRequest openCursor(any key, [ForceOptional] optional DOMString direction);
+    [CallWith=ExecutionContext, RaisesException] IDBRequest count(any key);
 };
 
 interface EntrySync {
@@ -359,3 +359,4 @@
 [Supplemental]
 interface Window : EventTarget {};
 
+Element implements GlobalEventHandlers;
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 93a2474..570255b 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -19,6 +19,7 @@
     'DOMStringMap',
     'ChildNode',
     'EventListener',
+    'GlobalEventHandlers',
     'MediaQueryListListener',
     'MutationCallback',
     'NavigatorID',
@@ -31,7 +32,10 @@
     'SVGURIReference',
     'SVGZoomAndPan',
     'TimeoutHandler',
+    'URLUtils',
+    'URLUtilsReadOnly',
     'WindowBase64',
+    'WindowEventHandlers',
     'WindowTimers',
     ])
 
@@ -194,6 +198,9 @@
   auto-transforming callbacks into futures)."""
   callback_handlers = [operation for operation in interface.operations
       if operation.id == 'handleEvent']
+  if callback_handlers == []:
+    callback_handlers = [operation for operation in interface.operations
+                         if operation.id == 'handleItem']
   return AnalyzeOperation(interface, callback_handlers)
 
 # Given a list of overloaded arguments, render dart arguments.
@@ -718,9 +725,12 @@
   def to_dart_conversion(self, value, interface_name=None, attributes=None):
     return 'Dart%s::toDart(%s)' % (self._idl_type, value)
 
-  def return_to_dart_conversion(self, value,
+  def return_to_dart_conversion(self, value, auto_dart_scope_setup,
                                 interface_name=None, attributes=None):
-    return 'Dart%s::returnToDart(args, %s)' % (self._idl_type, value)
+    auto_dart_scope='true' if auto_dart_scope_setup else 'false'
+    return 'Dart%s::returnToDart(args, %s, %s)' % (self._idl_type,
+                                                   value,
+                                                   auto_dart_scope)
 
   def custom_to_dart(self):
     return self._data.custom_to_dart
@@ -848,7 +858,7 @@
       return 'DartDOMWrapper::vectorToDart(%s)' % value
     return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.bindings_class(), value)
 
-  def return_to_dart_conversion(self, value,
+  def return_to_dart_conversion(self, value, auto_dart_scope_setup=True,
                                 interface_name=None, attributes=None):
     return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
         value,
@@ -915,7 +925,7 @@
       function_name += 'WithNullCheck'
     return '%s(%s)' % (function_name, value)
 
-  def return_to_dart_conversion(self, value,
+  def return_to_dart_conversion(self, value, auto_dart_scope_setup=True,
                                 interface_name=None, attributes=None):
     return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
         value,
@@ -970,12 +980,15 @@
   def to_dart_conversion(self, value, interface_name, attributes):
     return 'Dart%s::toDart(%s)' % (self._idl_type, self.to_conversion_cast(value, interface_name, attributes))
 
-  def return_to_dart_conversion(self, value, interface_name, attr):
-    return 'Dart%s::returnToDart(args, %s)' % (self._idl_type,
-                                               self.to_conversion_cast(
-                                                   value,
-                                                   interface_name,
-                                                   attr))
+  def return_to_dart_conversion(self, value, auto_dart_scope_setup,
+                                interface_name, attr):
+    auto_dart_scope='true' if auto_dart_scope_setup else 'false'
+    return 'Dart%s::returnToDart(args, %s, %s)' % (self._idl_type,
+                                                   self.to_conversion_cast(
+                                                       value,
+                                                       interface_name,
+                                                       attr),
+                                                   auto_dart_scope)
 
   def argument_expression(self, name, interface_name):
     return name if interface_name.endswith('List') else '%s->propertyReference()' % name
@@ -992,7 +1005,8 @@
   def to_dart_conversion(self, value, interface_name, attributes):
     return 'DartUtilities::arrayBufferViewToDart(%s)' % value
 
-  def return_to_dart_conversion(self, value, interface_name, attributes):
+  def return_to_dart_conversion(self, value, auto_dart_scope_setup,
+                                interface_name, attributes):
     return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
         value,
         interface_name,
@@ -1015,7 +1029,8 @@
     function_name = function_name[0].lower() + function_name[1:]
     return '%s(%s)' % (function_name, value)
 
-  def return_to_dart_conversion(self, value, interface_name, attributes):
+  def return_to_dart_conversion(self, value, auto_dart_scope_setup,
+                                interface_name, attributes):
     return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
         value,
         interface_name,
@@ -1172,7 +1187,7 @@
     'SVGPoint': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<FloatPoint>'),
     'SVGPointList': TypeData(clazz='SVGTearOff'),
     'SVGPreserveAspectRatio': TypeData(clazz='SVGTearOff'),
-    'SVGRect': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<FloatRect>'),
+    'SVGRect': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<SVGRect>'),
     'SVGStringList': TypeData(clazz='SVGTearOff', item_type='DOMString',
         native_type='SVGStaticListPropertyTearOff<SVGStringList>'),
     'SVGTransform': TypeData(clazz='SVGTearOff'),
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index 715d114..00979ab 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -382,7 +382,10 @@
     if self._renamer.ShouldSuppressMember(interface, event_name, 'on:'):
       return True
 
-    if interface.doc_js_name == 'Window':
+    if (interface.doc_js_name == 'Window' or
+        interface.doc_js_name == 'Element' or
+        interface.doc_js_name == 'Document' or
+        interface.doc_js_name == 'GlobalEventHandlers'):
       media_interface = self._database.GetInterface('HTMLMediaElement')
       media_events = self._GetEvents(media_interface, [])
       if self._HasEvent(media_events, event_name, event_type):
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index ab790a1..a8cc579 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -804,7 +804,7 @@
       return
 
     if IsPureInterface(self._interface.id):
-      self._AddInterfaceAttribute(attribute, html_name)
+      self._AddInterfaceAttribute(attribute, html_name, read_only)
       return
 
     # If the attribute is shadowing, we can't generate a shadowing
@@ -870,10 +870,11 @@
     if not read_only:
       self._AddRenamingSetter(attribute, html_name)
 
-  def _AddInterfaceAttribute(self, attribute, html_name):
+  def _AddInterfaceAttribute(self, attribute, html_name, read_only):
     self._members_emitter.Emit(
-        '\n  $TYPE $NAME;'
+        '\n  $QUALIFIER$TYPE $NAME;'
         '\n',
+        QUALIFIER='final ' if read_only else '',
         NAME=html_name,
         TYPE=self.SecureOutputType(attribute.type.id))
 
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 5c70a8c..c234928 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -17,6 +17,7 @@
 # an ugly workaround.
 _cpp_callback_map = {
   ('DataTransferItem', 'webkitGetAsEntry'): 'DataTransferItemFileSystem',
+  ('Document', 'fonts'): 'DocumentFontFaceSet',
   ('Document', 'webkitIsFullScreen'): 'DocumentFullscreen',
   ('Document', 'webkitFullScreenKeyboardInputAllowed'): 'DocumentFullscreen',
   ('Document', 'webkitCurrentFullScreenElement'): 'DocumentFullscreen',
@@ -39,6 +40,7 @@
   ('DOMWindow', 'clearInterval'): 'DOMWindowTimers',
   ('DOMWindow', 'createImageBitmap'): 'ImageBitmapFactories',
   ('HTMLInputElement', 'webkitEntries'): 'HTMLInputElementFileSystem',
+  ('HTMLVideoElement', 'getVideoPlaybackQuality'): 'HTMLVideoElementMediaSource',
   ('Navigator', 'doNotTrack'): 'NavigatorDoNotTrack',
   ('Navigator', 'geolocation'): 'NavigatorGeolocation',
   ('Navigator', 'webkitPersistentStorage'): 'NavigatorStorageQuota',
@@ -58,6 +60,7 @@
   ('Navigator', 'onLine'): 'NavigatorOnLine',
   ('Navigator', 'registerServiceWorker'): 'NavigatorServiceWorker',
   ('Navigator', 'unregisterServiceWorker'): 'NavigatorServiceWorker',
+  ('Navigator', 'maxTouchPoints'): 'NavigatorEvents',
   ('WorkerGlobalScope', 'crypto'): 'WorkerGlobalScopeCrypto',
   ('WorkerGlobalScope', 'indexedDB'): 'WorkerGlobalScopeIndexedDatabase',
   ('WorkerGlobalScope', 'webkitNotifications'): 'WorkerGlobalScopeNotifications',
@@ -90,16 +93,37 @@
 _cpp_partial_map = {}
 
 _cpp_no_auto_scope_list = set([
+  ('Document', 'body', 'Getter'),
+  ('Document', 'getElementById', 'Callback'),
+  ('Document', 'getElementsByName', 'Callback'),
+  ('Document', 'getElementsByTagName', 'Callback'),
+  ('Element', 'getAttribute', 'Callback'),
+  ('Element', 'getAttributeNS', 'Callback'),
+  ('Element', 'id', 'Getter'),
+  ('Element', 'id', 'Setter'),
+  ('Element', 'setAttribute', 'Callback'),
+  ('Element', 'setAttributeNS', 'Callback'),
   ('Node', 'firstChild', 'Getter'),
   ('Node', 'lastChild', 'Getter'),
   ('Node', 'nextSibling', 'Getter'),
   ('Node', 'previousSibling', 'Getter'),
   ('Node', 'childNodes', 'Getter'),
+  ('Node', 'nodeType', 'Getter'),
   ('NodeList', 'length', 'Getter'),
   ('NodeList', 'item', 'Callback'),
-  ('Document', 'body', 'Getter'),
 ])
 
+# TODO(vsm): This should be recoverable from IDL, but we appear to not
+# track the necessary info.
+_url_utils = ['hash', 'host', 'hostname', 'origin',
+              'password', 'pathname', 'port', 'protocol',
+              'search', 'username']
+_cpp_static_call_map = {
+  'DOMURL': _url_utils + ['href', 'toString'],
+  'HTMLAnchorElement': _url_utils,
+  'HTMLAreaElement': _url_utils,
+}
+
 def _GetCPPPartialNames(interface):
   interface_name = interface.ext_attrs.get('ImplementedAs', interface.id)
   if not _cpp_partial_map:
@@ -174,8 +198,11 @@
     cpp_impl_handlers_emitter = emitter.Emitter()
     class_name = 'Dart%s' % self._interface.id
     for operation in self._interface.operations:
+      function_name = operation.id
       parameters = []
       arguments = []
+      if operation.ext_attrs.get('CallWith') == 'ThisValue':
+        parameters.append('ScriptValue scriptValue')
       conversion_includes = []
       for argument in operation.arguments:
         argument_type_info = self._TypeInfo(argument.type.id)
@@ -184,9 +211,22 @@
         arguments.append(argument_type_info.to_dart_conversion(argument.id))
         conversion_includes.extend(argument_type_info.conversion_includes())
 
+      # FIXME(vsm): Handle ThisValue attribute.
+      if operation.ext_attrs.get('CallWith') == 'ThisValue':
+        cpp_header_handlers_emitter.Emit(
+            '\n'
+            '    virtual bool $FUNCTION($PARAMETERS) {\n'
+            '        DART_UNIMPLEMENTED();\n'
+            '        return false;\n'
+            '    }\n',
+            FUNCTION=function_name,
+            PARAMETERS=', '.join(parameters))
+        continue
+
       cpp_header_handlers_emitter.Emit(
           '\n'
-          '    virtual bool handleEvent($PARAMETERS);\n',
+          '    virtual bool $FUNCTION($PARAMETERS);\n',
+          FUNCTION=function_name,
           PARAMETERS=', '.join(parameters))
 
       if 'Custom' in operation.ext_attrs:
@@ -198,7 +238,7 @@
         arguments_declaration = 'Dart_Handle* arguments = 0'
       cpp_impl_handlers_emitter.Emit(
           '\n'
-          'bool $CLASS_NAME::handleEvent($PARAMETERS)\n'
+          'bool $CLASS_NAME::$FUNCTION($PARAMETERS)\n'
           '{\n'
           '    if (!m_callback.isIsolateAlive())\n'
           '        return false;\n'
@@ -208,6 +248,7 @@
           '    return m_callback.handleEvent($ARGUMENT_COUNT, arguments);\n'
           '}\n',
           CLASS_NAME=class_name,
+          FUNCTION=function_name,
           PARAMETERS=', '.join(parameters),
           ARGUMENTS_DECLARATION=arguments_declaration,
           ARGUMENT_COUNT=len(arguments))
@@ -352,7 +393,8 @@
         arguments,
         self._interface.id,
         False,
-        'ConstructorRaisesException' in ext_attrs or 'RaisesException' in ext_attrs)
+        'ConstructorRaisesException' in ext_attrs or 'RaisesException' in ext_attrs,
+        True)
 
   def HasSupportCheck(self):
     # Need to omit a support check if it is conditional in JS.
@@ -440,7 +482,8 @@
         '        return createWrapper(domData, value);\n'
         '    }\n'
         '    static void returnToDart(Dart_NativeArguments args,\n'
-        '                             NativeType* value)\n'
+        '                             NativeType* value,\n'
+        '                             bool autoDartScope = true)\n'
         '    {\n'
         '        if (value) {\n'
         '            DartDOMData* domData = static_cast<DartDOMData*>(\n'
@@ -450,8 +493,12 @@
         '            if (result)\n'
         '                Dart_SetWeakHandleReturnValue(args, result);\n'
         '            else {\n'
-        '                DartApiScope apiScope();\n'
-        '                Dart_SetReturnValue(args, createWrapper(domData, value));\n'
+        '                if (autoDartScope) {\n'
+        '                    Dart_SetReturnValue(args, createWrapper(domData, value));\n'
+        '                } else {\n'
+        '                    DartApiScope apiScope;\n'
+        '                    Dart_SetReturnValue(args, createWrapper(domData, value));\n'
+        '               }\n'
         '            }\n'
         '        }\n'
         '    }\n',
@@ -460,6 +507,7 @@
     if ('CustomToV8' in ext_attrs or
         'PureInterface' in ext_attrs or
         'CPPPureInterface' in ext_attrs or
+        'SpecialWrapFor' in ext_attrs or
         self._interface_type_info.custom_to_dart()):
       to_dart_emitter.Emit(
           '    static Dart_Handle createWrapper(DartDOMData* domData, NativeType* value);\n')
@@ -499,6 +547,9 @@
     if not read_only:
       self._AddSetter(attribute, html_name)
 
+  def _GenerateAutoSetupScope(self, idl_name, native_suffix):
+    return (self._interface.id, idl_name, native_suffix) not in _cpp_no_auto_scope_list
+
   def _AddGetter(self, attr, html_name, read_only):
     # Temporary hack to force dart:scalarlist clamped array for ImageData.data.
     # TODO(antonm): solve in principled way.
@@ -508,8 +559,10 @@
     dart_declaration = '%s get %s' % (
         self.SecureOutputType(attr.type.id, False, read_only), html_name)
     is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs
+    native_suffix = 'Getter'
+    auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
     cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
-        dart_declaration, 'Getter', is_custom)
+        dart_declaration, native_suffix, is_custom, auto_scope_setup)
     if is_custom:
       return
 
@@ -541,21 +594,24 @@
         [],
         attr.type.id,
         attr.type.nullable,
-        'GetterRaisesException' in attr.ext_attrs or 'RaisesException' in attr.ext_attrs)
+        'GetterRaisesException' in attr.ext_attrs or 'RaisesException' in attr.ext_attrs,
+        auto_scope_setup)
 
   def _AddSetter(self, attr, html_name):
     type_info = self._TypeInfo(attr.type.id)
     dart_declaration = 'void set %s(%s value)' % (html_name, self._DartType(attr.type.id))
     is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext_attrs)
+    native_suffix = 'Setter'
+    auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
     cpp_callback_name = self._GenerateNativeBinding(attr.id, 2,
-        dart_declaration, 'Setter', is_custom)
+        dart_declaration, native_suffix, is_custom, auto_scope_setup)
     if is_custom:
       return
 
     if 'Reflect' in attr.ext_attrs:
       webcore_function_name = self._TypeInfo(attr.type.id).webcore_setter_name()
     else:
-      webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)',
+      webcore_function_name = re.sub(r'^(xml|css|(?=[A-Z])|\w)',
                                      lambda s: s.group(1).upper(),
                                      attr.id)
       webcore_function_name = 'set%s' % webcore_function_name
@@ -570,6 +626,7 @@
         'void',
         False,
         'SetterRaisesException' in attr.ext_attrs,
+        auto_scope_setup,
         generate_custom_element_scope_if_needed=True)
 
   def AddIndexer(self, element_type):
@@ -642,7 +699,7 @@
     dart_declaration = '%s operator[](int index)' % \
         self.SecureOutputType(element_type, True)
     self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
-        'Callback', True)
+        'Callback', True, False)
 
   def _HasExplicitIndexedGetter(self):
     return any(op.id == 'getItem' for op in self._interface.operations)
@@ -667,7 +724,7 @@
   def _EmitNativeIndexSetter(self, element_type):
     dart_declaration = 'void operator[]=(int index, %s value)' % element_type
     self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
-        'Callback', True)
+        'Callback', True, False)
 
   def EmitOperation(self, info, html_name):
     """
@@ -691,10 +748,13 @@
     elif not needs_dispatcher:
       # Bind directly to native implementation
       argument_count = (0 if info.IsStatic() else 1) + len(info.param_infos)
+      native_suffix = 'Callback'
+      auto_scope_setup = self._GenerateAutoSetupScope(info.name, native_suffix)
       cpp_callback_name = self._GenerateNativeBinding(
-          info.name, argument_count, dart_declaration, 'Callback', is_custom)
+          info.name, argument_count, dart_declaration, native_suffix, is_custom,
+          auto_scope_setup)
       if not is_custom:
-        self._GenerateOperationNativeCallback(operation, operation.arguments, cpp_callback_name)
+        self._GenerateOperationNativeCallback(operation, operation.arguments, cpp_callback_name, auto_scope_setup)
     else:
       self._GenerateDispatcher(info, info.operations, dart_declaration)
 
@@ -712,11 +772,14 @@
           self.SecureOutputType(operation.type.id),
           overload_name, argument_list)
       is_custom = 'Custom' in operation.ext_attrs
+      native_suffix = 'Callback'
+      auto_scope_setup = self._GenerateAutoSetupScope(overload_name, native_suffix)
       cpp_callback_name = self._GenerateNativeBinding(
           overload_name, (0 if operation.is_static else 1) + argument_count,
-          dart_declaration, 'Callback', is_custom, emit_metadata=False)
+          dart_declaration, 'Callback', is_custom, auto_scope_setup,
+          emit_metadata=False)
       if not is_custom:
-        self._GenerateOperationNativeCallback(operation, operation.arguments[:argument_count], cpp_callback_name)
+        self._GenerateOperationNativeCallback(operation, operation.arguments[:argument_count], cpp_callback_name, auto_scope_setup)
 
     self._GenerateDispatcherBody(
         info,
@@ -728,7 +791,7 @@
   def SecondaryContext(self, interface):
     pass
 
-  def _GenerateOperationNativeCallback(self, operation, arguments, cpp_callback_name):
+  def _GenerateOperationNativeCallback(self, operation, arguments, cpp_callback_name, auto_scope_setup=True):
     webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.id)
     function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, operation, cpp_callback_name)
     self._GenerateNativeCallback(
@@ -740,6 +803,7 @@
         operation.type.id,
         operation.type.nullable,
         'RaisesException' in operation.ext_attrs,
+        auto_scope_setup,
         generate_custom_element_scope_if_needed=True)
 
   def _GenerateNativeCallback(self,
@@ -751,9 +815,12 @@
       return_type,
       return_type_is_nullable,
       raises_dom_exception,
+      auto_scope_setup=True,
       generate_custom_element_scope_if_needed=False):
 
     ext_attrs = node.ext_attrs
+    if self._IsStatic(node.id):
+      needs_receiver = True
 
     cpp_arguments = []
     runtime_check = None
@@ -782,8 +849,8 @@
       # it's not needed and should be just removed.
       arguments = arguments[:-1]
 
-    requires_script_execution_context = (ext_attrs.get('CallWith') == 'ScriptExecutionContext' or
-                                         ext_attrs.get('ConstructorCallWith') == 'ScriptExecutionContext')
+    requires_script_execution_context = (ext_attrs.get('CallWith') == 'ExecutionContext' or
+                                         ext_attrs.get('ConstructorCallWith') == 'ExecutionContext')
 
     requires_document = ext_attrs.get('ConstructorCallWith') == 'Document'
 
@@ -811,7 +878,7 @@
       cpp_arguments = [self._GenerateWebCoreReflectionAttributeName(node)]
 
     if generate_custom_element_scope_if_needed and (ext_attrs.get('CustomElementCallbacks', 'None') != 'None' or 'Reflect' in ext_attrs):
-      self._cpp_impl_includes.add('"core/dom/CustomElementCallbackDispatcher.h"')
+      self._cpp_impl_includes.add('"core/dom/custom/CustomElementCallbackDispatcher.h"')
       needs_custom_element_callbacks = True
 
     if return_type_is_nullable:
@@ -872,7 +939,7 @@
 
     if requires_script_execution_context:
       body_emitter.Emit(
-          '        ScriptExecutionContext* context = DartUtilities::scriptExecutionContext();\n'
+          '        ExecutionContext* context = DartUtilities::scriptExecutionContext();\n'
           '        if (!context) {\n'
           '            exception = Dart_NewStringFromCString("Failed to retrieve a context");\n'
           '            goto fail;\n'
@@ -977,8 +1044,12 @@
             '        $TYPE $ARGUMENT_NAME;\n'\
             '        $CLS::$FUNCTION(args, $INDEX, $ARGUMENT_NAME, exception);\n'
       else:
-        invocation_template =\
-            '        $TYPE $ARGUMENT_NAME = $CLS::$FUNCTION(args, $INDEX, exception);\n'
+        if not auto_scope_setup and type_info.native_type() == 'String':
+          invocation_template =\
+              '        $TYPE $ARGUMENT_NAME = $CLS::$FUNCTION(args, $INDEX, exception, false);\n'
+        else:
+          invocation_template =\
+              '        $TYPE $ARGUMENT_NAME = $CLS::$FUNCTION(args, $INDEX, exception);\n'
       body_emitter.Emit(
           '\n' +
           invocation_template +
@@ -1019,6 +1090,8 @@
           cpp_arguments.insert(0, 'receiver')
         else:
           cpp_arguments.append('receiver')
+      elif self._IsStatic(node.id):
+        cpp_arguments.insert(0, 'receiver')
 
     function_call = '%s(%s)' % (function_expression, ', '.join(cpp_arguments))
     if return_type == 'void':
@@ -1055,15 +1128,17 @@
       elif return_type_info.dart_type() == 'double':
         set_return_value = 'Dart_SetDoubleReturnValue(args, %s)' % (value_expression)
       elif return_type_info.dart_type() == 'String':
+        auto_dart_scope='true' if auto_scope_setup else 'false'
         if ext_attrs and 'TreatReturnedNullStringAs' in ext_attrs:
-          set_return_value = 'DartUtilities::setDartStringReturnValueWithNullCheck(args, %s)' % (value_expression)
+          set_return_value = 'DartUtilities::setDartStringReturnValueWithNullCheck(args, %s, %s)' % (value_expression, auto_dart_scope)
         else:
-          set_return_value = 'DartUtilities::setDartStringReturnValue(args, %s)' % (value_expression)
+          set_return_value = 'DartUtilities::setDartStringReturnValue(args, %s, %s)' % (value_expression, auto_dart_scope)
       elif return_type_info.dart_type() == 'num' and return_type_info.native_type() == 'double':
         set_return_value = 'Dart_SetDoubleReturnValue(args, %s)' % (value_expression)
       else:
         return_to_dart_conversion = return_type_info.return_to_dart_conversion(
             value_expression,
+            auto_scope_setup,
             self._interface.id,
             ext_attrs)
         set_return_value = '%s' % (return_to_dart_conversion)
@@ -1072,12 +1147,7 @@
         RETURN_VALUE=set_return_value)
 
   def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
-      native_suffix, is_custom, emit_metadata=True):
-
-    def _GenerateAutoSetupScope(self, idl_name, native_suffix):
-      if ((self._interface.id, idl_name, native_suffix) not in _cpp_no_auto_scope_list):
-        return 'true'
-      return 'false'
+      native_suffix, is_custom, auto_scope_setup=True, emit_metadata=True):
 
     metadata = []
     if emit_metadata:
@@ -1095,7 +1165,6 @@
         NATIVE_BINDING=native_binding)
 
     cpp_callback_name = '%s%s' % (idl_name, native_suffix)
-    auto_scope_setup = _GenerateAutoSetupScope(self, idl_name, native_suffix)
 
     self._cpp_resolver_emitter.Emit(
         '    if (argumentCount == $ARGC && name == "$NATIVE_BINDING") {\n'
@@ -1105,7 +1174,7 @@
         ARGC=argument_count,
         NATIVE_BINDING=native_binding,
         INTERFACE_NAME=self._interface.id,
-        AUTO_SCOPE_SETUP=auto_scope_setup,
+        AUTO_SCOPE_SETUP='true' if auto_scope_setup else 'false',
         CPP_CALLBACK_NAME=cpp_callback_name)
 
     if is_custom:
@@ -1128,12 +1197,18 @@
     attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower()
     return 'WebCore::%s::%sAttr' % (namespace, attribute_name)
 
+  def _IsStatic(self, attribute_name):
+    cpp_type_name = self._interface_type_info.native_type()
+    if cpp_type_name in _cpp_static_call_map:
+      return attribute_name in _cpp_static_call_map[cpp_type_name]
+    return False
+
   def _GenerateWebCoreFunctionExpression(self, function_name, idl_node, cpp_callback_name=None):
     if 'ImplementedBy' in idl_node.ext_attrs:
       return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name)
     cpp_type_name = self._interface_type_info.native_type()
     impl_type_name = _GetCPPTypeName(cpp_type_name, function_name, cpp_callback_name)
-    if idl_node.is_static:
+    if idl_node.is_static or self._IsStatic(idl_node.id):
       return '%s::%s' % (impl_type_name, function_name)
     if cpp_type_name == impl_type_name:
       return '%s%s' % (self._interface_type_info.receiver(), function_name)
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 0d2150d..0062f83 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -34,7 +34,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide Symbol, deprecated;
+import 'dart:_internal' hide Symbol, deprecated;
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -43,6 +43,7 @@
 import 'dart:typed_data';
 // Not actually used, but imported since dart:html can generate these objects.
 import 'dart:svg' as svg;
+import 'dart:svg' show Matrix;
 import 'dart:web_audio' as web_audio;
 import 'dart:web_gl' as gl;
 import 'dart:web_sql';
diff --git a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
index df8a304..3e4e168 100644
--- a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
@@ -14,7 +14,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, Returns, JSName;
diff --git a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
index 7cb895e..0c00c76 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -9,7 +9,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:typed_data';
diff --git a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
index 147f61c..7500782 100644
--- a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
@@ -8,7 +8,7 @@
 library dart.dom.web_gl;
 
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:typed_data';
diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
index 9c79d0d..c6c9bcf 100644
--- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
@@ -16,7 +16,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show convertDartClosureToJS, Creates, JSName;
diff --git a/tools/dom/templates/html/dartium/cpp_callback_header.template b/tools/dom/templates/html/dartium/cpp_callback_header.template
index 285b523..001207f 100644
--- a/tools/dom/templates/html/dartium/cpp_callback_header.template
+++ b/tools/dom/templates/html/dartium/cpp_callback_header.template
@@ -47,7 +47,7 @@
 $HANDLERS
 
 private:
-    Dart$(INTERFACE)(Dart_Handle object, Dart_Handle& exception, ScriptExecutionContext* context)
+    Dart$(INTERFACE)(Dart_Handle object, Dart_Handle& exception, ExecutionContext* context)
         : ActiveDOMCallback(context)
         , m_callback(object, exception)
     {
diff --git a/tools/dom/templates/html/dartium/cpp_header.template b/tools/dom/templates/html/dartium/cpp_header.template
index a8a0340..1f8ae1b 100644
--- a/tools/dom/templates/html/dartium/cpp_header.template
+++ b/tools/dom/templates/html/dartium/cpp_header.template
@@ -34,9 +34,9 @@
     {
         return createWrapper(value.get());
     }
-    static void returnToDart(Dart_NativeArguments args, PassRefPtr< $WEBCORE_CLASS_NAME > value)
+    static void returnToDart(Dart_NativeArguments args, PassRefPtr< $WEBCORE_CLASS_NAME > value, bool autoDartScope = true)
     {
-        return returnToDart(args, value.get());
+        return returnToDart(args, value.get(), autoDartScope);
     }
 
     static Dart_NativeFunction resolver(Dart_Handle name, int argumentCount, bool* autoSetupScope);
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 44b1990..2c92c8c 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -33,7 +33,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide Symbol, deprecated;
+import 'dart:_internal' hide Symbol, deprecated;
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -48,6 +48,7 @@
 import 'dart:web_sql';
 // Not actually used, but imported since dart:html can generate these objects.
 import 'dart:svg' as svg;
+import 'dart:svg' show Matrix;
 import 'dart:web_audio' as web_audio;
 
 export 'dart:math' show Rectangle, Point;
diff --git a/tools/dom/templates/html/dartium/svg_dartium.darttemplate b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
index 66b9873..bee1596 100644
--- a/tools/dom/templates/html/dartium/svg_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
@@ -5,7 +5,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
index d2457d0..0f9bdbd 100644
--- a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
@@ -5,7 +5,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate b/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
index f651502..c441c01 100644
--- a/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
@@ -5,7 +5,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate b/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
index eb97322..23eafeb 100644
--- a/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
@@ -16,7 +16,7 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:_collection-dev' hide deprecated;
+import 'dart:_internal' hide deprecated;
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate b/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
new file mode 100644
index 0000000..82862da
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_GlobalEventHandlers.darttemplate
@@ -0,0 +1,9 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+@DocsEditable()
+$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME extends EventTarget$NATIVESPEC {
+$!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
index af426b5..c460c1ba 100644
--- a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
@@ -28,17 +28,5 @@
    * Note that touch events are only supported if the user is using a touch
    * device.
    */
-  static bool get supported {
-$if DART2JS
-    if (JS('bool', '"ontouchstart" in window')) {
-      return Device.isEventTypeSupported('TouchEvent');
-    }
-    return false;
-$else
-    // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
-    // Basically, this is a fairly common check and it'd be great if it did not
-    // throw exceptions.
-    return Device.isEventTypeSupported('TouchEvent');
-$endif
-  }
+  static bool get supported => Device.isEventTypeSupported('TouchEvent');
 }
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index d7dadf4..b84bb5f 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -27,7 +27,7 @@
    * [animationFrame] again for the animation to continue.
    */
   Future<num> get animationFrame {
-    var completer = new Completer<num>();
+    var completer = new Completer<num>.sync();
     requestAnimationFrame((time) {
       completer.complete(time);
     });
diff --git a/tools/dom/templates/html/impl/impl_WindowEventHandlers.darttemplate b/tools/dom/templates/html/impl/impl_WindowEventHandlers.darttemplate
new file mode 100644
index 0000000..82862da
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_WindowEventHandlers.darttemplate
@@ -0,0 +1,9 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+@DocsEditable()
+$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME extends EventTarget$NATIVESPEC {
+$!MEMBERS}
diff --git a/tools/gyp/configurations_xcode.gypi b/tools/gyp/configurations_xcode.gypi
index 0af681d..066c628 100644
--- a/tools/gyp/configurations_xcode.gypi
+++ b/tools/gyp/configurations_xcode.gypi
@@ -34,6 +34,8 @@
             '-Wtrigraphs', # Disable Xcode default.
             '-Wreturn-type',
             '-Werror=return-type',
+            # TODO(15922): Enable this flag by default.
+            # '-Wshorten-64-to-32',
           ],
 
           # Generate PIC code as Chrome is switching to this.
diff --git a/tools/task_kill.py b/tools/task_kill.py
index ec6b574..fa7bbd5 100755
--- a/tools/task_kill.py
+++ b/tools/task_kill.py
@@ -23,12 +23,26 @@
 POSIX_INFO = 'ps -p %s -o args'
 
 EXECUTABLE_NAMES = {
-  'win32': { 'chrome': 'chrome.exe', 'dart': 'dart.exe',
-             'iexplore': 'iexplore.exe', 'firefox': 'firefox.exe'},
-  'linux': { 'chrome': 'chrome', 'dart': 'dart',
-             'firefox': 'firefox.exe'},
-  'macos': { 'chrome': 'Chrome', 'dart': 'dart',
-             'firefox': 'firefox', 'safari': 'Safari' }
+  'win32': {
+    'chrome': 'chrome.exe',
+    'content_shell': 'content_shell.exe',
+    'dart': 'dart.exe',
+    'iexplore': 'iexplore.exe',
+    'firefox': 'firefox.exe'
+  },
+  'linux': {
+    'chrome': 'chrome',
+    'content_shell': 'content_shell',
+    'dart': 'dart',
+    'firefox': 'firefox.exe'
+  },
+  'macos': {
+    'chrome': 'Chrome',
+    'content_shell': 'Content Shell',
+    'dart': 'dart',
+    'firefox': 'firefox',
+    'safari': 'Safari'
+  }
 }
 
 INFO_COMMAND = {
@@ -153,6 +167,7 @@
   status += Kill('chrome')
   status += Kill('iexplore')
   status += Kill('safari')
+  status += Kill('content_shell')
   return status
 
 def KillDart():
diff --git a/tools/test.dart b/tools/test.dart
index b7afb77..278dc74 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -191,6 +191,21 @@
         if (key == 'analyze_library') {
           testSuites.add(new AnalyzeLibraryTestSuite(conf));
         }
+      } else if (conf['compiler'] == 'none' &&
+                 conf['runtime'] == 'vm' &&
+                 key == 'pkgbuild') {
+        if (!conf['use_repository_packages'] && !conf['use_public_packages']) {
+          print("You need to use either --use-repository-packages or "
+                "--use-public-packages with the pkgbuild test suite!");
+          exit(1);
+        }
+        if (!conf['use_sdk']) {
+          print("Running the 'pkgbuild' test suite requires "
+                "passing the '--use-sdk' to test.py");
+          exit(1);
+        }
+        testSuites.add(
+            new PkgBuildTestSuite(conf, 'pkgbuild', 'pkg/pkgbuild.status'));
       }
     }
 
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index b25c992..462563d 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -145,28 +145,71 @@
       Completer stdoutDone = new Completer();
       Completer stderrDone = new Completer();
 
-      process.stdout.transform(UTF8.decoder).listen((data) {
+      bool stdoutIsDone = false;
+      bool stderrIsDone = false;
+      StreamSubscription stdoutSubscription;
+      StreamSubscription stderrSubscription;
+
+      // This timer is used to close stdio to the subprocess once we got
+      // the exitCode. Sometimes descendants of the subprocess keep stdio
+      // handles alive even though the direct subprocess is dead.
+      Timer watchdogTimer;
+
+      void closeStdout([_]){
+        if (!stdoutIsDone) {
+          stdoutDone.complete();
+          stdoutIsDone = true;
+
+          if (stderrIsDone && watchdogTimer != null) {
+            watchdogTimer.cancel();
+          }
+        }
+      }
+
+      void closeStderr([_]) {
+        if (!stderrIsDone) {
+          stderrDone.complete();
+          stderrIsDone = true;
+
+          if (stdoutIsDone && watchdogTimer != null) {
+            watchdogTimer.cancel();
+          }
+        }
+      }
+
+      stdoutSubscription =
+        process.stdout.transform(UTF8.decoder).listen((data) {
         _addStdout(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
         // if it actually does due to dart:io or vm bug.
         _logEvent("An error occured in the process stdout handling: $error");
-      }, onDone: () {
-        stdoutDone.complete(true);
-      });
+      }, onDone: closeStdout);
 
-      process.stderr.transform(UTF8.decoder).listen((data) {
+      stderrSubscription =
+        process.stderr.transform(UTF8.decoder).listen((data) {
         _addStderr(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
         // if it actually does due to dart:io or vm bug.
         _logEvent("An error occured in the process stderr handling: $error");
-      },  onDone: () {
-        stderrDone.complete(true);
-      });
+      },  onDone: closeStderr);
 
       process.exitCode.then((exitCode) {
         _logEvent("Browser closed with exitcode $exitCode");
+
+        if (!stdoutIsDone || !stderrIsDone) {
+          watchdogTimer = new Timer(MAX_STDIO_DELAY, () {
+            DebugLogger.warning(
+                "$MAX_STDIO_DELAY_PASSED_MESSAGE (browser: $this)");
+            watchdogTimer = null;
+            stdoutSubscription.cancel();
+            stderrSubscription.cancel();
+            closeStdout();
+            closeStderr();
+          });
+        }
+
         Future.wait([stdoutDone.future, stderrDone.future]).then((_) {
           process = null;
           if (_cleanup != null) {
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 6922687..7d12efb 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -25,6 +25,7 @@
   static Expectation STATIC_WARNING = byName('StaticWarning');
   static Expectation MISSING_STATIC_WARNING =
       byName('MissingStaticWarning');
+  static Expectation PUB_GET_ERROR = byName('PubGetError');
 
   // "meta expectations"
   static Expectation OK = byName('Ok');
@@ -67,6 +68,8 @@
       build("MissingStaticWarning", group: fail);
       build("StaticWarning", group: fail);
 
+      build("PubGetError", group: fail);
+
       build("Skip", isMetaExpectation: true);
       build("SkipByDesign", isMetaExpectation: true);
       build("Ok", isMetaExpectation: true);
@@ -124,10 +127,19 @@
   }
 }
 
-void ReadTestExpectationsInto(TestExpectations expectations,
-                              String statusFilePath,
-                              environment,
-                              onDone) {
+Future<TestExpectations> ReadTestExpectations(List<String> statusFilePaths,
+                                              Map environment) {
+  var testExpectations = new TestExpectations();
+  return Future.wait(statusFilePaths.map((String statusFile) {
+    return ReadTestExpectationsInto(
+        testExpectations, statusFile, environment);
+  })).then((_) => testExpectations);
+}
+
+Future ReadTestExpectationsInto(TestExpectations expectations,
+                                String statusFilePath,
+                                environment) {
+  var completer = new Completer();
   List<Section> sections = new List<Section>();
 
   void sectionsRead() {
@@ -138,10 +150,11 @@
         }
       }
     }
-    onDone();
+    completer.complete();
   }
 
   ReadConfigurationInto(statusFilePath, sections, sectionsRead);
+  return completer.future;
 }
 
 void ReadConfigurationInto(path, sections, onDone) {
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index c0af640..a9b407e 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -272,6 +272,23 @@
               false,
               'bool'),
           new _TestOptionSpecification(
+              'use_public_packages',
+              'For tests using packages: Use pub.dartlang.org packages '
+              'instead the ones in the repository.',
+              ['--use-public-packages'],
+              [],
+              false,
+              'bool'),
+            new _TestOptionSpecification(
+                'use_repository_packages',
+                'For tests using packages: Use pub.dartlang.org packages '
+                'but use overrides for the packages available in the '
+                'repository.',
+                ['--use-repository-packages'],
+                [],
+                false,
+            'bool'),
+          new _TestOptionSpecification(
               'build_directory',
               'The name of the build directory, where products are placed.',
               ['--build-directory'],
@@ -585,6 +602,12 @@
       print("Error: shard index is ${config['shard']} out of "
             "${config['shards']} shards");
     }
+
+    if (config['use_repository_packages'] && config['use_public_packages']) {
+      isValid = false;
+      print("Cannot have both --use-repository-packages and "
+            "--use-public-packages");
+    }
     return isValid;
   }
 
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 1ebc541..cf4a808 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -223,7 +223,8 @@
 
   static final INTERESTED_CONFIGURATION_PARAMETERS =
       ['mode', 'arch', 'compiler', 'runtime', 'checked', 'host_checked',
-       'minified', 'csp', 'system', 'vm_options', 'use_sdk'];
+       'minified', 'csp', 'system', 'vm_options', 'use_sdk',
+       'use_repository_packages', 'use_public_packages'];
 
   IOSink _sink;
 
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 8792355..9765d463 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -105,9 +105,13 @@
   /** Environment for the command */
   Map<String, String> environmentOverrides;
 
+  /** Working directory for the command */
+  final String workingDirectory;
+
   ProcessCommand._(String displayName, this.executable,
                    this.arguments,
-                   [this.environmentOverrides = null])
+                   [this.environmentOverrides = null,
+                    this.workingDirectory = null])
       : super._(displayName) {
     if (io.Platform.operatingSystem == 'windows') {
       // Windows can't handle the first command if it is a .bat file or the like
@@ -120,6 +124,7 @@
   void _buildHashCode(HashCodeBuilder builder) {
     super._buildHashCode(builder);
     builder.add(executable);
+    builder.add(workingDirectory);
     for (var object in arguments) builder.add(object);
     if (environmentOverrides != null) {
       for (var key in environmentOverrides.keys) {
@@ -130,8 +135,8 @@
   }
 
   bool _equal(Command other) {
-    if (!super._equal(other)) return false;
-      if (other is ProcessCommand) {
+    if (other is ProcessCommand) {
+      if (!super._equal(other)) return false;
 
       if (hashCode != other.hashCode ||
           executable != other.executable ||
@@ -140,6 +145,7 @@
       }
 
       if (!deepJsonCompare(arguments, other.arguments)) return false;
+      if (workingDirectory != other.workingDirectory) return false;
       if (!deepJsonCompare(environmentOverrides, other.environmentOverrides)) {
         return false;
       }
@@ -150,8 +156,12 @@
   }
 
   String get reproductionCommand {
-    return ([executable]..addAll(arguments))
+    var command = ([executable]..addAll(arguments))
         .map(escapeCommandLineArgument).join(' ');
+    if (workingDirectory != null) {
+      command = "$command (working directory: $workingDirectory)";
+    }
+    return command;
   }
 
   Future<bool> get outputIsUpToDate => new Future.value(false);
@@ -356,6 +366,213 @@
                 environmentOverrides);
 }
 
+class PubCommand extends ProcessCommand {
+  final String command;
+
+  PubCommand._(String pubCommand,
+               String pubExecutable,
+               String pubspecYamlDirectory,
+               String pubCacheDirectory)
+      : super._('pub_$pubCommand',
+                new io.File(pubExecutable).absolute.path,
+                [pubCommand],
+                {'PUB_CACHE' : pubCacheDirectory},
+                pubspecYamlDirectory), command = pubCommand;
+
+  void _buildHashCode(HashCodeBuilder builder) {
+    super._buildHashCode(builder);
+    builder.add(command);
+  }
+
+  bool _equal(Command other) {
+    return
+        other is PubCommand &&
+        super._equal(other) &&
+        command == other.command;
+  }
+}
+
+/* [ScriptCommand]s are executed by dart code. */
+abstract class ScriptCommand extends Command {
+  ScriptCommand._(String displayName) : super._(displayName);
+
+  Future<ScriptCommandOutputImpl> run();
+}
+
+class CleanDirectoryCopyCommand extends ScriptCommand {
+  final String _sourceDirectory;
+  final String _destinationDirectory;
+
+  CleanDirectoryCopyCommand._(this._sourceDirectory, this._destinationDirectory)
+    : super._('dir_copy');
+
+  String get reproductionCommand =>
+      "Copying '$_sourceDirectory' to '$_destinationDirectory'.";
+
+  Future<ScriptCommandOutputImpl> run() {
+    var watch = new Stopwatch()..start();
+
+    var source = new io.Directory(_sourceDirectory);
+    var destination = new io.Directory(_destinationDirectory);
+
+    return destination.exists().then((bool exists) {
+      var cleanDirectoryFuture;
+      if (exists) {
+        cleanDirectoryFuture = destination.delete(recursive: true);
+      } else {
+        cleanDirectoryFuture = new Future.value(null);
+      }
+      return cleanDirectoryFuture.then((_) {
+        return TestUtils.copyDirectory(_sourceDirectory, _destinationDirectory);
+      });
+    }).then((_) {
+      return new ScriptCommandOutputImpl(
+          this, Expectation.PASS, "", watch.elapsed);
+    }).catchError((error) {
+      return new ScriptCommandOutputImpl(
+          this, Expectation.FAIL, "An error occured: $error.", watch.elapsed);
+    });
+  }
+
+  void _buildHashCode(HashCodeBuilder builder) {
+    super._buildHashCode(builder);
+    builder.add(_sourceDirectory);
+    builder.add(_destinationDirectory);
+  }
+
+  bool _equal(Command other) {
+    return
+        other is CleanDirectoryCopyCommand &&
+        super._equal(other) &&
+        _sourceDirectory == other._sourceDirectory &&
+        _destinationDirectory == other._destinationDirectory;
+  }
+}
+
+class ModifyPubspecYamlCommand extends ScriptCommand {
+  String _pubspecYamlFile;
+  String _destinationFile;
+  Map<String, Map> _dependencyOverrides;
+
+  ModifyPubspecYamlCommand._(this._pubspecYamlFile,
+                             this._destinationFile,
+                             this._dependencyOverrides)
+    : super._("modify_pubspec") {
+    assert(_pubspecYamlFile.endsWith("pubspec.yaml"));
+    assert(_destinationFile.endsWith("pubspec.yaml"));
+  }
+
+  String get reproductionCommand =>
+      "Adding necessary dependency overrides to '$_pubspecYamlFile' "
+      "(destination = $_destinationFile).";
+
+  Future<ScriptCommandOutputImpl> run() {
+    var watch = new Stopwatch()..start();
+
+    var pubspecLockFile =
+        _destinationFile.substring(0, _destinationFile.length - ".yaml".length)
+        + ".lock";
+
+    var file = new io.File(_pubspecYamlFile);
+    var destinationFile = new io.File(_destinationFile);
+    var lockfile = new io.File(pubspecLockFile);
+    return file.readAsString().then((String yamlString) {
+      var dependencyOverrideSection = new StringBuffer();
+      if (_dependencyOverrides.isNotEmpty) {
+        dependencyOverrideSection.write(
+            "\n"
+            "# This section was autogenerated by test.py!\n"
+            "dependency_overrides:\n");
+        _dependencyOverrides.forEach((String packageName, Map override) {
+          dependencyOverrideSection.write("  $packageName:\n");
+          override.forEach((overrideKey, overrideValue) {
+            dependencyOverrideSection.write(
+                "    $overrideKey: $overrideValue\n");
+          });
+        });
+      }
+      var modifiedYamlString = "$yamlString\n$dependencyOverrideSection";
+      return destinationFile.writeAsString(modifiedYamlString).then((_) {
+        lockfile.exists().then((bool lockfileExists) {
+          if (lockfileExists) {
+            return lockfile.delete();
+          }
+        });
+      });
+    }).then((_) {
+      return new ScriptCommandOutputImpl(
+          this, Expectation.PASS, "", watch.elapsed);
+    }).catchError((error) {
+      return new ScriptCommandOutputImpl(
+          this, Expectation.FAIL, "An error occured: $error.", watch.elapsed);
+    });
+  }
+
+  void _buildHashCode(HashCodeBuilder builder) {
+    super._buildHashCode(builder);
+    builder.add(_pubspecYamlFile);
+    builder.add(_destinationFile);
+    builder.addJson(_dependencyOverrides);
+  }
+
+  bool _equal(Command other) {
+    return
+        other is ModifyPubspecYamlCommand &&
+        super._equal(other) &&
+        _pubspecYamlFile == other._pubspecYamlFile &&
+        _destinationFile == other._destinationFile &&
+        deepJsonCompare(_dependencyOverrides, other._dependencyOverrides);
+  }
+}
+
+/*
+ * [MakeSymlinkCommand] makes a symbolic link to another directory.
+ */
+class MakeSymlinkCommand extends ScriptCommand {
+  String _link;
+  String _target;
+
+  MakeSymlinkCommand._(this._link, this._target) : super._('make_symlink');
+
+  String get reproductionCommand =>
+      "Make symbolic link '$_link' (target: $_target)'.";
+
+  Future<ScriptCommandOutputImpl> run() {
+    var watch = new Stopwatch()..start();
+    var targetFile = new io.Directory(_target);
+    return targetFile.exists().then((bool targetExists) {
+      if (!targetExists) {
+        throw new Exception("Target '$_target' does not exist");
+      }
+      var link = new io.Link(_link);
+
+      return link.exists()
+          .then((bool exists) { if (exists) return link.delete(); })
+          .then((_) => link.create(_target));
+    }).then((_) {
+      return new ScriptCommandOutputImpl(
+          this, Expectation.PASS, "", watch.elapsed);
+    }).catchError((error) {
+      return new ScriptCommandOutputImpl(
+          this, Expectation.FAIL, "An error occured: $error.", watch.elapsed);
+    });
+  }
+
+  void _buildHashCode(HashCodeBuilder builder) {
+    super._buildHashCode(builder);
+    builder.add(_link);
+    builder.add(_target);
+  }
+
+  bool _equal(Command other) {
+    return
+        other is MakeSymlinkCommand &&
+        super._equal(other) &&
+        _link == other._link &&
+        _target == other._target;
+  }
+}
+
 class CommandBuilder {
   static final CommandBuilder instance = new CommandBuilder._();
 
@@ -418,12 +635,40 @@
   }
 
   Command getProcessCommand(String displayName, executable, arguments,
-                     [environment = null]) {
+                     [environment = null, workingDirectory = null]) {
     var command = new ProcessCommand._(displayName, executable, arguments,
-                                       environment);
+                                       environment, workingDirectory);
     return _getUniqueCommand(command);
   }
 
+  Command getCopyCommand(String sourceDirectory, String destinationDirectory) {
+    var command = new CleanDirectoryCopyCommand._(sourceDirectory,
+                                                  destinationDirectory);
+    return _getUniqueCommand(command);
+  }
+
+  Command getPubCommand(String pubCommand,
+                        String pubExecutable,
+                        String pubspecYamlDirectory,
+                        String pubCacheDirectory) {
+    var command = new PubCommand._(pubCommand,
+                                   pubExecutable,
+                                   pubspecYamlDirectory,
+                                   pubCacheDirectory);
+    return _getUniqueCommand(command);
+  }
+
+  Command getMakeSymlinkCommand(String link, String target) {
+    return _getUniqueCommand(new MakeSymlinkCommand._(link, target));
+  }
+
+  Command getModifyPubspecCommand(String pubspecYamlFile, Map depsOverrides,
+                                  {String destinationFile: null}) {
+    if (destinationFile == null) destinationFile = pubspecYamlFile;
+    return _getUniqueCommand(new ModifyPubspecYamlCommand._(
+        pubspecYamlFile, destinationFile, depsOverrides));
+  }
+
   Command _getUniqueCommand(Command command) {
     // All Command classes have hashCode/operator==, so we check if this command
     // has already been build, if so we return the cached one, otherwise we
@@ -532,8 +777,9 @@
   }
 
   bool get isFinished {
-    return !lastCommandOutput.successful ||
-           commands.length == commandOutputs.length;
+    return commandOutputs.length > 0 &&
+        (!lastCommandOutput.successful ||
+         commands.length == commandOutputs.length);
   }
 }
 
@@ -1323,6 +1569,44 @@
   }
 }
 
+class PubCommandOutputImpl extends CommandOutputImpl {
+  PubCommandOutputImpl(PubCommand command, int exitCode, bool timedOut,
+      List<int> stdout, List<int> stderr, Duration time)
+      : super(command, exitCode, timedOut, stdout, stderr, time, false);
+
+  Expectation result(TestCase testCase) {
+    // Handle crashes and timeouts first
+    if (hasCrashed) return Expectation.CRASH;
+    if (hasTimedOut) return Expectation.TIMEOUT;
+
+    if (exitCode == 0) {
+      return Expectation.PASS;
+    } else if ((command as PubCommand).command == 'get') {
+      return Expectation.PUB_GET_ERROR;
+    } else {
+      return Expectation.FAIL;
+    }
+  }
+}
+
+class ScriptCommandOutputImpl extends CommandOutputImpl {
+  final Expectation _result;
+
+  ScriptCommandOutputImpl(ScriptCommand command, this._result,
+                          String scriptExecutionInformation, Duration time)
+      : super(command, 0, false, [], [], time, false) {
+    var lines = scriptExecutionInformation.split("\n");
+    diagnostics.addAll(lines);
+  }
+
+  Expectation result(TestCase testCase) => _result;
+
+  bool get canRunDependendCommands => _result == Expectation.PASS;
+
+  bool get successful => _result == Expectation.PASS;
+
+}
+
 CommandOutput createCommandOutput(Command command,
                                   int exitCode,
                                   bool timedOut,
@@ -1351,6 +1635,9 @@
   } else if (command is JSCommandlineCommand) {
     return new JsCommandlineOutputImpl(
         command, exitCode, timedOut, stdout, stderr, time);
+  } else if (command is PubCommand) {
+    return new PubCommandOutputImpl(
+        command, exitCode, timedOut, stdout, stderr, time);
   }
 
   return new CommandOutputImpl(
@@ -1399,20 +1686,79 @@
         Future processFuture =
             io.Process.start(command.executable,
                              command.arguments,
-                             environment: processEnvironment);
+                             environment: processEnvironment,
+                             workingDirectory: command.workingDirectory);
         processFuture.then((io.Process process) {
+          StreamSubscription stdoutSubscription =
+              _drainStream(process.stdout, stdout);
+          StreamSubscription stderrSubscription =
+              _drainStream(process.stderr, stderr);
+
+          var stdoutCompleter = new Completer();
+          var stderrCompleter = new Completer();
+
+          bool stdoutDone = false;
+          bool stderrDone = false;
+
+          // This timer is used to close stdio to the subprocess once we got
+          // the exitCode. Sometimes descendants of the subprocess keep stdio
+          // handles alive even though the direct subprocess is dead.
+          Timer watchdogTimer;
+
+          closeStdout([_]) {
+            if (!stdoutDone) {
+              stdoutCompleter.complete();
+              stdoutDone = true;
+
+              if (stderrDone && watchdogTimer != null) {
+                watchdogTimer.cancel();
+              }
+            }
+          }
+          closeStderr([_]) {
+            if (!stderrDone) {
+              stderrCompleter.complete();
+              stderrDone = true;
+
+              if (stdoutDone && watchdogTimer != null) {
+                watchdogTimer.cancel();
+              }
+            }
+          }
+
           // Close stdin so that tests that try to block on input will fail.
           process.stdin.close();
           void timeoutHandler() {
             timedOut = true;
             if (process != null) {
-              process.kill();
+              if (!process.kill()) {
+                DebugLogger.error("Unable to kill ${process.pid}");
+              }
             }
           }
-          Future.wait([process.exitCode,
-                       _drainStream(process.stdout, stdout),
-                       _drainStream(process.stderr, stderr)])
-              .then((values) => _commandComplete(values[0]));
+
+          stdoutSubscription.asFuture().then(closeStdout);
+          stderrSubscription.asFuture().then(closeStderr);
+
+          process.exitCode.then((exitCode) {
+            if (!stdoutDone || !stderrDone) {
+              watchdogTimer = new Timer(MAX_STDIO_DELAY, () {
+                DebugLogger.warning(
+                    "$MAX_STDIO_DELAY_PASSED_MESSAGE (command: $command)");
+                watchdogTimer = null;
+                stdoutSubscription.cancel();
+                stderrSubscription.cancel();
+                closeStdout();
+                closeStderr();
+              });
+            }
+
+            Future.wait([stdoutCompleter.future,
+                         stderrCompleter.future]).then((_) {
+              _commandComplete(exitCode);
+            });
+          });
+
           timeoutTimer = new Timer(new Duration(seconds: timeout),
                                    timeoutHandler);
         }).catchError((e) {
@@ -1447,12 +1793,13 @@
     return commandOutput;
   }
 
-  Future _drainStream(Stream<List<int>> source, List<int> destination) {
-    return source.listen(destination.addAll).asFuture();
+  StreamSubscription _drainStream(Stream<List<int>> source,
+                                  List<int> destination) {
+    return source.listen(destination.addAll);
   }
 
   Map<String, String> _createProcessEnvironment() {
-    var environment = io.Platform.environment;
+    var environment = new Map.from(io.Platform.environment);
 
     if (command.environmentOverrides != null) {
       for (var key in command.environmentOverrides.keys) {
@@ -1965,6 +2312,19 @@
       });
     }
   }
+
+  void dumpState() {
+    print("");
+    print("CommandQueue state:");
+    print("  Processes: used: $_numProcesses max: $_maxProcesses");
+    print("  BrowserProcesses: used: $_numBrowserProcesses "
+          "max: $_maxBrowserProcesses");
+    print("  Finishing: $_finishing");
+    print("  Queue (length = ${_runQueue.length}):");
+    for (var command in _runQueue) {
+      print("      $command");
+    }
+  }
 }
 
 
@@ -2047,6 +2407,8 @@
     } else if (command is AnalysisCommand && batchMode) {
       return _getBatchRunner(command.flavor)
           .runCommand(command.flavor, command, timeout, command.arguments);
+    } else if (command is ScriptCommand) {
+      return command.run();
     } else {
       return new RunningProcess(command, timeout).run();
     }
@@ -2332,6 +2694,7 @@
     }
 
     var testCaseEnqueuer;
+    CommandQueue commandQueue;
     void setupForRunning(TestCaseEnqueuer testCaseEnqueuer) {
       Timer _debugTimer;
       // If we haven't seen a single test finishing during a 10 minute period
@@ -2350,6 +2713,8 @@
           print("The debug timer of test.dart expired. Please report this issue"
                 " to ricow/kustermann and provide the following information:");
           print("");
+          print("Graph is sealed: ${_graph.isSealed}");
+          print("");
           _graph.DumpCounts();
           print("");
           var unfinishedNodeStates = [
@@ -2379,6 +2744,10 @@
               print("");
             }
           }
+
+          if (commandQueue != null) {
+            commandQueue.dumpState();
+          }
         });
       }
 
@@ -2407,7 +2776,7 @@
 
       // Run "runnable commands" using [executor] subject to
       // maxProcesses/maxBrowserProcesses constraint
-      var commandQueue = new CommandQueue(
+      commandQueue = new CommandQueue(
           _graph, testCaseEnqueuer, executor, maxProcesses, maxBrowserProcesses,
           verbose);
 
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 686c6e0..2a2e809 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -173,6 +173,32 @@
     return name;
   }
 
+  String get pubPath {
+    var prefix = 'sdk/bin/';
+    if (configuration['use_sdk']) {
+      prefix = '$buildDir/dart-sdk/bin/';
+    }
+    String suffix = getExecutableSuffix('pub');
+    var name = '${prefix}pub$suffix';
+    if (!(new File(name)).existsSync() && !configuration['list']) {
+      throw "Executable '$name' does not exist";
+    }
+    return name;
+  }
+
+  String get dartPath {
+    var prefix = 'sdk/bin/';
+    if (configuration['use_sdk']) {
+      prefix = '$buildDir/dart-sdk/bin/';
+    }
+    String suffix = getExecutableSuffix('vm');
+    var name = '${prefix}dart$suffix';
+    if (!(new File(name)).existsSync() && !configuration['list']) {
+      throw "Executable '$name' does not exist";
+    }
+    return name;
+  }
+
   /**
    * The path to the executable used to run this suite's tests.
    */
@@ -306,6 +332,25 @@
     doTest(testCase);
   }
 
+  String createGeneratedTestDirectoryHelper(
+      String name, String dirname, Path testPath, String optionsName) {
+    Path relative = testPath.relativeTo(TestUtils.dartDir());
+    relative = relative.directoryPath.append(relative.filenameWithoutExtension);
+    String testUniqueName = relative.toString().replaceAll('/', '_');
+    if (!optionsName.isEmpty) {
+      testUniqueName = '$testUniqueName-$optionsName';
+    }
+
+    Path generatedTestPath = new Path(buildDir)
+        .append('generated_$name')
+        .append(dirname)
+        .append(testUniqueName);
+
+    TestUtils.mkdirRecursive(new Path('.'), generatedTestPath);
+    return new File(generatedTestPath.toNativePath()).absolute.path
+        .replaceAll('\\', '/');
+  }
+
   String buildTestCaseDisplayName(Path suiteDir,
                                   Path originTestPath,
                                   {String multitestName: ""}) {
@@ -324,6 +369,145 @@
     testName = concat(testName, multitestName);
     return testName;
   }
+
+  /**
+   * Create a directories for generated assets (tests, html files,
+   * pubspec checkouts ...).
+   */
+
+  String createOutputDirectory(Path testPath, String optionsName) {
+    var checked = configuration['checked'] ? '-checked' : '';
+    var minified = configuration['minified'] ? '-minified' : '';
+    var csp = configuration['csp'] ? '-csp' : '';
+    var sdk = configuration['use_sdk'] ? '-sdk' : '';
+    var packages = configuration['use_public_packages']
+        ? '-public_packages' : '';
+    var dirName = "${configuration['compiler']}-${configuration['runtime']}"
+                  "$checked$minified$csp$packages$sdk";
+    return createGeneratedTestDirectoryHelper(
+        "tests", dirName, testPath, optionsName);
+  }
+
+  String createCompilationOutputDirectory(Path testPath) {
+    var checked = configuration['checked'] ? '-checked' : '';
+    var minified = configuration['minified'] ? '-minified' : '';
+    var sdk = configuration['use_sdk'] ? '-sdk' : '';
+    var packages = configuration['use_public_packages']
+        ? '-public_packages' : '';
+    var dirName = "${configuration['compiler']}$checked$minified$packages$sdk";
+    return createGeneratedTestDirectoryHelper(
+        "compilations", dirName, testPath, "");
+  }
+
+  String createPubspecCheckoutDirectory(Path directoryOfPubspecYaml) {
+    var relativeDir = directoryOfPubspecYaml.relativeTo(TestUtils.dartDir());
+    var sdk = configuration['use_sdk'] ? '-sdk' : '';
+    var pkg = configuration['use_public_packages']
+        ? 'public_packages' : 'repo_packages';
+    return createGeneratedTestDirectoryHelper(
+        "pubspec_checkouts", '$pkg$sdk', directoryOfPubspecYaml, "");
+  }
+
+  String createPubPackageBuildsDirectory(Path directoryOfPubspecYaml) {
+    var relativeDir = directoryOfPubspecYaml.relativeTo(TestUtils.dartDir());
+    var pkg = configuration['use_public_packages']
+        ? 'public_packages' : 'repo_packages';
+    return createGeneratedTestDirectoryHelper(
+        "pub_package_builds", pkg, directoryOfPubspecYaml, "");
+  }
+
+  /**
+   * Helper function for discovering the packages in the dart repository.
+   */
+  Future<List> listDir(Path path, Function isValid) {
+    return new Directory(path.toNativePath())
+    .list(recursive: false)
+    .where((fse) => fse is Directory)
+    .map((Directory directory) {
+      var fullPath = directory.absolute.path;
+      var packageName = new Path(fullPath).filename;
+      if (isValid(packageName)) {
+        return [packageName, path.append(packageName).toNativePath()];
+      }
+      return null;
+    })
+    .where((name) => name != null)
+    .toList();
+  }
+
+  Future<Map> discoverPackagesInRepository() {
+    /*
+     * Layout of packages inside the dart repository:
+     *  dart/
+     *      pkg/PACKAGE_NAME
+     *      pkg/third_party/PACKAGE_NAME
+     *      third_party/pkg/PACKAGE_NAME
+     */
+
+    isValid(packageName) => packageName != 'third_party';
+
+    var dartDir = TestUtils.dartDir();
+    var futures = [
+      listDir(dartDir.append('pkg'), isValid),
+      listDir(dartDir.append('pkg').append('third_party'), isValid),
+      listDir(dartDir.append('third_party').append('pkg'), isValid),
+    ];
+    return Future.wait(futures).then((results) {
+      var packageDirectories = {};
+      for (var result in results) {
+        for (var packageTuple in result) {
+          String packageName = packageTuple[0];
+          String fullPath = packageTuple[1];
+          String yamlFile =
+              new Path(fullPath).append('pubspec.yaml').toNativePath();
+          if (new File(yamlFile).existsSync()) {
+            packageDirectories[packageName] = fullPath;
+          }
+        }
+      }
+      return packageDirectories;
+    });
+  }
+
+  Future<Map> discoverSamplesInRepository() {
+    /*
+     * Layout of samples inside the dart repository:
+     *  dart/
+     *      samples/SAMPLE_NAME
+     *      samples/third_party/SAMPLE_NAME
+     */
+
+    isValid(packageName) => packageName != 'third_party';
+
+    var dartDir = TestUtils.dartDir();
+    var futures = [
+      listDir(dartDir.append('samples'), isValid),
+      listDir(dartDir.append('samples').append('third_party'), isValid),
+    ];
+    return Future.wait(futures).then((results) {
+      var packageDirectories = {};
+      for (var result in results) {
+        for (var packageTuple in result) {
+          String packageName = packageTuple[0];
+          String fullPath = packageTuple[1];
+          packageDirectories[packageName] = fullPath;
+        }
+      }
+      return packageDirectories;
+    });
+  }
+
+  /**
+   * Helper function for building dependency_overrides for pubspec.yaml files.
+   */
+  Map buildPubspecDependencyOverrides(Map packageDirectories) {
+    Map overrides = {};
+    packageDirectories.forEach((String packageName, String fullPath) {
+      overrides[packageName] = { 'path' : fullPath };
+    });
+    return overrides;
+  }
+
 }
 
 
@@ -356,12 +540,11 @@
   final String dartDir;
   List<String> statusFilePaths;
   VoidFunction doDone;
-  TestExpectations testExpectations;
 
   CCTestSuite(Map configuration,
               String suiteName,
               String runnerName,
-              List<String> this.statusFilePaths,
+              this.statusFilePaths,
               {this.testPrefix: ''})
       : super(configuration, suiteName),
         dartDir = TestUtils.dartDir().toNativePath() {
@@ -379,7 +562,7 @@
     }
   }
 
-  void testNameHandler(String testName) {
+  void testNameHandler(TestExpectations testExpectations, String testName) {
     // Only run the tests that match the pattern. Use the name
     // "suiteName/testName" for cc tests.
     String constructedName = '$suiteName/$testPrefix$testName';
@@ -400,27 +583,19 @@
     doTest = onTest;
     doDone = onDone;
 
-    var filesRead = 0;
-    void statusFileRead() {
-      filesRead++;
-      if (filesRead == statusFilePaths.length) {
-        ccTestLister(hostRunnerPath).then((Iterable<String> names) {
-          names.forEach(testNameHandler);
-          onDone();
-        }).catchError((error) {
-          print("Fatal error occured: $error");
-          exit(1);
-        });
-      }
-    }
+    var statusFiles =
+        statusFilePaths.map((statusFile) => "$dartDir/$statusFile").toList();
 
-    testExpectations = new TestExpectations();
-    for (var statusFilePath in statusFilePaths) {
-      ReadTestExpectationsInto(testExpectations,
-                               '$dartDir/$statusFilePath',
-                               configuration,
-                               statusFileRead);
-    }
+    ReadTestExpectations(statusFiles, configuration)
+        .then((TestExpectations expectations) {
+      ccTestLister(hostRunnerPath).then((Iterable<String> names) {
+        names.forEach((testName) => testNameHandler(expectations, testName));
+        onDone();
+      }).catchError((error) {
+        print("Fatal error occured: $error");
+        exit(1);
+      });
+    });
   }
 }
 
@@ -537,8 +712,13 @@
 
   List<String> additionalOptions(Path filePath) => [];
 
+  Map<String, String> localPackageDirectories;
+
   void forEachTest(Function onTest, Map testCache, [VoidFunction onDone]) {
-    updateDartium().then((_) {
+    discoverPackagesInRepository().then((Map packageDirectories) {
+      localPackageDirectories = packageDirectories;
+      return updateDartium();
+    }).then((_) {
       doTest = onTest;
 
       return readExpectations();
@@ -584,36 +764,21 @@
    * Reads the status files and completes with the parsed expectations.
    */
   Future<TestExpectations> readExpectations() {
-    var completer = new Completer();
-    var expectations = new TestExpectations();
-
-    var filesRead = 0;
-    void statusFileRead() {
-      filesRead++;
-      if (filesRead == statusFilePaths.length) {
-        completer.complete(expectations);
-      }
-    }
-
-    for (var statusFilePath in statusFilePaths) {
-      // [forDirectory] adds name_$compiler.status for all tests suites. Use it
-      // if it exists, but otherwise skip it and don't fail.
+    var statusFiles = statusFilePaths.where((String statusFilePath) {
+      // [forDirectory] adds name_$compiler.status for all tests suites.
+      // Use it if it exists, but otherwise skip it and don't fail.
       if (statusFilePath.endsWith('_dart2js.status') ||
           statusFilePath.endsWith('_analyzer.status') ||
           statusFilePath.endsWith('_analyzer2.status')) {
         var file = new File(dartDir.append(statusFilePath).toNativePath());
-        if (!file.existsSync()) {
-          filesRead++;
-          continue;
-        }
+        return file.existsSync();
       }
+      return true;
+    }).map((statusFilePath) {
+      return dartDir.append(statusFilePath).toNativePath();
+    }).toList();
 
-      ReadTestExpectationsInto(expectations,
-                               dartDir.append(statusFilePath).toNativePath(),
-                               configuration, statusFileRead);
-    }
-
-    return completer.future;
+    return ReadTestExpectations(statusFiles, configuration);
   }
 
   Future enqueueTests() {
@@ -665,6 +830,102 @@
     var filePath = info.filePath;
     var optionsFromFile = info.optionsFromFile;
 
+    Path findPubspecYamlFile(Path filePath) {
+      final existsCache = TestUtils.existsCache;
+
+      Path root = TestUtils.dartDir();
+      assert ("$filePath".startsWith("$root"));
+
+      // We start with the parent directory of [filePath] and go up until
+      // the root directory (excluding the root).
+      List<String> segments =
+          filePath.directoryPath.relativeTo(root).segments();
+      while (segments.length > 0) {
+        var pubspecYamlPath =
+            new Path(segments.join('/')).append('pubspec.yaml');
+        if (existsCache.doesFileExist(pubspecYamlPath.toNativePath())) {
+          return root.join(pubspecYamlPath);
+        }
+        segments.removeLast();
+      }
+      return null;
+    }
+
+    Map buildSpecialPackageRoot(Path pubspecYamlFile) {
+      var commands = <Command>[];
+      var packageDir = pubspecYamlFile.directoryPath;
+      var packageName = packageDir.filename;
+
+      var checkoutDirectory =
+          createPubspecCheckoutDirectory(packageDir);
+      var modifiedYamlFile = new Path(checkoutDirectory).append("pubspec.yaml");
+      var pubCacheDirectory = new Path(checkoutDirectory).append("pub-cache");
+      var newPackageRoot = new Path(checkoutDirectory).append("packages");
+
+      // Remove the old packages directory, so we can do a clean 'pub get'.
+      var newPackagesDirectory = new Directory(newPackageRoot.toNativePath());
+      if (newPackagesDirectory.existsSync()) {
+        newPackagesDirectory.deleteSync(recursive: true);
+      }
+
+      // NOTE: We make a link in the package-root to [packageName], since
+      // 'pub get' doesn't create the link to the package containing
+      // pubspec.yaml if there is no lib directory.
+      var packageLink = newPackageRoot.append(packageName);
+      var packageLinkTarget = packageDir.append('lib');
+
+      // NOTE: We make a link in the package-root to pkg/expect, since
+      // 'package:expect' is not available on pub.dartlang.org!
+      var expectLink = newPackageRoot.append('expect');
+      var expectLinkTarget = TestUtils.dartDir()
+          .append('pkg').append('expect').append('lib');
+
+      // Generate dependency overrides if we use repository packages.
+      var packageDirectories = {};
+      if (configuration['use_repository_packages']) {
+        packageDirectories = new Map.from(localPackageDirectories);
+        // Do not create an dependency override for the package itself.
+        if (packageDirectories.containsKey(packageName)) {
+          packageDirectories.remove(packageName);
+        }
+      }
+      var overrides = buildPubspecDependencyOverrides(packageDirectories);
+
+      commands.add(CommandBuilder.instance.getModifyPubspecCommand(
+          pubspecYamlFile.toNativePath(), overrides,
+          destinationFile: modifiedYamlFile.toNativePath()));
+      commands.add(CommandBuilder.instance.getPubCommand(
+          "get", pubPath, checkoutDirectory, pubCacheDirectory.toNativePath()));
+      if (new Directory(packageLinkTarget.toNativePath()).existsSync()) {
+        commands.add(CommandBuilder.instance.getMakeSymlinkCommand(
+            packageLink.toNativePath(), packageLinkTarget.toNativePath()));
+      }
+      commands.add(CommandBuilder.instance.getMakeSymlinkCommand(
+          expectLink.toNativePath(), expectLinkTarget.toNativePath()));
+
+      return {
+        'commands' : commands,
+        'package-root' : newPackageRoot,
+      };
+    }
+
+    // If this test is inside a package, we will check if there is a
+    // pubspec.yaml file and if so, create a custom package root for it.
+    List<Command> baseCommands = <Command>[];
+    Path packageRoot;
+    if (configuration['use_repository_packages'] ||
+        configuration['use_public_packages']) {
+        Path pubspecYamlFile = findPubspecYamlFile(filePath);
+        if (pubspecYamlFile != null) {
+          var result = buildSpecialPackageRoot(pubspecYamlFile);
+          baseCommands.addAll(result['commands']);
+          packageRoot = result['package-root'];
+          if (optionsFromFile['packageRoot'] == null ||
+              optionsFromFile['packageRoot'] == "") {
+            optionsFromFile['packageRoot'] = packageRoot.toNativePath();
+          }
+      }
+    }
     String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath,
         multitestName: optionsFromFile['isMultitest'] ? info.multitestKey : "");
 
@@ -673,7 +934,7 @@
       // If a compile-time error is expected, and we're testing a
       // compiler, we never need to attempt to run the program (in a
       // browser or otherwise).
-      enqueueStandardTest(info, testName, expectations);
+      enqueueStandardTest(baseCommands, info, testName, expectations);
     } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) {
       if (info.optionsFromFile['isMultiHtmlTest']) {
         // A browser multi-test has multiple expectations for one test file.
@@ -685,16 +946,20 @@
           multiHtmlTestExpectations[fullTestName] =
               testExpectations.expectations(fullTestName);
         }
-        enqueueBrowserTest(info, testName, multiHtmlTestExpectations);
+        enqueueBrowserTest(baseCommands, packageRoot, info, testName,
+            multiHtmlTestExpectations);
       } else {
-        enqueueBrowserTest(info, testName, expectations);
+        enqueueBrowserTest(
+            baseCommands, packageRoot, info, testName, expectations);
       }
     } else {
-      enqueueStandardTest(info, testName, expectations);
+      enqueueStandardTest(
+          baseCommands, info, testName, expectations);
     }
   }
 
-  void enqueueStandardTest(TestInformation info,
+  void enqueueStandardTest(List<Command> baseCommands,
+                           TestInformation info,
                            String testName,
                            Set<Expectation> expectations) {
     var commonArguments = commonArgumentsFromFile(info.filePath,
@@ -709,9 +974,11 @@
         allVmOptions = new List.from(vmOptions)..addAll(extraVmOptions);
       }
 
+      var commands = []..addAll(baseCommands);
+      commands.addAll(makeCommands(info, allVmOptions, commonArguments));
       enqueueNewTestCase(
           new TestCase('$suiteName/$testName',
-                       makeCommands(info, allVmOptions, commonArguments),
+                       commands,
                        configuration,
                        expectations,
                        isNegative: isNegative(info),
@@ -743,16 +1010,21 @@
           dart2JsBootstrapDependencies, compilerPath, args,
           environmentOverrides);
 
+      var javascriptFile = '$tempDir/out.js';
+      if (configuration['csp']) {
+        javascriptFile = '$tempDir/out.precompiled.js';
+      }
+
       List<Command> commands = <Command>[command];
       if (info.hasCompileError) {
         // Do not attempt to run the compiled result. A compilation
         // error should be reported by the compilation command.
       } else if (configuration['runtime'] == 'd8') {
         commands.add(CommandBuilder.instance.getJSCommandlineCommand(
-            "d8", d8FileName, ['$tempDir/out.js'], environmentOverrides));
+            "d8", d8FileName, [javascriptFile], environmentOverrides));
       } else if (configuration['runtime'] == 'jsshell') {
         commands.add(CommandBuilder.instance.getJSCommandlineCommand(
-            "jsshell", jsShellFileName, ['$tempDir/out.js'],
+            "jsshell", jsShellFileName, [javascriptFile],
             environmentOverrides));
       }
       return commands;
@@ -883,12 +1155,12 @@
   }
 
   void _createWrapperFile(String dartWrapperFilename,
-                          Path dartLibraryFilename) {
+                          Path localDartLibraryFilename) {
     File file = new File(dartWrapperFilename);
     RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE);
 
-    var usePackageImport = dartLibraryFilename.segments().contains("pkg");
-    var libraryPathComponent = _createUrlPathFromFile(dartLibraryFilename);
+    var usePackageImport = localDartLibraryFilename.segments().contains("pkg");
+    var libraryPathComponent = _createUrlPathFromFile(localDartLibraryFilename);
     var generatedSource = dartTestWrapper(libraryPathComponent);
     dartWrapper.writeStringSync(generatedSource);
     dartWrapper.closeSync();
@@ -907,9 +1179,14 @@
    * subTestName, Set<String>> if we are running a browser multi-test (one
    * compilation and many browser runs).
    */
-  void enqueueBrowserTest(TestInformation info,
+  void enqueueBrowserTest(List<Command> baseCommands,
+                          Path packageRoot,
+                          TestInformation info,
                           String testName,
                           expectations) {
+    // TODO(Issue 14651): If we're on dartium, we need to pass [packageRoot]
+    // on to the browser (it may be test specific).
+
     // TODO(kustermann/ricow): This method should be refactored.
     Map optionsFromFile = info.optionsFromFile;
     Path filePath = info.filePath;
@@ -948,7 +1225,7 @@
 
       // Construct the command(s) that compile all the inputs needed by the
       // browser test. For running Dart in DRT, this will be noop commands.
-      List<Command> commands = [];
+      List<Command> commands = []..addAll(baseCommands);
 
       // Use existing HTML document if available.
       String htmlPath;
@@ -1142,41 +1419,6 @@
         'polymer_deploy', vmFileName, args, environmentOverrides);
   }
 
-  /**
-   * Create a directory for the generated test.  If a Dart language test
-   * needs to be run in a browser, the Dart test needs to be embedded in
-   * an HTML page, with a testing framework based on scripting and DOM events.
-   * These scripts and pages are written to a generated_test directory
-   * inside the build directory of the checkout.
-   *
-   * Those tests which are already HTML web applications (web tests), with
-   * resources including CSS files and HTML files, need to be compiled into
-   * a work directory where the relative URLS to the resources work.
-   * We use a subdirectory of the build directory that is the same number
-   * of levels down in the checkout as the original path of the web test.
-   */
-  String createOutputDirectory(Path testPath, String optionsName) {
-    // Create
-    // '[build dir]/generated_tests/$compiler-$runtime-$flags/$testUniqueName'.
-    var checked = configuration['checked'] ? '-checked' : '';
-    var minified = configuration['minified'] ? '-minified' : '';
-    var csp = configuration['csp'] ? '-csp' : '';
-    var dirName = "${configuration['compiler']}-${configuration['runtime']}"
-                  "$checked$minified$csp";
-    return createGeneratedTestDirectoryHelper(
-        "tests", dirName, testPath, optionsName);
-  }
-
-  String createCompilationOutputDirectory(Path testPath) {
-    // Create
-    // '[build dir]/generated_compilations/$compiler-$flags/$testUniqueName'.
-    var checked = configuration['checked'] ? '-checked' : '';
-    var minified = configuration['minified'] ? '-minified' : '';
-    var dirName = "${configuration['compiler']}$checked$minified";
-    return createGeneratedTestDirectoryHelper(
-        "compilations", dirName, testPath, "");
-  }
-
   String createGeneratedTestDirectoryHelper(
       String name, String dirname, Path testPath, String optionsName) {
     Path relative = testPath.relativeTo(TestUtils.dartDir());
@@ -1582,6 +1824,114 @@
   bool get listRecursively => true;
 }
 
+class PkgBuildTestSuite extends TestSuite {
+  final String statusFilePath;
+
+  PkgBuildTestSuite(Map configuration, String suiteName, this.statusFilePath)
+      : super(configuration, suiteName) {
+    assert(configuration['use_sdk']);;
+  }
+
+  void forEachTest(void onTest(TestCase testCase), _, [void onDone()]) {
+    bool fileExists(Path path) => new File(path.toNativePath()).existsSync();
+
+    bool dirExists(Path path)
+        => new Directory(path.toNativePath()).existsSync();
+
+    enqueueTestCases(Map<String, String> localPackageDirectories,
+                     Map<String, String> localSampleDirectories,
+                     TestExpectations testExpectations) {
+      enqueueTestCase(String packageName, String directory) {
+        var absoluteDirectoryPath = new Path(directory);
+
+        // Early return if this package is not using pub.
+        if (!fileExists(absoluteDirectoryPath.append('pubspec.yaml'))) {
+          return;
+        }
+
+        var directoryPath =
+            absoluteDirectoryPath.relativeTo(TestUtils.dartDir());
+        var testName = "$directoryPath";
+        var displayName = '$suiteName/$testName';
+        var packageName = directoryPath.filename;
+
+        // Collect necessary paths for pubspec.yaml overrides, pub-cache, ...
+        var checkoutDir =
+            createPubPackageBuildsDirectory(absoluteDirectoryPath);
+        var cacheDir = new Path(checkoutDir).append("pub-cache").toNativePath();
+        var pubspecYamlFile =
+            new Path(checkoutDir).append('pubspec.yaml').toNativePath();
+
+        var packageDirectories = {};
+        if (!configuration['use_public_packages']) {
+          packageDirectories = new Map.from(localPackageDirectories);
+          if (packageDirectories.containsKey(packageName)) {
+            packageDirectories.remove(packageName);
+          }
+        }
+        var dependencyOverrides =
+            buildPubspecDependencyOverrides(packageDirectories);
+
+        // Build all commands
+        var commands = new List<Command>();
+        commands.add(
+            CommandBuilder.instance.getCopyCommand(directory, checkoutDir));
+        commands.add(CommandBuilder.instance.getModifyPubspecCommand(
+            pubspecYamlFile, dependencyOverrides));
+        commands.add(CommandBuilder.instance.getPubCommand(
+            "get", pubPath, checkoutDir, cacheDir));
+
+        bool containsWebDirectory = dirExists(directoryPath.append('web'));
+        bool containsBuildDartFile =
+            fileExists(directoryPath.append('build.dart'));
+        if (containsBuildDartFile) {
+          var dartBinary = new File(dartPath).absolute.path;
+
+          commands.add(CommandBuilder.instance.getProcessCommand(
+              "custom_build", dartBinary, ['build.dart'], null,
+              checkoutDir));
+
+          // We only try to deploy the application if it's a webapp.
+          if (containsWebDirectory) {
+            commands.add(CommandBuilder.instance.getProcessCommand(
+                 "custom_deploy", dartBinary, ['build.dart', '--deploy'], null,
+                 checkoutDir));
+          }
+        } else if (containsWebDirectory)  {
+          commands.add(CommandBuilder.instance.getPubCommand(
+             "build", pubPath, checkoutDir, cacheDir));
+        }
+
+        // Enqueue TestCase
+        var testCase = new TestCase(displayName,
+            commands, configuration, testExpectations.expectations(testName));
+        enqueueNewTestCase(testCase);
+      }
+
+      localPackageDirectories.forEach(enqueueTestCase);
+      localSampleDirectories.forEach(enqueueTestCase);
+
+      // Notify we're done
+      if (onDone != null) onDone();
+    }
+
+    doTest = onTest;
+    Map<String, String> _localPackageDirectories;
+    Map<String, String> _localSampleDirectories;
+    List<String> statusFiles = [
+        TestUtils.dartDir().join(new Path(statusFilePath)).toNativePath()];
+    ReadTestExpectations(statusFiles, configuration).then((expectations) {
+      Future.wait([discoverPackagesInRepository(),
+                   discoverSamplesInRepository()]).then((List results) {
+        Map packageDirectories = results[0];
+        Map sampleDirectories = results[1];
+        enqueueTestCases(packageDirectories, sampleDirectories, expectations);
+      });
+    });
+  }
+}
+
+
 class LastModifiedCache {
   Map<String, DateTime> _cache = <String, DateTime>{};
 
@@ -1607,6 +1957,22 @@
   }
 }
 
+class ExistsCache {
+  Map<String, bool> _cache = <String, bool>{};
+
+  /**
+   * Returns true if the file in [path] exists, false otherwise.
+   *
+   * The information will be cached.
+   */
+  bool doesFileExist(String path) {
+    if (!_cache.containsKey(path)) {
+      _cache[path] = new File(path).existsSync();
+    }
+    return _cache[path];
+  }
+}
+
 class TestUtils {
   /**
    * The libraries in this directory relies on finding various files
@@ -1616,6 +1982,7 @@
    */
   static String testScriptPath = new Path(Platform.script.path).toNativePath();
   static LastModifiedCache lastModifiedCache = new LastModifiedCache();
+  static ExistsCache existsCache = new ExistsCache();
   static Path currentWorkingDirectory =
       new Path(Directory.current.path);
   /**
@@ -1655,6 +2022,24 @@
         .pipe(new File(dest.toNativePath()).openWrite());
   }
 
+  static Future copyDirectory(String source, String dest) {
+    source = new Path(source).toNativePath();
+    dest = new Path(dest).toNativePath();
+
+    var executable = 'cp';
+    var args = ['-Rp', source, dest];
+    if (Platform.operatingSystem == 'windows') {
+      executable = 'xcopy';
+      args = [source, dest, '/e', '/i'];
+    }
+    return Process.run(executable, args).then((ProcessResult result) {
+      if (result.exitCode != 0) {
+        throw new Exception("Failed to execute '$executable "
+            "${args.join(' ')}'.");
+      }
+    });
+  }
+
   static Path debugLogfile() {
     return new Path(".debug.log");
   }
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index eacba54..cb3f802d 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -10,6 +10,15 @@
 
 part 'legacy_path.dart';
 
+// This is the maximum time we expect stdout/stderr of subprocesses to deliver
+// data after we've got the exitCode.
+const Duration MAX_STDIO_DELAY = const Duration(seconds: 30);
+
+String MAX_STDIO_DELAY_PASSED_MESSAGE =
+"""Not waiting for stdout/stderr from subprocess anymore 
+($MAX_STDIO_DELAY passed). Please note that this could be an indicator 
+that there is a hanging process which we were unable to kill.""";
+
 class DebugLogger {
   static IOSink _sink;
 
@@ -233,6 +242,19 @@
     _value = ((_value * 31) ^ object.hashCode)  & 0x3FFFFFFF;
   }
 
+  void addJson(Object object) {
+    if (object == null || object is num || object is String) {
+      add(object);
+    } else if (object is List) {
+      object.forEach(addJson);
+    } else if (object is Map) {
+      object.forEach((k, v) { addJson(k); addJson(value); });
+    } else {
+      throw new Exception("Can't build hashcode for non json-like object "
+          "(${object.runtimeType})");
+    }
+  }
+
   int get value => _value;
 }
 
diff --git a/utils/css/css b/utils/css/css
deleted file mode 100755
index 1dcc22d..0000000
--- a/utils/css/css
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# To pre-process CSS files, run this script with the path to a .scss file, like:
-#
-# $ $DART/utils/css/css foo.scss foo.css
-#
-# To use your Dart VM must be on your $PATH e.g.,
-#
-# export PATH=$PATH:/home/<your name>/dart-all/dart/out/Release_ia32/
-
-
-SRCFILE=$PWD/$1
-OUTPUT=$PWD/$2
-if [[ $1 == $2 ]]
-then
-  echo -e "\033[31msource file must be different then output file\033[0m"
-  exit 1
-fi
-
-# Path of this bash script.
-BASE_DIR="$( cd "$( dirname "$0" )" && pwd )"
-
-# Pre-process the file
-dart $BASE_DIR/tool.dart $SRCFILE $OUTPUT
-
diff --git a/utils/css/css.dart b/utils/css/css.dart
deleted file mode 100644
index e3c74f6..0000000
--- a/utils/css/css.dart
+++ /dev/null
@@ -1,72 +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 css;
-
-import 'dart:math' as Math;
-import '../lib/file_system.dart';
-import '../lib/file_system_memory.dart';
-
-part 'cssoptions.dart';
-part 'source.dart';
-part 'tokenkind.dart';
-part 'token.dart';
-part 'tokenizer_base.dart';
-part 'tokenizer.dart';
-part 'treebase.dart';
-part 'tree.dart';
-part 'cssselectorexception.dart';
-part 'cssworld.dart';
-part 'parser.dart';
-part 'validate.dart';
-part 'generate.dart';
-part 'world.dart';
-
-
-void initCssWorld([bool commandLine = true]) {
-  FileSystem fs = new MemoryFileSystem();
-  parseOptions([], fs);
-  initializeWorld(fs);
-
-  // TODO(terry): Should be set by arguments.  When run as a tool these aren't
-  // set when run internaly set these so we can compile CSS and catch any
-  // problems programmatically.
-  options.throwOnErrors = true;
-  options.throwOnFatal = true;
-  options.useColors = commandLine ? true : false;
-  options.warningsAsErrors = false;
-  options.showWarnings = true;
-}
-
-// TODO(terry): Add obfuscation mapping file.
-void cssParseAndValidate(String cssExpression, CssWorld cssworld) {
-  Parser parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      cssExpression));
-  var tree = parser.parseTemplate();
-  if (tree != null) {
-    Validate.template(tree.selectors, cssworld);
-  }
-}
-
-// Returns pretty printed tree of the expression.
-String cssParseAndValidateDebug(String cssExpression, CssWorld cssworld) {
-  Parser parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      cssExpression));
-  String output = "";
-  String prettyTree = "";
-  try {
-    var tree = parser.parseTemplate();
-    if (tree != null) {
-      prettyTree = tree.toDebugString();
-      Validate.template(tree.selectors, cssworld);
-      output = prettyTree;
-    }
-  } catch (e) {
-    String error = e.toString();
-    output = "$error\n$prettyTree";
-    throw e;
-  }
-
-  return output;
-}
diff --git a/utils/css/css.html b/utils/css/css.html
deleted file mode 100755
index bf1ec18..0000000
--- a/utils/css/css.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <head>
-    <title>CSS UITest</title>
-  </head>
-  <body>
-    <script type="application/dart" src="uitest.dart"></script>
-  </body>
-</html>
diff --git a/utils/css/cssoptions.dart b/utils/css/cssoptions.dart
deleted file mode 100644
index 8193d65..0000000
--- a/utils/css/cssoptions.dart
+++ /dev/null
@@ -1,93 +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.
-
-/** General options used by the compiler. */
-CSSOptions options;
-
-/** Extracts options from command-line arguments. */
-void parseOptions(List<String> args, var files) {
-  assert(options == null);
-  options = new CSSOptions(args, files);
-}
-
-class CSSOptions {
-  /** Location of corelib and other special dart libraries. */
-  String libDir;
-
-  /* The top-level dart script to compile. */
-  String dartScript;
-
-  /** Where to place the generated code. */
-  String outfile;
-
-  // Options that modify behavior significantly
-
-  bool warningsAsErrors = false;
-  bool checkOnly = false;
-
-  // Message support
-  bool throwOnErrors = false;
-  bool throwOnWarnings = false;
-  bool throwOnFatal = false;
-  bool showInfo = false;
-  bool showWarnings = true;
-  bool useColors = true;
-
-  /**
-   * Options to be used later for passing to the generated code. These are all
-   * the arguments after the first dart script, if any.
-   */
-  List<String> childArgs;
-
-  CSSOptions(List<String> args, var files) {
-    bool ignoreUnrecognizedFlags = false;
-    bool passedLibDir = false;
-    childArgs = [];
-
-    // Start from 2 to skip arguments representing the compiler command
-    // (python followed by frog.py).
-    for (int i = 2; i < args.length; i++) {
-      var arg = args[i];
-
-      switch (arg) {
-        case '--check-only':
-          checkOnly = true;
-          break;
-
-        case '--verbose':
-          showInfo = true;
-          break;
-
-        case '--suppress_warnings':
-          showWarnings = false;
-          break;
-
-        case '--warnings_as_errors':
-          warningsAsErrors = true;
-          break;
-
-        case '--throw_on_errors':
-          throwOnErrors = true;
-          break;
-
-        case '--throw_on_warnings':
-          throwOnWarnings = true;
-          break;
-
-        case '--no_colors':
-          useColors = false;
-          break;
-
-        case '--checked':
-          checkOnly = true;
-          break;
-
-        default:
-          if (!ignoreUnrecognizedFlags) {
-            print('unrecognized flag: "$arg"');
-          }
-      }
-    }
-  }
-}
diff --git a/utils/css/cssselectorexception.dart b/utils/css/cssselectorexception.dart
deleted file mode 100644
index 2077ed7..0000000
--- a/utils/css/cssselectorexception.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(terry): Rename CompilerException to be SourceException then this
-//              exception would be derived from SourceException.
-
-/** Can be thrown on any Css runtime problem includes source location. */
-class CssSelectorException implements Exception {
-  final String _message;
-  final SourceSpan _location;
-
-  CssSelectorException(this._message, [this._location = null]);
-
-  String toString() {
-    if (_location != null) {
-      return 'CssSelectorException: ${_location.toMessageString(_message)}';
-    } else {
-      return 'CssSelectorException: $_message';
-    }
-  }
-
-}
diff --git a/utils/css/cssworld.dart b/utils/css/cssworld.dart
deleted file mode 100644
index 281b2b7..0000000
--- a/utils/css/cssworld.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class CssWorld {
-  List<String> classes;
-  List<String> ids;
-
-  CssWorld(this.classes, this.ids) {
-    // Insure no private class names in our CSS world (._foo).
-    for (final aClass in classes) {
-      if (aClass.startsWith('_')) {
-        throw new CssSelectorException(
-            "private class ('_' prefix) not valid for CssWorld $aClass)");
-      }
-    }
-
-    // Insure no private element ids in our CSS world (#_foo).
-    for (final id in ids) {
-      if (id.startsWith('_')) {
-        throw new CssSelectorException(
-            "private id ('_' prefix) not valid for CssWorld $id)");
-      }
-    }
-  }
-}
diff --git a/utils/css/generate.dart b/utils/css/generate.dart
deleted file mode 100644
index 2d24845..0000000
--- a/utils/css/generate.dart
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Generate {
-
-  // Build up list of all known class selectors in all CSS files.
-  static List<String> computeClassSelectors(RuleSet ruleset, classes) {
-    for (final selector in ruleset.selectorGroup.selectors) {
-      var selSeqs = selector.simpleSelectorSequences;
-      for (final selSeq in selSeqs) {
-        var simpleSelector = selSeq.simpleSelector;
-        if (simpleSelector is ClassSelector) {
-          String className = simpleSelector.name;
-          if (classes.indexOf(className) == -1) {   // Class name already known?
-            // No, expose it.
-            classes.add(className);
-          }
-        }
-      }
-    }
-
-    return classes;
-  }
-
-  static dartClass(var files, String outPath, Stylesheet stylesheet,
-      String filename) {
-
-    List<String> knownClasses = [];
-
-    StringBuffer buff = new StringBuffer(
-        '// File generated by Dart CSS from source file ${filename}\n' +
-        '// Do not edit.\n\n');
-
-    // Emit class for any @stylet directive.
-    for (final production in stylesheet._topLevels) {
-      if (production is Directive) {
-        if (production is StyletDirective) {
-          // TODO(terry): Need safer mechanism for stylets in different files
-          //              and stylets with colliding names.
-          buff.write('class ${production.dartClassName} {\n');
-          buff.write('  // selector, properties<propertyName, value>\n');
-          buff.write('  static const selectors = const {\n');
-
-          for (final ruleset in production.rulesets) {
-            for (final selector in ruleset.selectorGroup.selectors) {
-              var selSeq = selector.simpleSelectorSquences;
-              if (selSeq.length == 1) {
-                buff.write('    \'${selSeq.toString()}\' : const {\n');
-              }
-            }
-
-            for (final decl in ruleset.declarationGroup.declarations) {
-              buff.write('      \'${decl.property}\' : ' +
-                  '\'${decl.expression.toString()}\',\n');
-            }
-            buff.write('    },\n');   // End of declarations for stylet class.
-          }
-          buff.write('  };\n');       // End of static selectors constant.
-          buff.write('}\n\n');        // End of stylet class
-        } else if (production is IncludeDirective) {
-          for (final topLevel in production.styleSheet._topLevels) {
-            if (topLevel is RuleSet) {
-              knownClasses = computeClassSelectors(topLevel, knownClasses);
-            }
-          }
-        }
-      } else if (production is RuleSet) {
-        knownClasses = computeClassSelectors(production, knownClasses);
-      }
-    }
-
-    // Generate all known classes encountered in all processed CSS files.
-    StringBuffer classSelectors = new StringBuffer(
-      'class CSS {\n' +
-      '  // CSS class selectors:\n');
-    for (final className in knownClasses) {
-      String classAsDart = className.replaceAll('-', '_').toUpperCase();
-      classSelectors.write('  static const String ${classAsDart} = ' +
-          '\'${className}\';\n');
-    }
-    classSelectors.write('}\n');            // End of class selectors.
-    buff.write(classSelectors.toString());
-
-    // Write Dart file.
-    String outFile = '${outPath}CSS.dart';
-    files.writeString(outFile, buff.toString());
-
-    return outFile;
-  }
-}
-
diff --git a/utils/css/parser.dart b/utils/css/parser.dart
deleted file mode 100644
index a865bdf..0000000
--- a/utils/css/parser.dart
+++ /dev/null
@@ -1,1017 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-
-/**
- * A simple recursive descent parser for CSS.
- */
-class Parser {
-  Tokenizer tokenizer;
-
-  var _fs;                        // If non-null filesystem to read files.
-  String _basePath;               // Base path of CSS file.
-
-  final SourceFile source;
-
-  Token _previousToken;
-  Token _peekToken;
-
-// Communicating errors back to template parser.
-// TODO(terry): Need a better mechanism (e.g., common World).
-  var _erroMsgRedirector;
-
-  Parser(this.source, [int start = 0, this._fs = null, this._basePath = null]) {
-    tokenizer = new Tokenizer(source, true, start);
-    _peekToken = tokenizer.next();
-    _previousToken = null;
-  }
-
-  // Main entry point for parsing an entire CSS file.
-  // If nestedCSS is true when we're back at processing directives from top and
-  // we encounter a } then stop we're inside of a template e.g.,
-  //
-  //       template ... {
-  //          css {
-  //            .item {
-  //               left: 10px;
-  //            }
-  //          }
-  //          <div>...</div>
-  //       }
-  //
-  Stylesheet parse([bool nestedCSS = false, var erroMsgRedirector = null]) {
-    // TODO(terry): Hack for migrating CSS errors back to template errors.
-    _erroMsgRedirector = erroMsgRedirector;
-
-    List<ASTNode> productions = [];
-
-    int start = _peekToken.start;
-    while (!_maybeEat(TokenKind.END_OF_FILE) &&
-           (!nestedCSS && !_peekKind(TokenKind.RBRACE))) {
-      // TODO(terry): Need to handle charset, import, media and page.
-      var directive = processDirective();
-      if (directive != null) {
-        productions.add(directive);
-      } else {
-        RuleSet ruleset = processRuleSet();
-        if (ruleset != null) {
-          productions.add(ruleset);
-        } else {
-          break;
-        }
-      }
-    }
-
-    return new Stylesheet(productions, _makeSpan(start));
-  }
-
-  /** Generate an error if [source] has not been completely consumed. */
-  void checkEndOfFile() {
-    _eat(TokenKind.END_OF_FILE);
-  }
-
-  /** Guard to break out of parser when an unexpected end of file is found. */
-  // TODO(jimhug): Failure to call this method can lead to inifinite parser
-  //   loops.  Consider embracing exceptions for more errors to reduce
-  //   the danger here.
-  bool isPrematureEndOfFile() {
-    if (_maybeEat(TokenKind.END_OF_FILE)) {
-      _error('unexpected end of file', _peekToken.span);
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  ///////////////////////////////////////////////////////////////////
-  // Basic support methods
-  ///////////////////////////////////////////////////////////////////
-  int _peek() {
-    return _peekToken.kind;
-  }
-
-  Token _next() {
-    _previousToken = _peekToken;
-    _peekToken = tokenizer.next();
-    return _previousToken;
-  }
-
-  bool _peekKind(int kind) {
-    return _peekToken.kind == kind;
-  }
-
-  /* Is the next token a legal identifier?  This includes pseudo-keywords. */
-  bool _peekIdentifier() {
-    return TokenKind.isIdentifier(_peekToken.kind);
-  }
-
-  bool _maybeEat(int kind) {
-    if (_peekToken.kind == kind) {
-      _previousToken = _peekToken;
-      _peekToken = tokenizer.next();
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  void _eat(int kind) {
-    if (!_maybeEat(kind)) {
-      _errorExpected(TokenKind.kindToString(kind));
-    }
-  }
-
-  void _eatSemicolon() {
-    _eat(TokenKind.SEMICOLON);
-  }
-
-  void _errorExpected(String expected) {
-    var tok = _next();
-    var message;
-    try {
-      message = 'expected $expected, but found $tok';
-    } catch (e) {
-      message = 'parsing error expected $expected';
-    }
-    _error(message, tok.span);
-  }
-
-  void _error(String message, [SourceSpan location=null]) {
-    if (location == null) {
-      location = _peekToken.span;
-    }
-
-    if (_erroMsgRedirector == null) {
-       world.fatal(message, location);    // syntax errors are fatal for now
-    } else {
-      String text = "";
-      if (location != null) {
-        text = location.toMessageString("");
-      }
-      _erroMsgRedirector.displayError("CSS error: \r${text}\r${message}");
-    }
-  }
-
-  void _warning(String message, [SourceSpan location=null]) {
-    if (location == null) {
-      location = _peekToken.span;
-    }
-
-    world.warning(message, location);
-  }
-
-  SourceSpan _makeSpan(int start) {
-    return new SourceSpan(source, start, _previousToken.end);
-  }
-
-  ///////////////////////////////////////////////////////////////////
-  // Top level productions
-  ///////////////////////////////////////////////////////////////////
-
-  // Templates are @{selectors} single line nothing else.
-  SelectorGroup parseTemplate() {
-    SelectorGroup selectorGroup = null;
-    if (!isPrematureEndOfFile()) {
-      selectorGroup = templateExpression();
-    }
-
-    return selectorGroup;
-  }
-
-  /*
-   * Expect @{css_expression}
-   */
-  templateExpression() {
-    List<Selector> selectors = [];
-
-    int start = _peekToken.start;
-
-    _eat(TokenKind.AT);
-    _eat(TokenKind.LBRACE);
-
-    selectors.add(processSelector());
-    SelectorGroup group = new SelectorGroup(selectors, _makeSpan(start));
-
-    _eat(TokenKind.RBRACE);
-
-    return group;
-  }
-
-  ///////////////////////////////////////////////////////////////////
-  // Productions
-  ///////////////////////////////////////////////////////////////////
-
-  processMedia([bool oneRequired = false]) {
-    List<String> media = [];
-
-    while (_peekIdentifier()) {
-      // We have some media types.
-      var medium = identifier();   // Medium ident.
-      media.add(medium);
-      if (!_maybeEat(TokenKind.COMMA)) {
-        // No more media types exit now.
-        break;
-      }
-    }
-
-    if (oneRequired && media.length == 0) {
-      _error('at least one media type required', _peekToken.span);
-    }
-
-    return media;
-  }
-
-  //  Directive grammar:
-  //
-  //  import:       '@import' [string | URI] media_list?
-  //  media:        '@media' media_list '{' ruleset '}'
-  //  page:         '@page' [':' IDENT]? '{' declarations '}'
-  //  include:      '@include' [string | URI]
-  //  stylet:       '@stylet' IDENT '{' ruleset '}'
-  //  media_list:   IDENT [',' IDENT]
-  //  keyframes:    '@-webkit-keyframes ...' (see grammar below).
-  //  font_face:    '@font-face' '{' declarations '}'
-  //
-  processDirective() {
-    int start = _peekToken.start;
-
-    if (_maybeEat(TokenKind.AT)) {
-      switch (_peek()) {
-      case TokenKind.DIRECTIVE_IMPORT:
-        _next();
-
-        String importStr;
-        if (_peekIdentifier()) {
-          var func = processFunction(identifier());
-          if (func is UriTerm) {
-            importStr = func.text;
-          }
-        } else {
-          importStr = processQuotedString(false);
-        }
-
-        // Any medias?
-        List<String> medias = processMedia();
-
-        if (importStr == null) {
-          _error('missing import string', _peekToken.span);
-        }
-        return new ImportDirective(importStr, medias, _makeSpan(start));
-      case TokenKind.DIRECTIVE_MEDIA:
-        _next();
-
-        // Any medias?
-        List<String> media = processMedia(true);
-        RuleSet ruleset;
-
-        if (_maybeEat(TokenKind.LBRACE)) {
-          ruleset = processRuleSet();
-          if (!_maybeEat(TokenKind.RBRACE)) {
-            _error('expected } after ruleset for @media', _peekToken.span);
-          }
-        } else {
-          _error('expected { after media before ruleset', _peekToken.span);
-        }
-        return new MediaDirective(media, ruleset, _makeSpan(start));
-      case TokenKind.DIRECTIVE_PAGE:
-        _next();
-
-        // Any pseudo page?
-        var pseudoPage;
-        if (_maybeEat(TokenKind.COLON)) {
-          if (_peekIdentifier()) {
-            pseudoPage = identifier();
-          }
-        }
-        return new PageDirective(pseudoPage, processDeclarations(),
-            _makeSpan(start));
-      case TokenKind.DIRECTIVE_KEYFRAMES:
-        /*  Key frames grammar:
-         *
-         *  @-webkit-keyframes [IDENT|STRING] '{' keyframes-blocks '}';
-         *
-         *  keyframes-blocks:
-         *    [keyframe-selectors '{' declarations '}']* ;
-         *
-         *  keyframe-selectors:
-         *    ['from'|'to'|PERCENTAGE] [',' ['from'|'to'|PERCENTAGE] ]* ;
-         */
-        _next();
-
-        var name;
-        if (_peekIdentifier()) {
-          name = identifier();
-        }
-
-        _eat(TokenKind.LBRACE);
-
-        KeyFrameDirective kf = new KeyFrameDirective(name, _makeSpan(start));
-
-        do {
-          Expressions selectors = new Expressions(_makeSpan(start));
-
-          do {
-            var term = processTerm();
-
-            // TODO(terry): Only allow from, to and PERCENTAGE ...
-
-            selectors.add(term);
-          } while (_maybeEat(TokenKind.COMMA));
-
-          kf.add(new KeyFrameBlock(selectors, processDeclarations(),
-              _makeSpan(start)));
-
-        } while (!_maybeEat(TokenKind.RBRACE));
-
-        return kf;
-      case TokenKind.DIRECTIVE_FONTFACE:
-        _next();
-
-        List<Declaration> decls = [];
-
-        // TODO(terry): To Be Implemented
-
-        return new FontFaceDirective(decls, _makeSpan(start));
-      case TokenKind.DIRECTIVE_INCLUDE:
-        _next();
-        String filename = processQuotedString(false);
-        if (_fs != null) {
-          // Does CSS file exist?
-          if (_fs.fileExists('${_basePath}${filename}')) {
-            String basePath = "";
-            int idx = filename.lastIndexOf('/');
-            if (idx >= 0) {
-              basePath = filename.substring(0, idx + 1);
-            }
-            basePath = '${_basePath}${basePath}';
-            // Yes, let's parse this file as well.
-            String fullFN = '${basePath}${filename}';
-            String contents = _fs.readAll(fullFN);
-            Parser parser = new Parser(new SourceFile(fullFN, contents), 0,
-                _fs, basePath);
-            Stylesheet stylesheet = parser.parse();
-            return new IncludeDirective(filename, stylesheet, _makeSpan(start));
-          }
-
-          _error('file doesn\'t exist ${filename}', _peekToken.span);
-        }
-
-        print("WARNING: @include doesn't work for uitest");
-        return new IncludeDirective(filename, null, _makeSpan(start));
-      case TokenKind.DIRECTIVE_STYLET:
-        /* Stylet grammar:
-        *
-        *  @stylet IDENT '{'
-        *    ruleset
-        *  '}'
-        */
-        _next();
-
-        var name;
-        if (_peekIdentifier()) {
-          name = identifier();
-        }
-
-        _eat(TokenKind.LBRACE);
-
-        List<ASTNode> productions = [];
-
-        start = _peekToken.start;
-        while (!_maybeEat(TokenKind.END_OF_FILE)) {
-          RuleSet ruleset = processRuleSet();
-          if (ruleset == null) {
-            break;
-          }
-          productions.add(ruleset);
-        }
-
-        _eat(TokenKind.RBRACE);
-
-        return new StyletDirective(name, productions, _makeSpan(start));
-      default:
-        _error('unknown directive, found $_peekToken', _peekToken.span);
-      }
-    }
-  }
-
-  RuleSet processRuleSet() {
-    int start = _peekToken.start;
-
-    SelectorGroup selGroup = processSelectorGroup();
-    if (selGroup != null) {
-      return new RuleSet(selGroup, processDeclarations(), _makeSpan(start));
-    }
-  }
-
-  DeclarationGroup processDeclarations() {
-    int start = _peekToken.start;
-
-    _eat(TokenKind.LBRACE);
-
-    List<Declaration> decls = [];
-    do {
-      Declaration decl = processDeclaration();
-      if (decl != null) {
-        decls.add(decl);
-      }
-    } while (_maybeEat(TokenKind.SEMICOLON));
-
-    _eat(TokenKind.RBRACE);
-
-    return new DeclarationGroup(decls, _makeSpan(start));
-  }
-
-  SelectorGroup processSelectorGroup() {
-    List<Selector> selectors = [];
-    int start = _peekToken.start;
-    do {
-      Selector selector = processSelector();
-      if (selector != null) {
-        selectors.add(selector);
-      }
-    } while (_maybeEat(TokenKind.COMMA));
-
-    if (selectors.length > 0) {
-      return new SelectorGroup(selectors, _makeSpan(start));
-    }
-  }
-
-  /* Return list of selectors
-   *
-   */
-  processSelector() {
-    List<SimpleSelectorSequence> simpleSequences = [];
-    int start = _peekToken.start;
-    while (true) {
-      // First item is never descendant make sure it's COMBINATOR_NONE.
-      var selectorItem = simpleSelectorSequence(simpleSequences.length == 0);
-      if (selectorItem != null) {
-        simpleSequences.add(selectorItem);
-      } else {
-        break;
-      }
-    }
-
-    if (simpleSequences.length > 0) {
-      return new Selector(simpleSequences, _makeSpan(start));
-    }
-  }
-
-  simpleSelectorSequence(bool forceCombinatorNone) {
-    int start = _peekToken.start;
-    int combinatorType = TokenKind.COMBINATOR_NONE;
-
-    switch (_peek()) {
-      case TokenKind.PLUS:
-        _eat(TokenKind.PLUS);
-        combinatorType = TokenKind.COMBINATOR_PLUS;
-        break;
-      case TokenKind.GREATER:
-        _eat(TokenKind.GREATER);
-        combinatorType = TokenKind.COMBINATOR_GREATER;
-        break;
-      case TokenKind.TILDE:
-        _eat(TokenKind.TILDE);
-        combinatorType = TokenKind.COMBINATOR_TILDE;
-        break;
-    }
-
-    // Check if WHITESPACE existed between tokens if so we're descendent.
-    if (combinatorType == TokenKind.COMBINATOR_NONE && !forceCombinatorNone) {
-      if (this._previousToken != null &&
-          this._previousToken.end != this._peekToken.start) {
-        combinatorType = TokenKind.COMBINATOR_DESCENDANT;
-      }
-    }
-
-    var simpleSel = simpleSelector();
-    if (simpleSel != null) {
-      return new SimpleSelectorSequence(simpleSel, _makeSpan(start),
-          combinatorType);
-    }
-  }
-
-  /**
-   * Simple selector grammar:
-   *
-   *    simple_selector_sequence
-   *       : [ type_selector | universal ]
-   *         [ HASH | class | attrib | pseudo | negation ]*
-   *       | [ HASH | class | attrib | pseudo | negation ]+
-   *    type_selector
-   *       : [ namespace_prefix ]? element_name
-   *    namespace_prefix
-   *       : [ IDENT | '*' ]? '|'
-   *    element_name
-   *       : IDENT
-   *    universal
-   *       : [ namespace_prefix ]? '*'
-   *    class
-   *       : '.' IDENT
-   */
-  simpleSelector() {
-    // TODO(terry): Nathan makes a good point parsing of namespace and element
-    //              are essentially the same (asterisk or identifier) other
-    //              than the error message for element.  Should consolidate the
-    //              code.
-    // TODO(terry): Need to handle attribute namespace too.
-    var first;
-    int start = _peekToken.start;
-    switch (_peek()) {
-      case TokenKind.ASTERISK:
-        // Mark as universal namespace.
-        var tok = _next();
-        first = new Wildcard(_makeSpan(tok.start));
-        break;
-      case TokenKind.IDENTIFIER:
-        int startIdent = _peekToken.start;
-        first = identifier();
-        break;
-    }
-
-    if (_maybeEat(TokenKind.NAMESPACE)) {
-      var element;
-      switch (_peek()) {
-        case TokenKind.ASTERISK:
-          // Mark as universal element
-          var tok = _next();
-          element = new Wildcard(_makeSpan(tok.start));
-          break;
-        case TokenKind.IDENTIFIER:
-          element = identifier();
-          break;
-        default:
-          _error('expected element name or universal(*), but found $_peekToken',
-              _peekToken.span);
-      }
-
-      return new NamespaceSelector(first,
-          new ElementSelector(element, element.span), _makeSpan(start));
-    } else if (first != null) {
-      return new ElementSelector(first, _makeSpan(start));
-    } else {
-      // Check for HASH | class | attrib | pseudo | negation
-      return simpleSelectorTail();
-    }
-  }
-
-  simpleSelectorTail() {
-    // Check for HASH | class | attrib | pseudo | negation
-    int start = _peekToken.start;
-    switch (_peek()) {
-      case TokenKind.HASH:
-        _eat(TokenKind.HASH);
-        return new IdSelector(identifier(), _makeSpan(start));
-      case TokenKind.DOT:
-        _eat(TokenKind.DOT);
-        return new ClassSelector(identifier(), _makeSpan(start));
-      case TokenKind.COLON:
-        // :pseudo-class ::pseudo-element
-        // TODO(terry): '::' should be token.
-        _eat(TokenKind.COLON);
-        bool pseudoElement = _maybeEat(TokenKind.COLON);
-        var name = identifier();
-        // TODO(terry): Need to handle specific pseudo class/element name and
-        // backward compatible names that are : as well as :: as well as
-        // parameters.
-        return pseudoElement ?
-            new PseudoElementSelector(name, _makeSpan(start)) :
-            new PseudoClassSelector(name, _makeSpan(start));
-      case TokenKind.LBRACK:
-        return processAttribute();
-    }
-  }
-
-  //  Attribute grammar:
-  //
-  //  attributes :
-  //    '[' S* IDENT S* [ ATTRIB_MATCHES S* [ IDENT | STRING ] S* ]? ']'
-  //
-  //  ATTRIB_MATCHES :
-  //    [ '=' | INCLUDES | DASHMATCH | PREFIXMATCH | SUFFIXMATCH | SUBSTRMATCH ]
-  //
-  //  INCLUDES:         '~='
-  //
-  //  DASHMATCH:        '|='
-  //
-  //  PREFIXMATCH:      '^='
-  //
-  //  SUFFIXMATCH:      '$='
-  //
-  //  SUBSTRMATCH:      '*='
-  //
-  //
-  processAttribute() {
-    int start = _peekToken.start;
-
-    if (_maybeEat(TokenKind.LBRACK)) {
-      var attrName = identifier();
-
-      int op = TokenKind.NO_MATCH;
-      switch (_peek()) {
-      case TokenKind.EQUALS:
-      case TokenKind.INCLUDES:        // ~=
-      case TokenKind.DASH_MATCH:      // |=
-      case TokenKind.PREFIX_MATCH:    // ^=
-      case TokenKind.SUFFIX_MATCH:    // $=
-      case TokenKind.SUBSTRING_MATCH: // *=
-        op = _peek();
-        _next();
-        break;
-      }
-
-      String value;
-      if (op != TokenKind.NO_MATCH) {
-        // Operator hit so we require a value too.
-        if (_peekIdentifier()) {
-          value = identifier();
-        } else {
-          value = processQuotedString(false);
-        }
-
-        if (value == null) {
-          _error('expected attribute value string or ident', _peekToken.span);
-        }
-      }
-
-      _eat(TokenKind.RBRACK);
-
-      return new AttributeSelector(attrName, op, value, _makeSpan(start));
-    }
-  }
-
-  //  Declaration grammar:
-  //
-  //  declaration:  property ':' expr prio?
-  //
-  //  property:  IDENT
-  //  prio:      !important
-  //  expr:      (see processExpr)
-  //
-  processDeclaration() {
-    Declaration decl;
-
-    int start = _peekToken.start;
-
-    // IDENT ':' expr '!important'?
-    if (TokenKind.isIdentifier(_peekToken.kind)) {
-      var propertyIdent = identifier();
-      _eat(TokenKind.COLON);
-
-      decl = new Declaration(propertyIdent, processExpr(), _makeSpan(start));
-
-      // Handle !important (prio)
-      decl.important = _maybeEat(TokenKind.IMPORTANT);
-    }
-
-    return decl;
-  }
-
-  //  Expression grammar:
-  //
-  //  expression:   term [ operator? term]*
-  //
-  //  operator:     '/' | ','
-  //  term:         (see processTerm)
-  //
-  processExpr() {
-    int start = _peekToken.start;
-    Expressions expressions = new Expressions(_makeSpan(start));
-
-    bool keepGoing = true;
-    var expr;
-    while (keepGoing && (expr = processTerm()) != null) {
-      var op;
-
-      int opStart = _peekToken.start;
-
-      switch (_peek()) {
-      case TokenKind.SLASH:
-        op = new OperatorSlash(_makeSpan(opStart));
-        break;
-      case TokenKind.COMMA:
-        op = new OperatorComma(_makeSpan(opStart));
-        break;
-      }
-
-      if (expr != null) {
-        expressions.add(expr);
-      } else {
-        keepGoing = false;
-      }
-
-      if (op != null) {
-        expressions.add(op);
-        _next();
-      }
-    }
-
-    return expressions;
-  }
-
-  //  Term grammar:
-  //
-  //  term:
-  //    unary_operator?
-  //    [ term_value ]
-  //    | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
-  //
-  //  term_value:
-  //    NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
-  //    TIME S* | FREQ S* | function
-  //
-  //  NUMBER:       {num}
-  //  PERCENTAGE:   {num}%
-  //  LENGTH:       {num}['px' | 'cm' | 'mm' | 'in' | 'pt' | 'pc']
-  //  EMS:          {num}'em'
-  //  EXS:          {num}'ex'
-  //  ANGLE:        {num}['deg' | 'rad' | 'grad']
-  //  TIME:         {num}['ms' | 's']
-  //  FREQ:         {num}['hz' | 'khz']
-  //  function:     IDENT '(' expr ')'
-  //
-  processTerm() {
-    int start = _peekToken.start;
-    Token t;             // token for term's value
-    var value;                // value of term (numeric values)
-
-    var unary = "";
-
-    switch (_peek()) {
-    case TokenKind.HASH:
-      this._eat(TokenKind.HASH);
-      String hexText;
-      if (_peekKind(TokenKind.INTEGER)) {
-        String hexText1 = _peekToken.text;
-        _next();
-        if (_peekIdentifier()) {
-          hexText = '${hexText1}${identifier().name}';
-        } else {
-          hexText = hexText1;
-        }
-      } else if (_peekIdentifier()) {
-        hexText = identifier().name;
-      } else {
-        _errorExpected("hex number");
-      }
-
-      try {
-        int hexValue = parseHex(hexText);
-        return new HexColorTerm(hexValue, hexText, _makeSpan(start));
-      } on HexNumberException catch (hne) {
-        _error('Bad hex number', _makeSpan(start));
-      }
-      break;
-    case TokenKind.INTEGER:
-      t = _next();
-      value = int.parse("${unary}${t.text}");
-      break;
-    case TokenKind.DOUBLE:
-      t = _next();
-      value = double.parse("${unary}${t.text}");
-      break;
-    case TokenKind.SINGLE_QUOTE:
-    case TokenKind.DOUBLE_QUOTE:
-      value = processQuotedString(false);
-      value = '"${value}"';
-      return new LiteralTerm(value, value, _makeSpan(start));
-    case TokenKind.LPAREN:
-      _next();
-
-      GroupTerm group = new GroupTerm(_makeSpan(start));
-
-      do {
-        var term = processTerm();
-        if (term != null && term is LiteralTerm) {
-          group.add(term);
-        }
-      } while (!_maybeEat(TokenKind.RPAREN));
-
-      return group;
-    case TokenKind.LBRACK:
-      _next();
-
-      var term = processTerm();
-      if (!(term is NumberTerm)) {
-        _error('Expecting a positive number', _makeSpan(start));
-      }
-
-      _eat(TokenKind.RBRACK);
-
-      return new ItemTerm(term.value, term.text, _makeSpan(start));
-    case TokenKind.IDENTIFIER:
-      var nameValue = identifier();   // Snarf up the ident we'll remap, maybe.
-
-      if (_maybeEat(TokenKind.LPAREN)) {
-        // FUNCTION
-        return processFunction(nameValue);
-      } else {
-        // TODO(terry): Need to have a list of known identifiers today only
-        //              'from' is special.
-        if (nameValue.name == 'from') {
-          return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
-        }
-
-        // What kind of identifier is it?
-        try {
-          // Named color?
-          int colorValue = TokenKind.matchColorName(nameValue.name);
-
-          // Yes, process the color as an RGB value.
-          String rgbColor = TokenKind.decimalToHex(colorValue, 3);
-          try {
-            colorValue = parseHex(rgbColor);
-          } on HexNumberException catch (hne) {
-            _error('Bad hex number', _makeSpan(start));
-          }
-          return new HexColorTerm(colorValue, rgbColor, _makeSpan(start));
-        } catch (error) {
-          if (error is NoColorMatchException) {
-            // TODO(terry): Other named things to match with validator?
-
-            // TODO(terry): Disable call to _warning need one World class for
-            //              both CSS parser and other parser (e.g., template)
-            //              so all warnings, errors, options, etc. are driven
-            //              from the one World.
-//          _warning('Unknown property value ${error.name}', _makeSpan(start));
-            return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
-          }
-        }
-      }
-    }
-
-    var term;
-    var unitType = this._peek();
-
-    switch (unitType) {
-    case TokenKind.UNIT_EM:
-      term = new EmTerm(value, t.text, _makeSpan(start));
-      _next();    // Skip the unit
-      break;
-    case TokenKind.UNIT_EX:
-      term = new ExTerm(value, t.text, _makeSpan(start));
-      _next();    // Skip the unit
-      break;
-    case TokenKind.UNIT_LENGTH_PX:
-    case TokenKind.UNIT_LENGTH_CM:
-    case TokenKind.UNIT_LENGTH_MM:
-    case TokenKind.UNIT_LENGTH_IN:
-    case TokenKind.UNIT_LENGTH_PT:
-    case TokenKind.UNIT_LENGTH_PC:
-      term = new LengthTerm(value, t.text, _makeSpan(start), unitType);
-      _next();    // Skip the unit
-      break;
-    case TokenKind.UNIT_ANGLE_DEG:
-    case TokenKind.UNIT_ANGLE_RAD:
-    case TokenKind.UNIT_ANGLE_GRAD:
-      term = new AngleTerm(value, t.text, _makeSpan(start), unitType);
-      _next();    // Skip the unit
-      break;
-    case TokenKind.UNIT_TIME_MS:
-    case TokenKind.UNIT_TIME_S:
-      term = new TimeTerm(value, t.text, _makeSpan(start), unitType);
-      _next();    // Skip the unit
-      break;
-    case TokenKind.UNIT_FREQ_HZ:
-    case TokenKind.UNIT_FREQ_KHZ:
-      term = new FreqTerm(value, t.text, _makeSpan(start), unitType);
-      _next();    // Skip the unit
-      break;
-    case TokenKind.PERCENT:
-      term = new PercentageTerm(value, t.text, _makeSpan(start));
-      _next();    // Skip the %
-      break;
-    case TokenKind.UNIT_FRACTION:
-      term = new FractionTerm(value, t.text, _makeSpan(start));
-      _next();     // Skip the unit
-      break;
-    default:
-      if (value != null) {
-        term = new NumberTerm(value, t.text, _makeSpan(start));
-      }
-    }
-
-    return term;
-  }
-
-  processQuotedString([bool urlString = false]) {
-    int start = _peekToken.start;
-
-    // URI term sucks up everything inside of quotes(' or ") or between parens
-    int stopToken = urlString ? TokenKind.RPAREN : -1;
-    switch (_peek()) {
-    case TokenKind.SINGLE_QUOTE:
-      stopToken = TokenKind.SINGLE_QUOTE;
-      _next();    // Skip the SINGLE_QUOTE.
-      break;
-    case TokenKind.DOUBLE_QUOTE:
-      stopToken = TokenKind.DOUBLE_QUOTE;
-      _next();    // Skip the DOUBLE_QUOTE.
-      break;
-    default:
-      if (urlString) {
-        if (_peek() == TokenKind.LPAREN) {
-          _next();    // Skip the LPAREN.
-        }
-        stopToken = TokenKind.RPAREN;
-      } else {
-        _error('unexpected string', _makeSpan(start));
-      }
-    }
-
-    StringBuffer stringValue = new StringBuffer();
-
-    // Gobble up everything until we hit our stop token.
-    int runningStart = _peekToken.start;
-    while (_peek() != stopToken && _peek() != TokenKind.END_OF_FILE) {
-      var tok = _next();
-      stringValue.write(tok.text);
-    }
-
-    if (stopToken != TokenKind.RPAREN) {
-      _next();    // Skip the SINGLE_QUOTE or DOUBLE_QUOTE;
-    }
-
-    return stringValue.toString();
-  }
-
-  //  Function grammar:
-  //
-  //  function:     IDENT '(' expr ')'
-  //
-  processFunction(Identifier func) {
-    int start = _peekToken.start;
-
-    String name = func.name;
-
-    switch (name) {
-    case 'url':
-      // URI term sucks up everything inside of quotes(' or ") or between parens
-      String urlParam = processQuotedString(true);
-
-      // TODO(terry): Better error messge and checking for mismatched quotes.
-      if (_peek() == TokenKind.END_OF_FILE) {
-        _error("problem parsing URI", _peekToken.span);
-      }
-
-      if (_peek() == TokenKind.RPAREN) {
-        _next();
-      }
-
-      return new UriTerm(urlParam, _makeSpan(start));
-    case 'calc':
-      // TODO(terry): Implement expression handling...
-      break;
-    default:
-      var expr = processExpr();
-      if (!_maybeEat(TokenKind.RPAREN)) {
-        _error("problem parsing function expected ), ", _peekToken.span);
-      }
-
-      return new FunctionTerm(name, name, expr, _makeSpan(start));
-    }
-
-    return null;
-  }
-
-  identifier() {
-    var tok = _next();
-    if (!TokenKind.isIdentifier(tok.kind)) {
-      _error('expected identifier, but found $tok', tok.span);
-    }
-
-    return new Identifier(tok.text, _makeSpan(tok.start));
-  }
-
-  // TODO(terry): Move this to base <= 36 and into shared code.
-  static int _hexDigit(int c) {
-    if(c >= 48/*0*/ && c <= 57/*9*/) {
-      return c - 48;
-    } else if (c >= 97/*a*/ && c <= 102/*f*/) {
-      return c - 87;
-    } else if (c >= 65/*A*/ && c <= 70/*F*/) {
-      return c - 55;
-    } else {
-      return -1;
-    }
-  }
-
-  static int parseHex(String hex) {
-    var result = 0;
-
-    for (int i = 0; i < hex.length; i++) {
-      var digit = _hexDigit(hex.codeUnitAt(i));
-      if (digit < 0) {
-        throw new HexNumberException();
-      }
-      result = (result << 4) + digit;
-    }
-
-    return result;
-  }
-}
-
-/** Not a hex number. */
-class HexNumberException implements Exception {
-  HexNumberException();
-}
-
diff --git a/utils/css/source.dart b/utils/css/source.dart
deleted file mode 100644
index 5eeb0e2..0000000
--- a/utils/css/source.dart
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(jimhug): This should be an interface to work better with tools.
-/**
- * Represents a file of source code.
- */
-class SourceFile implements Comparable<SourceFile> {
-  // TODO(terry): This filename for in memory buffer.  May need to rework if
-  //              filename is used for more than informational.
-  static String IN_MEMORY_FILE = '<buffer>';
-
-  /** The name of the file. */
-  final String filename;
-
-  /** The text content of the file. */
-  String _text;
-
-  /**
-   * The order of the source file in a given library. This is used while we're
-   * writing code for a library. A single source file can be used
-   */
-  // TODO(jmesserly): I don't like having properties that are only valid
-  // sometimes. An alternative would be to store it in a Map that's used by
-  // WorldGenerator while it's emitting code. This seems simpler.
-  int orderInLibrary;
-
-  List<int> _lineStarts;
-
-  SourceFile(this.filename, this._text);
-
-  String get text => _text;
-
-  set text(String newText) {
-    if (newText != _text) {
-      _text = newText;
-      _lineStarts = null;
-      orderInLibrary = null;
-    }
-  }
-
-  List<int> get lineStarts {
-    if (_lineStarts == null) {
-      var starts = [0];
-      var index = 0;
-      while (index < text.length) {
-        index = text.indexOf('\n', index) + 1;
-        if (index <= 0) break;
-        starts.add(index);
-      }
-      starts.add(text.length + 1);
-      _lineStarts = starts;
-    }
-    return _lineStarts;
-  }
-
-  int getLine(int position) {
-    // TODO(jimhug): Implement as binary search.
-    var starts = lineStarts;
-    for (int i=0; i < starts.length; i++) {
-      if (starts[i] > position) return i-1;
-    }
-    world.internalError('bad position');
-  }
-
-  int getColumn(int line, int position) {
-    return position - lineStarts[line];
-  }
-
-  /**
-   * Create a pretty string representation from a character position
-   * in the file.
-   */
-  String getLocationMessage(String message, int start,
-      [int end, bool includeText=false]) {
-    var line = getLine(start);
-    var column = getColumn(line, start);
-
-    var buf = new StringBuffer(
-        '${filename}:${line + 1}:${column + 1}: $message');
-    if (includeText) {
-      buf.write('\n');
-      var textLine;
-      // +1 for 0-indexing, +1 again to avoid the last line of the file
-      if ((line + 2) < _lineStarts.length) {
-        textLine = text.substring(_lineStarts[line], _lineStarts[line+1]);
-      } else {
-        textLine = text.substring(_lineStarts[line]) + '\n';
-      }
-
-      int toColumn = Math.min(column + (end-start), textLine.length);
-      if (options.useColors) {
-        buf.write(textLine.substring(0, column));
-        buf.write(_RED_COLOR);
-        buf.write(textLine.substring(column, toColumn));
-        buf.write(_NO_COLOR);
-        buf.write(textLine.substring(toColumn));
-      } else {
-        buf.write(textLine);
-      }
-
-      int i = 0;
-      for (; i < column; i++) {
-        buf.write(' ');
-      }
-
-      if (options.useColors) buf.write(_RED_COLOR);
-      for (; i < toColumn; i++) {
-        buf.write('^');
-      }
-      if (options.useColors) buf.write(_NO_COLOR);
-    }
-
-    return buf.toString();
-  }
-
-  /** Compares two source files. */
-  int compareTo(SourceFile other) {
-    if (orderInLibrary != null && other.orderInLibrary != null) {
-      return orderInLibrary - other.orderInLibrary;
-    } else {
-      return filename.compareTo(other.filename);
-    }
-  }
-}
-
-
-/**
- * A range of characters in a [SourceFile].  Used to represent the source
- * positions of [Token]s and [Node]s for error reporting or other tooling
- * work.
- */
- // TODO(jmesserly): Rename to Span - but first write cool refactoring tool
-class SourceSpan implements Comparable<SourceSpan> {
-  /** The [SourceFile] that contains this span. */
-  final SourceFile file;
-
-  /** The character position of the start of this span. */
-  final int start;
-
-  /** The character position of the end of this span. */
-  final int end;
-
-  SourceSpan(this.file, this.start, this.end);
-
-  /** Returns the source text corresponding to this [Span]. */
-  String get text {
-    return file.text.substring(start, end);
-  }
-
-  toMessageString(String message) {
-    return file.getLocationMessage(message, start, end: end, includeText: true);
-  }
-
-  int get line {
-    return file.getLine(start);
-  }
-
-  int get column {
-    return file.getColumn(line, start);
-  }
-
-  int get endLine {
-    return file.getLine(end);
-  }
-
-  int get endColumn {
-    return file.getColumn(endLine, end);
-  }
-
-  String get locationText {
-    var line = file.getLine(start);
-    var column = file.getColumn(line, start);
-    return '${file.filename}:${line + 1}:${column + 1}';
-  }
-
-  /** Compares two source spans by file and position. Handles nulls. */
-  int compareTo(SourceSpan other) {
-    if (file == other.file) {
-      int d = start - other.start;
-      return d == 0 ? (end - other.end) : d;
-    }
-    return file.compareTo(other.file);
-  }
-}
diff --git a/utils/css/token.dart b/utils/css/token.dart
deleted file mode 100644
index 144e39c..0000000
--- a/utils/css/token.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * A single token in the Dart language.
- */
-class Token {
-  /** A member of [TokenKind] specifying what kind of token this is. */
-  final int kind;
-
-  /** The [SourceFile] this token came from. */
-  final SourceFile source;
-
-  /** The start and end indexes into the [SourceFile] of this [Token]. */
-  final int start, end;
-
-  Token(this.kind, this.source, this.start, this.end) {}
-
-  Token.fake(this.kind, span)
-    : this.source = span.file, this.start = span.start, this.end = span.end;
-
-  /** Returns the source text corresponding to this [Token]. */
-  String get text {
-    return source.text.substring(start, end);
-  }
-
-  /** Returns a pretty representation of this token for error messages. **/
-  String toString() {
-    var kindText = TokenKind.kindToString(kind);
-    var actualText = text;
-    if (kindText != actualText) {
-      if (actualText.length > 10) {
-        actualText = actualText.substring(0, 8) + '...';
-      }
-      return '$kindText($actualText)';
-    } else {
-      return kindText;
-    }
-  }
-
-  /** Returns a [SourceSpan] representing the source location. */
-  SourceSpan get span {
-    return new SourceSpan(source, start, end);
-  }
-}
-
-/** A token containing a parsed literal value. */
-class LiteralToken extends Token {
-  var value;
-  LiteralToken(kind, source, start, end, this.value)
-      : super(kind, source, start, end);
-}
-
-/** A token containing error information. */
-class ErrorToken extends Token {
-  String message;
-  ErrorToken(kind, source, start, end, this.message)
-      : super(kind, source, start, end);
-}
diff --git a/utils/css/tokenizer.dart b/utils/css/tokenizer.dart
deleted file mode 100644
index 63573df..0000000
--- a/utils/css/tokenizer.dart
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Tokenizer extends CSSTokenizerBase {
-  TokenKind cssTokens;
-
-  bool _selectorParsing;
-
-  Tokenizer(SourceFile source, bool skipWhitespace, [int index = 0])
-    : super(source, skipWhitespace, index), _selectorParsing = false {
-    cssTokens = new TokenKind();
-  }
-
-  int get startIndex => _startIndex;
-
-  Token next() {
-    // keep track of our starting position
-    _startIndex = _index;
-
-    if (_interpStack != null && _interpStack.depth == 0) {
-      var istack = _interpStack;
-      _interpStack = _interpStack.pop();
-
-      /* TODO(terry): Enable for variable and string interpolation.
-       * if (istack.isMultiline) {
-       *   return finishMultilineStringBody(istack.quote);
-       * } else {
-       *   return finishStringBody(istack.quote);
-       * }
-       */
-    }
-
-    int ch;
-    ch = _nextChar();
-    switch(ch) {
-      case 0:
-        return _finishToken(TokenKind.END_OF_FILE);
-      case cssTokens.tokens[TokenKind.SPACE]:
-      case cssTokens.tokens[TokenKind.TAB]:
-      case cssTokens.tokens[TokenKind.NEWLINE]:
-      case cssTokens.tokens[TokenKind.RETURN]:
-        return finishWhitespace();
-      case cssTokens.tokens[TokenKind.END_OF_FILE]:
-        return _finishToken(TokenKind.END_OF_FILE);
-      case cssTokens.tokens[TokenKind.AT]:
-        return _finishToken(TokenKind.AT);
-      case cssTokens.tokens[TokenKind.DOT]:
-        int start = _startIndex;             // Start where the dot started.
-        if (maybeEatDigit()) {
-          // looks like a number dot followed by digit(s).
-          Token number = finishNumber();
-          if (number.kind == TokenKind.INTEGER) {
-            // It's a number but it's preceeded by a dot, so make it a double.
-            _startIndex = start;
-            return _finishToken(TokenKind.DOUBLE);
-          } else {
-            // Don't allow dot followed by a double (e.g,  '..1').
-            return _errorToken();
-          }
-        } else {
-          // It's really a dot.
-          return _finishToken(TokenKind.DOT);
-        }
-      case cssTokens.tokens[TokenKind.LPAREN]:
-        return _finishToken(TokenKind.LPAREN);
-      case cssTokens.tokens[TokenKind.RPAREN]:
-        return _finishToken(TokenKind.RPAREN);
-      case cssTokens.tokens[TokenKind.LBRACE]:
-        return _finishToken(TokenKind.LBRACE);
-      case cssTokens.tokens[TokenKind.RBRACE]:
-        return _finishToken(TokenKind.RBRACE);
-      case cssTokens.tokens[TokenKind.LBRACK]:
-        return _finishToken(TokenKind.LBRACK);
-      case cssTokens.tokens[TokenKind.RBRACK]:
-        return _finishToken(TokenKind.RBRACK);
-      case cssTokens.tokens[TokenKind.HASH]:
-        return _finishToken(TokenKind.HASH);
-      case cssTokens.tokens[TokenKind.PLUS]:
-        if (maybeEatDigit()) {
-          return finishNumber();
-        } else {
-          return _finishToken(TokenKind.PLUS);
-        }
-      case cssTokens.tokens[TokenKind.MINUS]:
-        if (maybeEatDigit()) {
-          return finishNumber();
-        } else if (TokenizerHelpers.isIdentifierStart(ch)) {
-          return this.finishIdentifier(ch);
-        } else {
-          return _finishToken(TokenKind.MINUS);
-        }
-      case cssTokens.tokens[TokenKind.GREATER]:
-        return _finishToken(TokenKind.GREATER);
-      case cssTokens.tokens[TokenKind.TILDE]:
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.EQUALS])) {
-          return _finishToken(TokenKind.INCLUDES);          // ~=
-        } else {
-          return _finishToken(TokenKind.TILDE);
-        }
-      case cssTokens.tokens[TokenKind.ASTERISK]:
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.EQUALS])) {
-          return _finishToken(TokenKind.SUBSTRING_MATCH);   // *=
-        } else {
-          return _finishToken(TokenKind.ASTERISK);
-        }
-      case cssTokens.tokens[TokenKind.NAMESPACE]:
-        return _finishToken(TokenKind.NAMESPACE);
-      case cssTokens.tokens[TokenKind.COLON]:
-        return _finishToken(TokenKind.COLON);
-      case cssTokens.tokens[TokenKind.COMMA]:
-        return _finishToken(TokenKind.COMMA);
-      case cssTokens.tokens[TokenKind.SEMICOLON]:
-        return _finishToken(TokenKind.SEMICOLON);
-      case cssTokens.tokens[TokenKind.PERCENT]:
-        return _finishToken(TokenKind.PERCENT);
-      case cssTokens.tokens[TokenKind.SINGLE_QUOTE]:
-        return _finishToken(TokenKind.SINGLE_QUOTE);
-      case cssTokens.tokens[TokenKind.DOUBLE_QUOTE]:
-        return _finishToken(TokenKind.DOUBLE_QUOTE);
-      case cssTokens.tokens[TokenKind.SLASH]:
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.ASTERISK])) {
-          return finishMultiLineComment();
-        } else {
-          return _finishToken(TokenKind.SLASH);
-        }
-      case  cssTokens.tokens[TokenKind.LESS]:      // <!--
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.BANG]) &&
-            _maybeEatChar(cssTokens.tokens[TokenKind.MINUS]) &&
-            _maybeEatChar(cssTokens.tokens[TokenKind.MINUS])) {
-          return finishMultiLineComment();
-        } else {
-          return _finishToken(TokenKind.LESS);
-        }
-      case cssTokens.tokens[TokenKind.EQUALS]:
-        return _finishToken(TokenKind.EQUALS);
-      case cssTokens.tokens[TokenKind.OR]:
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.EQUALS])) {
-          return _finishToken(TokenKind.DASH_MATCH);      // |=
-        } else {
-          return _finishToken(TokenKind.OR);
-        }
-      case cssTokens.tokens[TokenKind.CARET]:
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.EQUALS])) {
-          return _finishToken(TokenKind.PREFIX_MATCH);    // ^=
-        } else {
-          return _finishToken(TokenKind.CARET);
-        }
-      case cssTokens.tokens[TokenKind.DOLLAR]:
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.EQUALS])) {
-          return _finishToken(TokenKind.SUFFIX_MATCH);    // $=
-        } else {
-          return _finishToken(TokenKind.DOLLAR);
-        }
-      case cssTokens.tokens[TokenKind.BANG]:
-        Token tok = finishIdentifier(ch);
-        return (tok == null) ? _finishToken(TokenKind.BANG) : tok;
-      default:
-        if (TokenizerHelpers.isIdentifierStart(ch)) {
-          return this.finishIdentifier(ch);
-        } else if (TokenizerHelpers.isDigit(ch)) {
-          return this.finishNumber();
-        } else {
-          return _errorToken();
-        }
-    }
-  }
-
-  // TODO(jmesserly): we need a way to emit human readable error messages from
-  // the tokenizer.
-  Token _errorToken([String message = null]) {
-    return _finishToken(TokenKind.ERROR);
-  }
-
-  int getIdentifierKind() {
-    // Is the identifier a unit type?
-    int tokId = TokenKind.matchUnits(_text, _startIndex, _index - _startIndex);
-    if (tokId == -1) {
-      // No, is it a directive?
-      tokId = TokenKind.matchDirectives(
-          _text, _startIndex, _index - _startIndex);
-    }
-    if (tokId == -1) {
-      tokId = (_text.substring(_startIndex, _index) == '!important') ?
-          TokenKind.IMPORTANT : -1;
-    }
-
-    return tokId >= 0 ? tokId : TokenKind.IDENTIFIER;
-  }
-
-  // Need to override so CSS version of isIdentifierPart is used.
-  Token finishIdentifier(int ch) {
-    while (_index < _text.length) {
-//      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index++))) {
-      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index))) {
-//        _index--;
-        break;
-      } else {
-        _index += 1;
-      }
-    }
-    if (_interpStack != null && _interpStack.depth == -1) {
-      _interpStack.depth = 0;
-    }
-    int kind = getIdentifierKind();
-    if (kind == TokenKind.IDENTIFIER) {
-      return _finishToken(TokenKind.IDENTIFIER);
-    } else {
-      return _finishToken(kind);
-    }
-  }
-
-  Token finishImportant() {
-
-  }
-
-  Token finishNumber() {
-    eatDigits();
-
-    if (_peekChar() == 46/*.*/) {
-      // Handle the case of 1.toString().
-      _nextChar();
-      if (TokenizerHelpers.isDigit(_peekChar())) {
-        eatDigits();
-        return _finishToken(TokenKind.DOUBLE);
-      } else {
-        _index -= 1;
-      }
-    }
-
-    return _finishToken(TokenKind.INTEGER);
-  }
-
-  bool maybeEatDigit() {
-    if (_index < _text.length
-        && TokenizerHelpers.isDigit(_text.codeUnitAt(_index))) {
-      _index += 1;
-      return true;
-    }
-    return false;
-  }
-
-  void eatHexDigits() {
-    while (_index < _text.length) {
-     if (TokenizerHelpers.isHexDigit(_text.codeUnitAt(_index))) {
-       _index += 1;
-     } else {
-       return;
-     }
-    }
-  }
-
-  bool maybeEatHexDigit() {
-    if (_index < _text.length
-        && TokenizerHelpers.isHexDigit(_text.codeUnitAt(_index))) {
-      _index += 1;
-      return true;
-    }
-    return false;
-  }
-
-  Token finishMultiLineComment() {
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _finishToken(TokenKind.INCOMPLETE_COMMENT);
-      } else if (ch == 42/*'*'*/) {
-        if (_maybeEatChar(47/*'/'*/)) {
-          if (_skipWhitespace) {
-            return next();
-          } else {
-            return _finishToken(TokenKind.COMMENT);
-          }
-        }
-      } else if (ch == cssTokens.tokens[TokenKind.MINUS]) {
-        /* Check if close part of Comment Definition --> (CDC). */
-        if (_maybeEatChar(cssTokens.tokens[TokenKind.MINUS])) {
-          if (_maybeEatChar(cssTokens.tokens[TokenKind.GREATER])) {
-            if (_skipWhitespace) {
-              return next();
-            } else {
-              return _finishToken(TokenKind.HTML_COMMENT);
-            }
-          }
-        }
-      }
-    }
-    return _errorToken();
-  }
-
-}
-
-/** Static helper methods. */
-/** Static helper methods. */
-class TokenizerHelpers {
-
-  static bool isIdentifierStart(int c) {
-    return ((c >= 97/*a*/ && c <= 122/*z*/) || (c >= 65/*A*/ && c <= 90/*Z*/) ||
-        c == 95/*_*/ || c == 45 /*-*/);
-  }
-
-  static bool isDigit(int c) {
-    return (c >= 48/*0*/ && c <= 57/*9*/);
-  }
-
-  static bool isHexDigit(int c) {
-    return (isDigit(c) || (c >= 97/*a*/ && c <= 102/*f*/)
-        || (c >= 65/*A*/ && c <= 70/*F*/));
-  }
-
-  static bool isIdentifierPart(int c) {
-    return (isIdentifierStart(c) || isDigit(c) || c == 45 /*-*/);
-  }
-}
-
diff --git a/utils/css/tokenizer_base.dart b/utils/css/tokenizer_base.dart
deleted file mode 100644
index f98f245..0000000
--- a/utils/css/tokenizer_base.dart
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Generated by scripts/tokenizer_gen.py.
-
-
-abstract class TokenSource {
-  Token next();
-}
-
-class InterpStack {
-  InterpStack next, previous;
-  final int quote;
-  final bool isMultiline;
-  int depth;
-
-  InterpStack(this.previous, this.quote, this.isMultiline): depth = -1;
-
-  InterpStack pop() {
-    return this.previous;
-  }
-
-  static InterpStack push(InterpStack stack, int quote, bool isMultiline) {
-    var newStack = new InterpStack(stack, quote, isMultiline);
-    if (stack != null) newStack.previous = stack;
-    return newStack;
-  }
-}
-
-/**
- * The base class for our tokenizer. The hand coded parts are in this file, with
- * the generated parts in the subclass Tokenizer.
- */
-class CSSTokenizerBase implements TokenSource {
-  final SourceFile _source;
-  final bool _skipWhitespace;
-  String _text;
-
-  int _index;
-  int _startIndex;
-
-  /** Keeps track of string interpolation state. */
-  InterpStack _interpStack;
-
-  CSSTokenizerBase(this._source, this._skipWhitespace, [index = 0])
-      : this._index = index {
-    _text = _source.text;
-  }
-
-  abstract Token next();
-  abstract int getIdentifierKind();
-
-  int _nextChar() {
-    if (_index < _text.length) {
-      return _text.codeUnitAt(_index++);
-    } else {
-      return 0;
-    }
-  }
-
-  int _peekChar() {
-    if (_index < _text.length) {
-      return _text.codeUnitAt(_index);
-    } else {
-      return 0;
-    }
-  }
-
-  bool _maybeEatChar(int ch) {
-    if (_index < _text.length) {
-      if (_text.codeUnitAt(_index) == ch) {
-        _index++;
-        return true;
-      } else {
-        return false;
-      }
-    } else {
-      return false;
-    }
-  }
-
-  String _tokenText() {
-    if (_index < _text.length) {
-      return _text.substring(_startIndex, _index);
-    } else {
-      return _text.substring(_startIndex, _text.length);
-    }
-  }
-
-  Token _finishToken(int kind) {
-    return new Token(kind, _source, _startIndex, _index);
-  }
-
-  Token _errorToken([String message = null]) {
-    return new ErrorToken(
-        TokenKind.ERROR, _source, _startIndex, _index, message);
-  }
-
-  Token finishWhitespace() {
-    _index--;
-    while (_index < _text.length) {
-      final ch = _text.codeUnitAt(_index++);
-      if (ch == 32/*' '*/ || ch == 9/*'\t'*/ || ch == 13/*'\r'*/) {
-        // do nothing
-      } else if (ch == 10/*'\n'*/) {
-        if (!_skipWhitespace) {
-          return _finishToken(TokenKind.WHITESPACE); // note the newline?
-        }
-      } else {
-        _index--;
-        if (_skipWhitespace) {
-          return next();
-        } else {
-          return _finishToken(TokenKind.WHITESPACE);
-        }
-      }
-
-    }
-    return _finishToken(TokenKind.END_OF_FILE);
-  }
-
-  Token finishSingleLineComment() {
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0 || ch == 10/*'\n'*/ || ch == 13/*'\r'*/) {
-        if (_skipWhitespace) {
-          return next();
-        } else {
-          return _finishToken(TokenKind.COMMENT);
-        }
-      }
-    }
-  }
-
-  Token finishMultiLineComment() {
-    int nesting = 1;
-    do {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _errorToken();
-      } else if (ch == 42/*'*'*/) {
-        if (_maybeEatChar(47/*'/'*/)) {
-          nesting--;
-        }
-      } else if (ch == 47/*'/'*/) {
-        if (_maybeEatChar(42/*'*'*/)) {
-          nesting++;
-        }
-      }
-    } while (nesting > 0);
-
-    if (_skipWhitespace) {
-      return next();
-    } else {
-      return _finishToken(TokenKind.COMMENT);
-    }
-  }
-
-  void eatDigits() {
-    while (_index < _text.length) {
-      if (TokenizerHelpers.isDigit(_text.codeUnitAt(_index))) {
-        _index++;
-      } else {
-        return;
-      }
-    }
-  }
-
-  static int _hexDigit(int c) {
-    if(c >= 48/*0*/ && c <= 57/*9*/) {
-      return c - 48;
-    } else if (c >= 97/*a*/ && c <= 102/*f*/) {
-      return c - 87;
-    } else if (c >= 65/*A*/ && c <= 70/*F*/) {
-      return c - 55;
-    } else {
-      return -1;
-    }
-  }
-
-  int readHex([int hexLength]) {
-    int maxIndex;
-    if (hexLength == null) {
-      maxIndex = _text.length - 1;
-    } else {
-      // TODO(jimhug): What if this is too long?
-      maxIndex = _index + hexLength;
-      if (maxIndex >= _text.length) return -1;
-    }
-    var result = 0;
-    while (_index < maxIndex) {
-      final digit = _hexDigit(_text.codeUnitAt(_index));
-      if (digit == -1) {
-        if (hexLength == null) {
-          return result;
-        } else {
-          return -1;
-        }
-      }
-      _hexDigit(_text.codeUnitAt(_index));
-      // Multiply by 16 rather than shift by 4 since that will result in a
-      // correct value for numbers that exceed the 32 bit precision of JS
-      // 'integers'.
-      // TODO: Figure out a better solution to integer truncation. Issue 638.
-      result = (result * 16) + digit;
-      _index++;
-    }
-
-    return result;
-  }
-
-  Token finishNumber() {
-    eatDigits();
-
-    if (_peekChar() == 46/*.*/) {
-      // Handle the case of 1.toString().
-      _nextChar();
-      if (TokenizerHelpers.isDigit(_peekChar())) {
-        eatDigits();
-        return finishNumberExtra(TokenKind.DOUBLE);
-      } else {
-        _index--;
-      }
-    }
-
-    return finishNumberExtra(TokenKind.INTEGER);
-  }
-
-  Token finishNumberExtra(int kind) {
-    if (_maybeEatChar(101/*e*/) || _maybeEatChar(69/*E*/)) {
-      kind = TokenKind.DOUBLE;
-      _maybeEatChar(45/*-*/);
-      _maybeEatChar(43/*+*/);
-      eatDigits();
-    }
-    if (_peekChar() != 0 && TokenizerHelpers.isIdentifierStart(_peekChar())) {
-      _nextChar();
-      return _errorToken("illegal character in number");
-    }
-
-    return _finishToken(kind);
-  }
-
-  Token _makeStringToken(List<int> buf, bool isPart) {
-    final s = new String.fromCharCodes(buf);
-    final kind = isPart ? TokenKind.STRING_PART : TokenKind.STRING;
-    return new LiteralToken(kind, _source, _startIndex, _index, s);
-  }
-
-  Token _makeRawStringToken(bool isMultiline) {
-    String s;
-    if (isMultiline) {
-      // Skip initial newline in multiline strings
-      int start = _startIndex + 4;
-      if (_source.text[start] == '\n') start++;
-      s = _source.text.substring(start, _index - 3);
-    } else {
-      s = _source.text.substring(_startIndex + 2, _index - 1);
-    }
-    return new LiteralToken(TokenKind.STRING, _source, _startIndex, _index, s);
-  }
-
-  Token finishMultilineString(int quote) {
-    var buf = <int>[];
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _errorToken();
-      } else if (ch == quote) {
-        if (_maybeEatChar(quote)) {
-          if (_maybeEatChar(quote)) {
-            return _makeStringToken(buf, false);
-          }
-          buf.add(quote);
-        }
-        buf.add(quote);
-      } else if (ch == 36/*$*/) {
-        // start of string interp
-        _interpStack = InterpStack.push(_interpStack, quote, true);
-        return _makeStringToken(buf, true);
-      } else if (ch == 92/*\*/) {
-        var escapeVal = readEscapeSequence();
-        if (escapeVal == -1) {
-          return _errorToken("invalid hex escape sequence");
-        } else {
-          buf.add(escapeVal);
-        }
-      } else {
-        buf.add(ch);
-      }
-    }
-  }
-
-  Token _finishOpenBrace() {
-    if (_interpStack != null) {
-      if (_interpStack.depth == -1) {
-        _interpStack.depth = 1;
-      } else {
-        assert(_interpStack.depth >= 0);
-        _interpStack.depth += 1;
-      }
-    }
-    return _finishToken(TokenKind.LBRACE);
-  }
-
-  Token _finishCloseBrace() {
-    if (_interpStack != null) {
-      _interpStack.depth -= 1;
-      assert(_interpStack.depth >= 0);
-    }
-    return _finishToken(TokenKind.RBRACE);
-  }
-
-  Token finishString(int quote) {
-    if (_maybeEatChar(quote)) {
-      if (_maybeEatChar(quote)) {
-        // skip an initial newline
-        _maybeEatChar(10/*'\n'*/);
-        return finishMultilineString(quote);
-      } else {
-        return _makeStringToken(new List<int>(), false);
-      }
-    }
-    return finishStringBody(quote);
-  }
-
-  Token finishRawString(int quote) {
-    if (_maybeEatChar(quote)) {
-      if (_maybeEatChar(quote)) {
-        return finishMultilineRawString(quote);
-      } else {
-        return _makeStringToken(<int>[], false);
-      }
-    }
-    while (true) {
-      int ch = _nextChar();
-      if (ch == quote) {
-        return _makeRawStringToken(false);
-      } else if (ch == 0) {
-        return _errorToken();
-      }
-    }
-  }
-
-  Token finishMultilineRawString(int quote) {
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _errorToken();
-      } else if (ch == quote && _maybeEatChar(quote) && _maybeEatChar(quote)) {
-        return _makeRawStringToken(true);
-      }
-    }
-  }
-
-  Token finishStringBody(int quote) {
-    var buf = new List<int>();
-    while (true) {
-      int ch = _nextChar();
-      if (ch == quote) {
-        return _makeStringToken(buf, false);
-      } else if (ch == 36/*$*/) {
-        // start of string interp
-        _interpStack = InterpStack.push(_interpStack, quote, false);
-        return _makeStringToken(buf, true);
-      } else if (ch == 0) {
-        return _errorToken();
-      } else if (ch == 92/*\*/) {
-        var escapeVal = readEscapeSequence();
-        if (escapeVal == -1) {
-          return _errorToken("invalid hex escape sequence");
-        } else {
-          buf.add(escapeVal);
-        }
-      } else {
-        buf.add(ch);
-      }
-    }
-  }
-
-  int readEscapeSequence() {
-    final ch = _nextChar();
-    int hexValue;
-    switch (ch) {
-      case 110/*n*/:
-        return 0x0a/*'\n'*/;
-      case 114/*r*/:
-        return 0x0d/*'\r'*/;
-      case 102/*f*/:
-        return 0x0c/*'\f'*/;
-      case 98/*b*/:
-        return 0x08/*'\b'*/;
-      case 116/*t*/:
-        return 0x09/*'\t'*/;
-      case 118/*v*/:
-        return 0x0b/*'\v'*/;
-      case 120/*x*/:
-        hexValue = readHex(2);
-        break;
-      case 117/*u*/:
-        if (_maybeEatChar(123/*{*/)) {
-          hexValue = readHex();
-          if (!_maybeEatChar(125/*}*/)) {
-            return -1;
-          } else {
-            break;
-          }
-        } else {
-          hexValue = readHex(4);
-          break;
-        }
-      default: return ch;
-    }
-
-    if (hexValue == -1) return -1;
-
-    // According to the Unicode standard the high and low surrogate halves
-    // used by UTF-16 (U+D800 through U+DFFF) and values above U+10FFFF
-    // are not legal Unicode values.
-    if (hexValue < 0xD800 || hexValue > 0xDFFF && hexValue <= 0xFFFF) {
-      return hexValue;
-    } else if (hexValue <= 0x10FFFF){
-      world.fatal('unicode values greater than 2 bytes not implemented yet');
-      return -1;
-    } else {
-      return -1;
-    }
-  }
-
-  Token finishDot() {
-    if (TokenizerHelpers.isDigit(_peekChar())) {
-      eatDigits();
-      return finishNumberExtra(TokenKind.DOUBLE);
-    } else {
-      return _finishToken(TokenKind.DOT);
-    }
-  }
-
-  Token finishIdentifier(int ch) {
-    while (_index < _text.length) {
-      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index++))) {
-        _index--;
-        break;
-      }
-    }
-    int kind = getIdentifierKind();
-    if (kind == TokenKind.IDENTIFIER) {
-      return _finishToken(TokenKind.IDENTIFIER);
-    } else {
-      return _finishToken(kind);
-    }
-  }
-}
-
diff --git a/utils/css/tokenkind.dart b/utils/css/tokenkind.dart
deleted file mode 100644
index fbcebdf..0000000
--- a/utils/css/tokenkind.dart
+++ /dev/null
@@ -1,596 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(terry): Need to be consistent with tokens either they're ASCII tokens
-//              e.g., ASTERISK or they're CSS e.g., PSEUDO, COMBINATOR_*.
-class TokenKind {
-  // Common shared tokens used in TokenizerBase.
-  static const int UNUSED = 0;                  // Unused place holder...
-  static const int END_OF_FILE = 1;             // TODO(terry): Must match base
-  static const int LPAREN = 2;                  // (
-  static const int RPAREN = 3;                  // )
-  static const int LBRACK = 4;                  // [
-  static const int RBRACK = 5;                  // ]
-  static const int LBRACE = 6;                  // {
-  static const int RBRACE = 7;                  // }
-  static const int DOT = 8;                     // .
-  static const int SEMICOLON = 9;               // ;
-
-  // Unique tokens for CSS.
-  static const int AT = 10;                     // @
-  static const int HASH = 11;                   // #
-  static const int PLUS = 12;                   // +
-  static const int GREATER = 13;                // >
-  static const int TILDE = 14;                  // ~
-  static const int ASTERISK = 15;               // *
-  static const int NAMESPACE = 16;              // |
-  static const int COLON = 17;                  // :
-  static const int PRIVATE_NAME = 18;           // _ prefix private class or id
-  static const int COMMA = 19;                  // ,
-  static const int SPACE = 20;
-  static const int TAB = 21;                    // /t
-  static const int NEWLINE = 22;                // /n
-  static const int RETURN = 23;                 // /r
-  static const int PERCENT = 24;                // %
-  static const int SINGLE_QUOTE = 25;           // '
-  static const int DOUBLE_QUOTE = 26;           // "
-  static const int SLASH = 27;                  // /
-  static const int EQUALS = 28;                 // =
-  static const int OR = 29;                     // |
-  static const int CARET = 30;                  // ^
-  static const int DOLLAR = 31;                 // $
-  static const int LESS = 32;                   // <
-  static const int BANG = 33;                   // !
-  static const int MINUS = 34;                  // -
-
-  // WARNING: END_TOKENS must be 1 greater than the last token above (last
-  //          character in our list).  Also add to kindToString function and the
-  //          constructor for TokenKind.
-
-  static const int END_TOKENS = 35;             // Marker for last token in list
-
-  /** [TokenKind] representing integer tokens. */
-  static const int INTEGER = 60;                // TODO(terry): must match base
-
-  /** [TokenKind] representing hex integer tokens. */
-//  static const int HEX_INTEGER = 61;            // TODO(terry): must match base
-
-  /** [TokenKind] representing double tokens. */
-  static const int DOUBLE = 62;                 // TODO(terry): must match base
-
-  /** [TokenKind] representing whitespace tokens. */
-  static const int WHITESPACE = 63;             // TODO(terry): must match base
-
-  /** [TokenKind] representing comment tokens. */
-  static const int COMMENT = 64;                // TODO(terry): must match base
-
-  /** [TokenKind] representing error tokens. */
-  static const int ERROR = 65;                  // TODO(terry): must match base
-
-  /** [TokenKind] representing incomplete string tokens. */
-  static const int INCOMPLETE_STRING = 66;      // TODO(terry): must match base
-
-  /** [TokenKind] representing incomplete comment tokens. */
-  static const int INCOMPLETE_COMMENT = 67;     // TODO(terry): must match base
-
-  // Synthesized Tokens (no character associated with TOKEN).
-  // TODO(terry): Possible common names used by both Dart and CSS tokenizers.
-  static const int STRING = 500;
-  static const int STRING_PART = 501;
-  static const int NUMBER = 502;
-  static const int HEX_NUMBER = 503;
-  static const int HTML_COMMENT = 504;          // <!--
-  static const int IMPORTANT = 505;             // !important
-  static const int IDENTIFIER = 511;
-
-  // Uniquely synthesized tokens for CSS.
-  static const int SELECTOR_EXPRESSION = 512;
-  static const int COMBINATOR_NONE = 513;
-  static const int COMBINATOR_DESCENDANT = 514; // Space combinator
-  static const int COMBINATOR_PLUS = 515;       // + combinator
-  static const int COMBINATOR_GREATER = 516;    // > combinator
-  static const int COMBINATOR_TILDE = 517;      // ~ combinator
-
-  static const int UNARY_OP_NONE = 518;         // No unary operator present.
-
-  // Attribute match types:
-  static const int INCLUDES = 530;              // '~='
-  static const int DASH_MATCH = 531;            // '|='
-  static const int PREFIX_MATCH = 532;          // '^='
-  static const int SUFFIX_MATCH = 533;          // '$='
-  static const int SUBSTRING_MATCH = 534;       // '*='
-  static const int NO_MATCH = 535;              // No operator.
-
-  // Unit types:
-  static const int UNIT_EM = 600;
-  static const int UNIT_EX = 601;
-  static const int UNIT_LENGTH_PX = 602;
-  static const int UNIT_LENGTH_CM = 603;
-  static const int UNIT_LENGTH_MM = 604;
-  static const int UNIT_LENGTH_IN = 605;
-  static const int UNIT_LENGTH_PT = 606;
-  static const int UNIT_LENGTH_PC = 607;
-  static const int UNIT_ANGLE_DEG = 608;
-  static const int UNIT_ANGLE_RAD = 609;
-  static const int UNIT_ANGLE_GRAD = 610;
-  static const int UNIT_TIME_MS = 611;
-  static const int UNIT_TIME_S = 612;
-  static const int UNIT_FREQ_HZ = 613;
-  static const int UNIT_FREQ_KHZ = 614;
-  static const int UNIT_PERCENT = 615;
-  static const int UNIT_FRACTION = 616;
-
-  // Directives (@nnnn)
-  static const int DIRECTIVE_NONE = 650;
-  static const int DIRECTIVE_IMPORT = 651;
-  static const int DIRECTIVE_MEDIA = 652;
-  static const int DIRECTIVE_PAGE = 653;
-  static const int DIRECTIVE_INCLUDE = 654;
-  static const int DIRECTIVE_STYLET = 655;
-  static const int DIRECTIVE_KEYFRAMES = 656;
-  static const int DIRECTIVE_FONTFACE = 657;
-
-  // Simple selector type.
-  static const int CLASS_NAME = 700;            // .class
-  static const int ELEMENT_NAME = 701;          // tagName
-  static const int HASH_NAME = 702;             // #elementId
-  static const int ATTRIBUTE_NAME = 703;        // [attrib]
-  static const int PSEUDO_ELEMENT_NAME = 704;   // ::pseudoElement
-  static const int PSEUDO_CLASS_NAME = 705;     // :pseudoClass
-  static const int NEGATION = 706;              // NOT
-
-  static const List<Map<int, String>> _DIRECTIVES = const [
-    const {'type': TokenKind.DIRECTIVE_IMPORT, 'value' : 'import'},
-    const {'type': TokenKind.DIRECTIVE_MEDIA, 'value' : 'media'},
-    const {'type': TokenKind.DIRECTIVE_PAGE, 'value' : 'page'},
-    const {'type': TokenKind.DIRECTIVE_INCLUDE, 'value' : 'include'},
-    const {'type': TokenKind.DIRECTIVE_STYLET, 'value' : 'stylet'},
-    const {'type': TokenKind.DIRECTIVE_KEYFRAMES, 'value' : '-webkit-keyframes'},
-    const {'type': TokenKind.DIRECTIVE_FONTFACE, 'value' : 'font-face'},
-  ];
-
-  static const List<Map<int, String>> _UNITS = const [
-    const {'unit': TokenKind.UNIT_EM, 'value' : 'em'},
-    const {'unit': TokenKind.UNIT_EX, 'value' : 'ex'},
-    const {'unit': TokenKind.UNIT_LENGTH_PX, 'value' : 'px'},
-    const {'unit': TokenKind.UNIT_LENGTH_CM, 'value' : 'cm'},
-    const {'unit': TokenKind.UNIT_LENGTH_MM, 'value' : 'mm'},
-    const {'unit': TokenKind.UNIT_LENGTH_IN, 'value' : 'in'},
-    const {'unit': TokenKind.UNIT_LENGTH_PT, 'value' : 'pt'},
-    const {'unit': TokenKind.UNIT_LENGTH_PC, 'value' : 'pc'},
-    const {'unit': TokenKind.UNIT_ANGLE_DEG, 'value' : 'deg'},
-    const {'unit': TokenKind.UNIT_ANGLE_RAD, 'value' : 'rad'},
-    const {'unit': TokenKind.UNIT_ANGLE_GRAD, 'value' : 'grad'},
-    const {'unit': TokenKind.UNIT_TIME_MS, 'value' : 'ms'},
-    const {'unit': TokenKind.UNIT_TIME_S, 'value' : 's'},
-    const {'unit': TokenKind.UNIT_FREQ_HZ, 'value' : 'hz'},
-    const {'unit': TokenKind.UNIT_FREQ_KHZ, 'value' : 'khz'},
-    const {'unit': TokenKind.UNIT_FRACTION, 'value' : 'fr'},
-  ];
-
-  // Some more constants:
-  static const int ASCII_UPPER_A = 65;    // ASCII value for uppercase A
-  static const int ASCII_UPPER_Z = 90;    // ASCII value for uppercase Z
-
-  // Extended color keywords:
-  static const List<Map<String, int>> _EXTENDED_COLOR_NAMES = const [
-    const {'name' : 'aliceblue', 'value' : 0xF08FF},
-    const {'name' : 'antiquewhite', 'value' : 0xFAEBD7},
-    const {'name' : 'aqua', 'value' : 0x00FFFF},
-    const {'name' : 'aquamarine', 'value' : 0x7FFFD4},
-    const {'name' : 'azure', 'value' : 0xF0FFFF},
-    const {'name' : 'beige', 'value' : 0xF5F5DC},
-    const {'name' : 'bisque', 'value' : 0xFFE4C4},
-    const {'name' : 'black', 'value' : 0x000000},
-    const {'name' : 'blanchedalmond', 'value' : 0xFFEBCD},
-    const {'name' : 'blue', 'value' : 0x0000FF},
-    const {'name' : 'blueviolet', 'value' : 0x8A2BE2},
-    const {'name' : 'brown', 'value' : 0xA52A2A},
-    const {'name' : 'burlywood', 'value' : 0xDEB887},
-    const {'name' : 'cadetblue', 'value' : 0x5F9EA0},
-    const {'name' : 'chartreuse', 'value' : 0x7FFF00},
-    const {'name' : 'chocolate', 'value' : 0xD2691E},
-    const {'name' : 'coral', 'value' : 0xFF7F50},
-    const {'name' : 'cornflowerblue', 'value' : 0x6495ED},
-    const {'name' : 'cornsilk', 'value' : 0xFFF8DC},
-    const {'name' : 'crimson', 'value' : 0xDC143C},
-    const {'name' : 'cyan', 'value' : 0x00FFFF},
-    const {'name' : 'darkblue', 'value' : 0x00008B},
-    const {'name' : 'darkcyan', 'value' : 0x008B8B},
-    const {'name' : 'darkgoldenrod', 'value' : 0xB8860B},
-    const {'name' : 'darkgray', 'value' : 0xA9A9A9},
-    const {'name' : 'darkgreen', 'value' : 0x006400},
-    const {'name' : 'darkgrey', 'value' : 0xA9A9A9},
-    const {'name' : 'darkkhaki', 'value' : 0xBDB76B},
-    const {'name' : 'darkmagenta', 'value' : 0x8B008B},
-    const {'name' : 'darkolivegreen', 'value' : 0x556B2F},
-    const {'name' : 'darkorange', 'value' : 0xFF8C00},
-    const {'name' : 'darkorchid', 'value' : 0x9932CC},
-    const {'name' : 'darkred', 'value' : 0x8B0000},
-    const {'name' : 'darksalmon', 'value' : 0xE9967A},
-    const {'name' : 'darkseagreen', 'value' : 0x8FBC8F},
-    const {'name' : 'darkslateblue', 'value' : 0x483D8B},
-    const {'name' : 'darkslategray', 'value' : 0x2F4F4F},
-    const {'name' : 'darkslategrey', 'value' : 0x2F4F4F},
-    const {'name' : 'darkturquoise', 'value' : 0x00CED1},
-    const {'name' : 'darkviolet', 'value' : 0x9400D3},
-    const {'name' : 'deeppink', 'value' : 0xFF1493},
-    const {'name' : 'deepskyblue', 'value' : 0x00BFFF},
-    const {'name' : 'dimgray', 'value' : 0x696969},
-    const {'name' : 'dimgrey', 'value' : 0x696969},
-    const {'name' : 'dodgerblue', 'value' : 0x1E90FF},
-    const {'name' : 'firebrick', 'value' : 0xB22222},
-    const {'name' : 'floralwhite', 'value' : 0xFFFAF0},
-    const {'name' : 'forestgreen', 'value' : 0x228B22},
-    const {'name' : 'fuchsia', 'value' : 0xFF00FF},
-    const {'name' : 'gainsboro', 'value' : 0xDCDCDC},
-    const {'name' : 'ghostwhite', 'value' : 0xF8F8FF},
-    const {'name' : 'gold', 'value' : 0xFFD700},
-    const {'name' : 'goldenrod', 'value' : 0xDAA520},
-    const {'name' : 'gray', 'value' : 0x808080},
-    const {'name' : 'green', 'value' : 0x008000},
-    const {'name' : 'greenyellow', 'value' : 0xADFF2F},
-    const {'name' : 'grey', 'value' : 0x808080},
-    const {'name' : 'honeydew', 'value' : 0xF0FFF0},
-    const {'name' : 'hotpink', 'value' : 0xFF69B4},
-    const {'name' : 'indianred', 'value' : 0xCD5C5C},
-    const {'name' : 'indigo', 'value' : 0x4B0082},
-    const {'name' : 'ivory', 'value' : 0xFFFFF0},
-    const {'name' : 'khaki', 'value' : 0xF0E68C},
-    const {'name' : 'lavender', 'value' : 0xE6E6FA},
-    const {'name' : 'lavenderblush', 'value' : 0xFFF0F5},
-    const {'name' : 'lawngreen', 'value' : 0x7CFC00},
-    const {'name' : 'lemonchiffon', 'value' : 0xFFFACD},
-    const {'name' : 'lightblue', 'value' : 0xADD8E6},
-    const {'name' : 'lightcoral', 'value' : 0xF08080},
-    const {'name' : 'lightcyan', 'value' : 0xE0FFFF},
-    const {'name' : 'lightgoldenrodyellow', 'value' : 0xFAFAD2},
-    const {'name' : 'lightgray', 'value' : 0xD3D3D3},
-    const {'name' : 'lightgreen', 'value' : 0x90EE90},
-    const {'name' : 'lightgrey', 'value' : 0xD3D3D3},
-    const {'name' : 'lightpink', 'value' : 0xFFB6C1},
-    const {'name' : 'lightsalmon', 'value' : 0xFFA07A},
-    const {'name' : 'lightseagreen', 'value' : 0x20B2AA},
-    const {'name' : 'lightskyblue', 'value' : 0x87CEFA},
-    const {'name' : 'lightslategray', 'value' : 0x778899},
-    const {'name' : 'lightslategrey', 'value' : 0x778899},
-    const {'name' : 'lightsteelblue', 'value' : 0xB0C4DE},
-    const {'name' : 'lightyellow', 'value' : 0xFFFFE0},
-    const {'name' : 'lime', 'value' : 0x00FF00},
-    const {'name' : 'limegreen', 'value' : 0x32CD32},
-    const {'name' : 'linen', 'value' : 0xFAF0E6},
-    const {'name' : 'magenta', 'value' : 0xFF00FF},
-    const {'name' : 'maroon', 'value' : 0x800000},
-    const {'name' : 'mediumaquamarine', 'value' : 0x66CDAA},
-    const {'name' : 'mediumblue', 'value' : 0x0000CD},
-    const {'name' : 'mediumorchid', 'value' : 0xBA55D3},
-    const {'name' : 'mediumpurple', 'value' : 0x9370DB},
-    const {'name' : 'mediumseagreen', 'value' : 0x3CB371},
-    const {'name' : 'mediumslateblue', 'value' : 0x7B68EE},
-    const {'name' : 'mediumspringgreen', 'value' : 0x00FA9A},
-    const {'name' : 'mediumturquoise', 'value' : 0x48D1CC},
-    const {'name' : 'mediumvioletred', 'value' : 0xC71585},
-    const {'name' : 'midnightblue', 'value' : 0x191970},
-    const {'name' : 'mintcream', 'value' : 0xF5FFFA},
-    const {'name' : 'mistyrose', 'value' : 0xFFE4E1},
-    const {'name' : 'moccasin', 'value' : 0xFFE4B5},
-    const {'name' : 'navajowhite', 'value' : 0xFFDEAD},
-    const {'name' : 'navy', 'value' : 0x000080},
-    const {'name' : 'oldlace', 'value' : 0xFDF5E6},
-    const {'name' : 'olive', 'value' : 0x808000},
-    const {'name' : 'olivedrab', 'value' : 0x6B8E23},
-    const {'name' : 'orange', 'value' : 0xFFA500},
-    const {'name' : 'orangered', 'value' : 0xFF4500},
-    const {'name' : 'orchid', 'value' : 0xDA70D6},
-    const {'name' : 'palegoldenrod', 'value' : 0xEEE8AA},
-    const {'name' : 'palegreen', 'value' : 0x98FB98},
-    const {'name' : 'paleturquoise', 'value' : 0xAFEEEE},
-    const {'name' : 'palevioletred', 'value' : 0xDB7093},
-    const {'name' : 'papayawhip', 'value' : 0xFFEFD5},
-    const {'name' : 'peachpuff', 'value' : 0xFFDAB9},
-    const {'name' : 'peru', 'value' : 0xCD853F},
-    const {'name' : 'pink', 'value' : 0xFFC0CB},
-    const {'name' : 'plum', 'value' : 0xDDA0DD},
-    const {'name' : 'powderblue', 'value' : 0xB0E0E6},
-    const {'name' : 'purple', 'value' : 0x800080},
-    const {'name' : 'red', 'value' : 0xFF0000},
-    const {'name' : 'rosybrown', 'value' : 0xBC8F8F},
-    const {'name' : 'royalblue', 'value' : 0x4169E1},
-    const {'name' : 'saddlebrown', 'value' : 0x8B4513},
-    const {'name' : 'salmon', 'value' : 0xFA8072},
-    const {'name' : 'sandybrown', 'value' : 0xF4A460},
-    const {'name' : 'seagreen', 'value' : 0x2E8B57},
-    const {'name' : 'seashell', 'value' : 0xFFF5EE},
-    const {'name' : 'sienna', 'value' : 0xA0522D},
-    const {'name' : 'silver', 'value' : 0xC0C0C0},
-    const {'name' : 'skyblue', 'value' : 0x87CEEB},
-    const {'name' : 'slateblue', 'value' : 0x6A5ACD},
-    const {'name' : 'slategray', 'value' : 0x708090},
-    const {'name' : 'slategrey', 'value' : 0x708090},
-    const {'name' : 'snow', 'value' : 0xFFFAFA},
-    const {'name' : 'springgreen', 'value' : 0x00FF7F},
-    const {'name' : 'steelblue', 'value' : 0x4682B4},
-    const {'name' : 'tan', 'value' : 0xD2B48C},
-    const {'name' : 'teal', 'value' : 0x008080},
-    const {'name' : 'thistle', 'value' : 0xD8BFD8},
-    const {'name' : 'tomato', 'value' : 0xFF6347},
-    const {'name' : 'turquoise', 'value' : 0x40E0D0},
-    const {'name' : 'violet', 'value' : 0xEE82EE},
-    const {'name' : 'wheat', 'value' : 0xF5DEB3},
-    const {'name' : 'white', 'value' : 0xFFFFFF},
-    const {'name' : 'whitesmoke', 'value' : 0xF5F5F5},
-    const {'name' : 'yellow', 'value' : 0xFFFF00},
-    const {'name' : 'yellowgreen', 'value' : 0x9ACD32},
-  ];
-
-  // TODO(terry): Should used Dart mirroring for parameter values and types
-  //              especially for enumeration (e.g., counter's second parameter
-  //              is list-style-type which is an enumerated list for ordering
-  //              of a list 'circle', 'decimal', 'lower-roman', 'square', etc.
-  //              see http://www.w3schools.com/cssref/pr_list-style-type.asp
-  //              for list of possible values.
-
-  // List of valid CSS functions:
-  static const List<Map<String, Object>> _FUNCTIONS = const [
-    const {'name' : 'counter', 'info' : const {'params' : 2, 'expr' : false}},
-    const {'name' : 'attr', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'calc', 'info' : const {'params' : 1, 'expr' : true}},
-    const {'name' : 'min', 'info' : const {'params' : 2, 'expr' : true}},
-    const {'name' : 'max', 'info' : const {'params' : 2, 'expr' : true}},
-
-    // 2D functions:
-    const {'name' : 'translateX',
-        'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'translateY',
-        'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'translate', 'info' : const {'params' : 2, 'expr' : false}},
-    const {'name' : 'rotate', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'scaleX', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'scaleY', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'scale', 'info' : const {'params' : 2, 'expr' : false}},
-    const {'name' : 'skewX', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'skewY', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'skew', 'info' : const {'params' : 2, 'expr' : false}},
-    const {'name' : 'matrix', 'info' : const {'params' : 6, 'expr' : false}},
-
-    // 3D functions:
-    const {'name' : 'matrix3d', 'info' : const {'params' : 16, 'expr' : false}},
-    const {'name' : 'translate3d',
-        'info' : const {'params' : 3, 'expr' : false}},
-    const {'name' : 'translateZ',
-        'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'scale3d', 'info' : const {'params' : 3, 'expr' : false}},
-    const {'name' : 'scaleZ', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'rotate3d', 'info' : const {'params' : 3, 'expr' : false}},
-    const {'name' : 'rotateX', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'rotateY', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'rotateZ', 'info' : const {'params' : 1, 'expr' : false}},
-    const {'name' : 'perspective',
-        'info' : const {'params' : 1, 'expr' : false}},
-  ];
-
-  List<int> tokens;
-
-  /*
-   * Return the token that matches the unit ident found.
-   */
-  static int matchList(var identList, String tokenField, String text,
-                       int offset, int length) {
-    for (final entry in identList) {
-      String ident = entry['value'];
-      if (length == ident.length) {
-        int idx = offset;
-        bool match = true;
-        for (int identIdx = 0; identIdx < ident.length; identIdx++) {
-          int identChar = ident.codeUnitAt(identIdx);
-          int char = text.codeUnitAt(idx++);
-          // Compare lowercase to lowercase then check if char is uppercase.
-          match = match && (char == identChar ||
-              ((char >= ASCII_UPPER_A && char <= ASCII_UPPER_Z) &&
-               (char + 32) == identChar));
-          if (!match) {
-            break;
-          }
-        }
-
-        if (match) {
-          // Completely matched; return the token for this unit.
-          return entry[tokenField];
-        }
-      }
-    }
-
-    return -1;  // Not a unit token.
-  }
-
-  /*
-   * Return the token that matches the unit ident found.
-   */
-  static int matchUnits(String text, int offset, int length) {
-    return matchList(_UNITS, 'unit', text, offset, length);
-  }
-
-  /*
-   * Return the token that matches the directive ident found.
-   */
-  static int matchDirectives(String text, int offset, int length) {
-    return matchList(_DIRECTIVES, 'type', text, offset, length);
-  }
-
-  /*
-   * Return the unit token as its pretty name.
-   */
-  static String unitToString(int unitTokenToFind) {
-    if (unitTokenToFind == TokenKind.PERCENT) {
-      return '%';
-    } else {
-      for (final entry in _UNITS) {
-        int unit = entry['unit'];
-        if (unit == unitTokenToFind) {
-          return entry['value'];
-        }
-      }
-    }
-
-    return '<BAD UNIT>';  // Not a unit token.
-  }
-
-  /*
-   * Match color name, case insensitive match and return the associated RGB
-   * value as decimal number.
-   */
-  static int matchColorName(String text) {
-    int length = text.length;
-    for (final entry in _EXTENDED_COLOR_NAMES) {
-      String ident = entry['name'];
-      if (length == ident.length) {
-        int idx = 0;
-        bool match = true;
-        for (int identIdx = 0; identIdx < ident.length; identIdx++) {
-          int identChar = ident.codeUnitAt(identIdx);
-          int char = text.codeUnitAt(idx++);
-          // Compare lowercase to lowercase then check if char is uppercase.
-          match = match && (char == identChar ||
-              ((char >= ASCII_UPPER_A && char <= ASCII_UPPER_Z) &&
-               (char + 32) == identChar));
-          if (!match) {
-            break;
-          }
-        }
-
-        if (match) {
-          // Completely matched; return the token for this unit.
-          return entry['value'];
-        }
-      }
-    }
-
-    // No match.
-    throw new NoColorMatchException(text);
-  }
-
-  static String decimalToHex(int num, [int minDigits = 1]) {
-    final String _HEX_DIGITS = '0123456789abcdef';
-
-    List<String> result = new List<String>();
-
-    int dividend = num >> 4;
-    int remain = num % 16;
-    result.add(_HEX_DIGITS[remain]);
-    while (dividend != 0) {
-      remain = dividend % 16;
-      dividend >>= 4;
-      result.add(_HEX_DIGITS[remain]);
-    }
-
-    StringBuffer invertResult = new StringBuffer();
-    int paddings = minDigits - result.length;
-    while (paddings-- > 0) {
-      invertResult.write('0');
-    }
-    for (int idx = result.length - 1; idx >= 0; idx--) {
-      invertResult.write(result[idx]);
-    }
-
-    return invertResult.toString();
-  }
-
-  static String kindToString(int kind) {
-    switch(kind) {
-      case TokenKind.UNUSED: return "ERROR";
-      case TokenKind.END_OF_FILE: return "end of file";
-      case TokenKind.LPAREN: return "(";
-      case TokenKind.RPAREN: return ")";
-      case TokenKind.LBRACK: return "[";
-      case TokenKind.RBRACK: return "]";
-      case TokenKind.LBRACE: return "{";
-      case TokenKind.RBRACE: return "}";
-      case TokenKind.DOT: return ".";
-      case TokenKind.SEMICOLON: return ";";
-      case TokenKind.AT: return "@";
-      case TokenKind.HASH: return "#";
-      case TokenKind.PLUS: return "+";
-      case TokenKind.GREATER: return ">";
-      case TokenKind.TILDE: return "~";
-      case TokenKind.ASTERISK: return "*";
-      case TokenKind.NAMESPACE: return "|";
-      case TokenKind.COLON: return ":";
-      case TokenKind.PRIVATE_NAME: return "_";
-      case TokenKind.COMMA: return ",";
-      case TokenKind.SPACE: return " ";
-      case TokenKind.TAB: return "\t";
-      case TokenKind.NEWLINE: return "\n";
-      case TokenKind.RETURN: return "\r";
-      case TokenKind.PERCENT: return "%";
-      case TokenKind.SINGLE_QUOTE: return "'";
-      case TokenKind.DOUBLE_QUOTE: return "\"";
-      case TokenKind.SLASH: return "/";
-      case TokenKind.EQUALS: return '=';
-      case TokenKind.OR: return '|';
-      case TokenKind.CARET: return '^';
-      case TokenKind.DOLLAR: return '\$';
-      case TokenKind.LESS: return '<';
-      case TokenKind.BANG: return '!';
-      case TokenKind.MINUS: return '-';
-
-      default:
-        throw "Unknown TOKEN";
-    }
-  }
-
-  TokenKind() {
-    tokens = [];
-
-    // All tokens must be in TokenKind order.
-    tokens.add(-1);                 // TokenKind.UNUSED
-    tokens.add(0);                  // TokenKind.END_OF_FILE match base
-    tokens.add(TokenKind.kindToString(TokenKind.LPAREN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RPAREN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.LBRACK).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RBRACK).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.LBRACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RBRACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.DOT).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SEMICOLON).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.AT).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.HASH).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.PLUS).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.GREATER).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.TILDE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.ASTERISK).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.NAMESPACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.COLON).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.PRIVATE_NAME).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.COMMA).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SPACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.TAB).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.NEWLINE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RETURN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.PERCENT).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SINGLE_QUOTE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.DOUBLE_QUOTE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SLASH).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.EQUALS).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.OR).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.CARET).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.DOLLAR).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.LESS).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.BANG).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.MINUS).codeUnitAt(0));
-
-    assert(tokens.length == TokenKind.END_TOKENS);
-  }
-
-  static bool isIdentifier(int kind) {
-    return kind == IDENTIFIER ;
-  }
-
-}
-
-class NoColorMatchException implements Exception {
-  String _colorName;
-  NoColorMatchException(this._colorName);
-
-  String get name => _colorName;
-}
diff --git a/utils/css/tool.dart b/utils/css/tool.dart
deleted file mode 100644
index beb2667..0000000
--- a/utils/css/tool.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library csstool;
-
-import 'dart:io';
-import 'css.dart';
-import '../lib/file_system.dart';
-import '../lib/file_system_vm.dart';
-
-
-FileSystem files;
-
-/** Invokes [callback] and returns how long it took to execute in ms. */
-num time(callback()) {
-  final watch = new Stopwatch();
-  watch.start();
-  callback();
-  watch.stop();
-  return watch.elapsedMilliseconds;
-}
-
-printStats(num elapsed, [String filename = '']) {
-  print('Parsed ${_GREEN_COLOR}${filename}${_NO_COLOR} in ${elapsed} msec.');
-}
-
-/**
- * Run from the `utils/css` directory.
- */
-void main(List<String> optionsArgs) {
-  assert(optionArgs.length == 2);
-
-  String sourceFullFn = optionArgs[0];
-  String outputFullFn = optionArgs[1];
-
-  String sourcePath;
-  String sourceFilename;
-  int idxBeforeFilename = sourceFullFn.lastIndexOf('/');
-  if (idxBeforeFilename >= 0) {
-    sourcePath = sourceFullFn.substring(0, idxBeforeFilename + 1);
-    sourceFilename = sourceFullFn.substring(idxBeforeFilename + 1);
-  }
-
-  String outPath;
-  idxBeforeFilename = outputFullFn.lastIndexOf('/');
-  if (idxBeforeFilename >= 0) {
-    outPath = outputFullFn.substring(0, idxBeforeFilename + 1);
-  }
-
-  initCssWorld();
-
-  files = new VMFileSystem();
-  if (!files.fileExists(sourceFullFn)) {
-    // Display colored error message if file is missing.
-    print("\033[31mCSS source file missing - ${sourceFullFn}\033[0m");
-  } else {
-    String source = files.readAll(sourceFullFn);
-
-    Stylesheet stylesheet;
-
-    final elapsed = time(() {
-      Parser parser = new Parser(
-          new SourceFile(sourceFullFn, source), 0, files, sourcePath);
-      stylesheet = parser.parse();
-    });
-
-    printStats(elapsed, sourceFullFn);
-
-    StringBuffer buff = new StringBuffer(
-      '/* File generated by SCSS from source ${sourceFilename}\n' +
-      ' * Do not edit.\n' +
-      ' */\n\n');
-    buff.write(stylesheet.toString());
-
-    files.writeString(outputFullFn, buff.toString());
-    print("Generated file ${outputFullFn}");
-
-    // Generate CSS.dart file.
-    String genDartClassFile = Generate.dartClass(files, outPath, stylesheet,
-        sourceFilename);
-    print("Generated file ${genDartClassFile}");
-  }
-}
diff --git a/utils/css/tree.dart b/utils/css/tree.dart
deleted file mode 100644
index 08160e4..0000000
--- a/utils/css/tree.dart
+++ /dev/null
@@ -1,1279 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Generated by scripts/tree_gen.py.
-
-/////////////////////////////////////////////////////////////////////////
-// CSS specific types:
-/////////////////////////////////////////////////////////////////////////
-
-
-class Identifier extends ASTNode {
-  String name;
-
-  Identifier(this.name, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitIdentifier(this);
-
-  String toString() => name;
-}
-
-class Wildcard extends ASTNode {
-  Wildcard(SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitWildcard(this);
-
-  String toString() => '*';
-}
-
-// /*  ....   */
-class CssComment extends ASTNode {
-  String comment;
-
-  CssComment(this.comment, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitCssComment(this);
-
-  String toString() => '/* ${comment} */';
-}
-
-// CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
-class CommentDefinition extends CssComment {
-  CommentDefinition(String comment, SourceSpan span): super(comment, span);
-
-  visit(TreeVisitor visitor) => visitor.visitCommentDefinition(this);
-
-  String toString() => '<!-- ${comment} -->';
-}
-
-class SelectorGroup extends ASTNode {
-  List<Selector> _selectors;
-
-  SelectorGroup(this._selectors, SourceSpan span): super(span);
-
-  List<Selector> get selectors => _selectors;
-
-  visit(TreeVisitor visitor) => visitor.visitSelectorGroup(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    int idx = 0;
-    for (final selector in _selectors) {
-      if (idx++ > 0) {
-        buff.write(', ');
-      }
-      buff.write(selector.toString());
-    }
-    return buff.toString();
-  }
-
-  /** A multiline string showing the node and its children. */
-  String toDebugString() {
-    var to = new TreeOutput();
-    var tp = new TreePrinter(to);
-    this.visit(tp);
-    return to.buf.toString();
-  }
-}
-
-class Selector extends ASTNode {
-  List<SimpleSelectorSequence> _simpleSelectorSequences;
-
-  Selector(this._simpleSelectorSequences, SourceSpan span) : super(span);
-
-  List<SimpleSelectorSequence> get simpleSelectorSequences =>
-      _simpleSelectorSequences;
-
-  add(SimpleSelectorSequence seq) => _simpleSelectorSequences.add(seq);
-
-  List<SimpleSelectorSequence> get simpleSelectorSquences =>
-      _simpleSelectorSequences;
-
-  int get length => _simpleSelectorSequences.length;
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    for (final simpleSelectorSequence in _simpleSelectorSequences) {
-      buff.write(simpleSelectorSequence.toString());
-    }
-    return buff.toString();
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitSelector(this);
-}
-
-class SimpleSelectorSequence extends ASTNode {
-  int _combinator;              // +, >, ~, NONE
-  SimpleSelector _selector;
-
-  SimpleSelectorSequence(this._selector, SourceSpan span,
-      [this._combinator = TokenKind.COMBINATOR_NONE]) : super(span);
-
-  get simpleSelector => _selector;
-
-  bool isCombinatorNone() => _combinator == TokenKind.COMBINATOR_NONE;
-  bool isCombinatorPlus() => _combinator == TokenKind.COMBINATOR_PLUS;
-  bool isCombinatorGreater() => _combinator == TokenKind.COMBINATOR_GREATER;
-  bool isCombinatorTilde() => _combinator == TokenKind.COMBINATOR_TILDE;
-  bool isCombinatorDescendant() =>
-      _combinator == TokenKind.COMBINATOR_DESCENDANT;
-
-  String _combinatorToString() =>
-      isCombinatorDescendant() ? ' ' :
-      isCombinatorPlus() ? '+' :
-      isCombinatorGreater() ? '>' :
-      isCombinatorTilde() ? '~' : '';
-
-  visit(TreeVisitor visitor) => visitor.visitSimpleSelectorSequence(this);
-
-  String toString() => "${_combinatorToString()}${_selector.toString()}";
-}
-
-/* All other selectors (element, #id, .class, attribute, pseudo, negation,
- * namespace, *) are derived from this selector.
- */
-class SimpleSelector extends ASTNode {
-  var _name;
-
-  SimpleSelector(this._name, SourceSpan span) : super(span);
-
-  // Name can be an Identifier or WildCard we'll return either the name or '*'.
-  String get name => isWildcard() ? '*' : _name.name;
-
-  bool isWildcard() => _name is Wildcard;
-
-  visit(TreeVisitor visitor) => visitor.visitSimpleSelector(this);
-
-  String toString() => name;
-}
-
-// element name
-class ElementSelector extends SimpleSelector {
-  ElementSelector(var name, SourceSpan span) : super(name, span);
-
-  visit(TreeVisitor visitor) => visitor.visitElementSelector(this);
-
-  String toString() => "$name";
-
-  /** A multiline string showing the node and its children. */
-  String toDebugString() {
-    var to = new TreeOutput();
-    var tp = new TreePrinter(to);
-    this.visit(tp);
-    return to.buf.toString();
-  }
-}
-
-// namespace|element
-class NamespaceSelector extends SimpleSelector {
-  var _namespace;           // null, Wildcard or Identifier
-
-  NamespaceSelector(this._namespace, var name, SourceSpan span) :
-      super(name, span);
-
-  String get namespace => _namespace is Wildcard ? '*' : _namespace.name;
-
-  bool isNamespaceWildcard() => _namespace is Wildcard;
-
-  SimpleSelector get nameAsSimpleSelector => _name;
-
-  visit(TreeVisitor visitor) => visitor.visitNamespaceSelector(this);
-
-  String toString() => "$namespace|${nameAsSimpleSelector.name}";
-}
-
-// [attr op value]
-class AttributeSelector extends SimpleSelector {
-  int _op;
-  var _value;
-
-  AttributeSelector(Identifier name, this._op, this._value,
-      SourceSpan span) : super(name, span);
-
-  String matchOperator() {
-    switch (_op) {
-    case TokenKind.EQUALS:
-      return '=';
-    case TokenKind.INCLUDES:
-      return '~=';
-    case TokenKind.DASH_MATCH:
-      return '|=';
-    case TokenKind.PREFIX_MATCH:
-      return '^=';
-    case TokenKind.SUFFIX_MATCH:
-      return '\$=';
-    case TokenKind.SUBSTRING_MATCH:
-      return '*=';
-    }
-  }
-
-  // Return the TokenKind for operator used by visitAttributeSelector.
-  String matchOperatorAsTokenString() {
-    switch (_op) {
-    case TokenKind.EQUALS:
-      return 'EQUALS';
-    case TokenKind.INCLUDES:
-      return 'INCLUDES';
-    case TokenKind.DASH_MATCH:
-      return 'DASH_MATCH';
-    case TokenKind.PREFIX_MATCH:
-      return 'PREFIX_MATCH';
-    case TokenKind.SUFFIX_MATCH:
-      return 'SUFFIX_MATCH';
-    case TokenKind.SUBSTRING_MATCH:
-      return 'SUBSTRING_MATCH';
-    }
-  }
-
-  String valueToString() {
-    if (_value is Identifier) {
-      return _value.name;
-    } else {
-      return '"${_value}"';
-    }
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitAttributeSelector(this);
-
-  String toString() => "[${name} ${matchOperator()} ${valueToString()}]";
-}
-
-// #id
-class IdSelector extends SimpleSelector {
-  IdSelector(Identifier name, SourceSpan span) : super(name, span);
-
-  visit(TreeVisitor visitor) => visitor.visitIdSelector(this);
-
-  String toString() => "#$name";
-}
-
-// .class
-class ClassSelector extends SimpleSelector {
-  ClassSelector(Identifier name, SourceSpan span) : super(name, span);
-
-  visit(TreeVisitor visitor) => visitor.visitClassSelector(this);
-
-  String toString() => ".$name";
-}
-
-// :pseudoClass
-class PseudoClassSelector extends SimpleSelector {
-  PseudoClassSelector(Identifier name, SourceSpan span) :
-      super(name, span);
-
-  visit(TreeVisitor visitor) => visitor.visitPseudoClassSelector(this);
-
-  String toString() => ":$name";
-}
-
-// ::pseudoElement
-class PseudoElementSelector extends SimpleSelector {
-  PseudoElementSelector(Identifier name, SourceSpan span) :
-      super(name, span);
-
-  visit(TreeVisitor visitor) => visitor.visitPseudoElementSelector(this);
-
-  String toString() => "::$name";
-}
-
-// TODO(terry): Implement
-// NOT
-class NotSelector extends SimpleSelector {
-  NotSelector(String name, SourceSpan span) : super(name, span);
-
-  visit(TreeVisitor visitor) => visitor.visitNotSelector(this);
-}
-
-class Stylesheet extends ASTNode {
-  // Contains charset, ruleset, directives (media, page, etc.)
-  List<ASTNode> _topLevels;
-
-  Stylesheet(this._topLevels, SourceSpan span) : super(span) {
-    for (final node in _topLevels) {
-      assert(node is TopLevelProduction || node is Directive);
-    }
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitStylesheet(this);
-
-  List<ASTNode> get topLevels => _topLevels;
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    for (final topLevel in _topLevels) {
-      buff.write(topLevel.toString());
-    }
-    return buff.toString();
-  }
-
-  /** A multiline string showing the node and its children. */
-  String toDebugString() {
-    var to = new TreeOutput();
-    var tp = new TreePrinter(to);
-    this.visit(tp);
-    return to.buf.toString();
-  }
-}
-
-class TopLevelProduction extends ASTNode {
-  TopLevelProduction(SourceSpan span) : super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTopLevelProduction(this);
-
-  String toString() => "TopLevelProduction";
-}
-
-class RuleSet extends TopLevelProduction {
-  SelectorGroup _selectorGroup;
-  DeclarationGroup _declarationGroup;
-
-  RuleSet(this._selectorGroup, this._declarationGroup, SourceSpan span) :
-      super(span);
-
-  SelectorGroup get selectorGroup => _selectorGroup;
-  DeclarationGroup get declarationGroup => _declarationGroup;
-
-  visit(TreeVisitor visitor) => visitor.visitRuleSet(this);
-
-  String toString() =>
-      "\n${_selectorGroup.toString()} {\n"
-        "${_declarationGroup.toString()}}\n";
-}
-
-class Directive extends ASTNode {
-  Directive(SourceSpan span) : super(span);
-
-  String toString() => "Directive";
-
-  bool get isBuiltIn => true;       // Known CSS directive?
-  bool get isExtension => false;    // SCSS extension?
-
-  visit(TreeVisitor visitor) => visitor.visitDirective(this);
-}
-
-class ImportDirective extends Directive {
-  String _import;
-  List<String> _media;
-
-  ImportDirective(this._import, this._media, SourceSpan span) :
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitImportDirective(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-
-    buff.write('@import url(${_import})');
-
-    int idx = 0;
-    for (final medium in _media) {
-      buff.write(idx++ == 0 ? ' $medium' : ',$medium');
-    }
-    buff.write('\n');
-
-    return buff.toString();
-  }
-}
-
-class MediaDirective extends Directive {
-  List<String> _media;
-  RuleSet _ruleset;
-
-  MediaDirective(this._media, this._ruleset, SourceSpan span) :
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitMediaDirective(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-
-    buff.write('@media');
-    int idx = 0;
-    for (var medium in _media) {
-      buff.write(idx++ == 0 ? ' $medium' : ',$medium');
-    }
-    buff.write(' {\n');
-    buff.write(_ruleset.toString());
-    buff.write('\n\}\n');
-
-    return buff.toString();
-  }
-}
-
-class PageDirective extends Directive {
-  String _pseudoPage;
-  DeclarationGroup _decls;
-
-  PageDirective(this._pseudoPage, this._decls, SourceSpan span) :
-    super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitPageDirective(this);
-
-  // @page : pseudoPage {
-  //    decls
-  // }
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-
-    buff.write('@page ');
-    if (_pseudoPage != null) {
-      buff.write(': ${_pseudoPage} ');
-    }
-    buff.write('{\n${_decls.toString()}\n}\n');
-
-    return buff.toString();
-  }
-}
-
-class KeyFrameDirective extends Directive {
-  var _name;
-  List<KeyFrameBlock> _blocks;
-
-  KeyFrameDirective(this._name, SourceSpan span) :
-      _blocks = [], super(span);
-
-  add(KeyFrameBlock block) {
-    _blocks.add(block);
-  }
-
-  String get name => _name;
-
-  visit(TreeVisitor visitor) => visitor.visitKeyFrameDirective(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    buff.write('@-webkit-keyframes ${_name} {\n');
-    for (final block in _blocks) {
-      buff.write(block.toString());
-    }
-    buff.write('}\n');
-    return buff.toString();
-  }
-}
-
-class KeyFrameBlock extends Expression {
-  Expressions _blockSelectors;
-  DeclarationGroup _declarations;
-
-  KeyFrameBlock(this._blockSelectors, this._declarations, SourceSpan span):
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitKeyFrameBlock(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    buff.write('  ${_blockSelectors.toString()} {\n');
-    buff.write(_declarations.toString());
-    buff.write('  }\n');
-    return buff.toString();
-  }
-}
-
-// TODO(terry): TBD
-class FontFaceDirective extends Directive {
-  List<Declaration> _declarations;
-
-  FontFaceDirective(this._declarations, SourceSpan span) : super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitFontFaceDirective(this);
-
-  String toString() {
-    return "TO BE DONE";
-  }
-}
-
-class IncludeDirective extends Directive {
-  String _include;
-  Stylesheet _stylesheet;
-
-  IncludeDirective(this._include, this._stylesheet, SourceSpan span) :
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitIncludeDirective(this);
-
-  bool get isBuiltIn => false;
-  bool get isExtension => true;
-
-  Stylesheet get styleSheet => _stylesheet;
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    buff.write('/****** @include ${_include} ******/\n');
-    buff.write(_stylesheet != null ? _stylesheet.toString() : '// <EMPTY>');
-    buff.write('/****** End of ${_include} ******/\n\n');
-    return buff.toString();
-  }
-}
-
-class StyletDirective extends Directive {
-  String _dartClassName;
-  List<RuleSet> _rulesets;
-
-  StyletDirective(this._dartClassName, this._rulesets, SourceSpan span) :
-      super(span);
-
-  bool get isBuiltIn => false;
-  bool get isExtension => true;
-
-  String get dartClassName => _dartClassName;
-  List<RuleSet> get rulesets => _rulesets;
-
-  visit(TreeVisitor visitor) => visitor.visitStyletDirective(this);
-
-  // TODO(terry): Output Dart class
-  String toString() => '/* @stylet export as ${_dartClassName} */\n';
-}
-
-class Declaration extends ASTNode {
-  Identifier _property;
-  Expression _expression;
-  bool _important;
-
-  Declaration(this._property, this._expression, SourceSpan span) :
-      _important = false, super(span);
-
-  String get property => _property.name;
-  Expression get expression => _expression;
-
-  bool get important => _important;
-  set important(bool value) => _important = value;
-  String importantAsString() => _important ? ' !important' : '';
-
-  visit(TreeVisitor visitor) => visitor.visitDeclaration(this);
-
-  String toString() =>
-      "${_property.name}: ${_expression.toString()}${importantAsString()}";
-}
-
-class DeclarationGroup extends ASTNode {
-  List<Declaration> _declarations;
-
-  DeclarationGroup(this._declarations, SourceSpan span) : super(span);
-
-  List<Declaration> get declarations => _declarations;
-
-  visit(TreeVisitor visitor) => visitor.visitDeclarationGroup(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    int idx = 0;
-    for (final declaration in _declarations) {
-      buff.write("  ${declaration.toString()};\n");
-    }
-    return buff.toString();
-  }
-}
-
-class OperatorSlash extends Expression {
-  OperatorSlash(SourceSpan span) : super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitOperatorSlash(this);
-
-  String toString() => ' /';
-}
-
-class OperatorComma extends Expression {
-  OperatorComma(SourceSpan span) : super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitOperatorComma(this);
-
-  String toString() => ',';
-}
-
-class LiteralTerm extends Expression {
-  var _value;
-  String _text;
-
-  LiteralTerm(this._value, this._text, SourceSpan span) : super(span);
-
-  get value => _value;
-  String get text => _text;
-
-  visit(TreeVisitor visitor) => visitor.visitLiteralTerm(this);
-
-  String toString() => _text;
-}
-
-class NumberTerm extends LiteralTerm {
-  NumberTerm(var value, String t, SourceSpan span) : super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitNumberTerm(this);
-}
-
-class UnitTerm extends LiteralTerm {
-  int _unit;
-
-  UnitTerm(var value, String t, SourceSpan span, this._unit) :
-      super(value, t, span);
-
-  int get unit => _unit;
-
-  visit(TreeVisitor visitor) => visitor.visitUnitTerm(this);
-
-  String toString() => '${text}${unitToString()}';
-  String unitToString() => TokenKind.unitToString(_unit);
-}
-
-class LengthTerm extends UnitTerm {
-  LengthTerm(var value, String t, SourceSpan span,
-      [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
-    assert(this._unit == TokenKind.UNIT_LENGTH_PX ||
-        this._unit == TokenKind.UNIT_LENGTH_CM ||
-        this._unit == TokenKind.UNIT_LENGTH_MM ||
-        this._unit == TokenKind.UNIT_LENGTH_IN ||
-        this._unit == TokenKind.UNIT_LENGTH_PT ||
-        this._unit == TokenKind.UNIT_LENGTH_PC);
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitLengthTerm(this);
-}
-
-class PercentageTerm extends LiteralTerm {
-  PercentageTerm(var value, String t, SourceSpan span) :
-      super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitPercentageTerm(this);
-
-  String toString() => '${text}%';
-
-}
-
-class EmTerm extends LiteralTerm {
-  EmTerm(var value, String t, SourceSpan span) :
-      super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitEmTerm(this);
-
-  String toString() => '${text}em';
-}
-
-class ExTerm extends LiteralTerm {
-  ExTerm(var value, String t, SourceSpan span) :
-      super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitExTerm(this);
-
-  String toString() => '${text}ex';
-}
-
-class AngleTerm extends UnitTerm {
-  AngleTerm(var value, String t, SourceSpan span,
-    [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
-    assert(this._unit == TokenKind.UNIT_ANGLE_DEG ||
-        this._unit == TokenKind.UNIT_ANGLE_RAD ||
-        this._unit == TokenKind.UNIT_ANGLE_GRAD);
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitAngleTerm(this);
-}
-
-class TimeTerm extends UnitTerm {
-  TimeTerm(var value, String t, SourceSpan span,
-    [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
-    assert(this._unit == TokenKind.UNIT_ANGLE_DEG ||
-        this._unit == TokenKind.UNIT_TIME_MS ||
-        this._unit == TokenKind.UNIT_TIME_S);
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitTimeTerm(this);
-}
-
-class FreqTerm extends UnitTerm {
-  FreqTerm(var value, String t, SourceSpan span,
-    [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
-    assert(_unit == TokenKind.UNIT_FREQ_HZ || _unit == TokenKind.UNIT_FREQ_KHZ);
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitFreqTerm(this);
-}
-
-class FractionTerm extends LiteralTerm {
-  FractionTerm(var value, String t, SourceSpan span) :
-    super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitFractionTerm(this);
-
-  String toString() => '${text}fr';
-}
-
-class UriTerm extends LiteralTerm {
-  UriTerm(String value, SourceSpan span) : super(value, value, span);
-
-  visit(TreeVisitor visitor) => visitor.visitUriTerm(this);
-
-  String toString() => 'url(${text})';
-}
-
-class HexColorTerm extends LiteralTerm {
-  HexColorTerm(var value, String t, SourceSpan span) :
-      super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitHexColorTerm(this);
-
-  String toString() => '#${text}';
-}
-
-class FunctionTerm extends LiteralTerm {
-  Expressions _params;
-
-  FunctionTerm(var value, String t, this._params, SourceSpan span)
-      : super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitFunctionTerm(this);
-
-  String toString() {
-    // TODO(terry): Optimize rgb to a hexcolor.
-    StringBuffer buff = new StringBuffer();
-
-    buff.write('${text}(');
-    buff.write(_params.toString());
-    buff.write(')');
-
-    return buff.toString();
-  }
-}
-
-class GroupTerm extends Expression {
-  List<LiteralTerm> _terms;
-
-  GroupTerm(SourceSpan span) : _terms =  [], super(span);
-
-  add(LiteralTerm term) {
-    _terms.add(term);
-  }
-
-  visit(TreeVisitor visitor) => visitor.visitGroupTerm(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    buff.write('(');
-    int idx = 0;
-    for (final term in _terms) {
-      if (idx++ > 0) {
-        buff.write(' ');
-      }
-      buff.write(term.toString());
-    }
-    buff.write(')');
-    return buff.toString();
-  }
-}
-
-class ItemTerm extends NumberTerm {
-  ItemTerm(var value, String t, SourceSpan span) : super(value, t, span);
-
-  visit(TreeVisitor visitor) => visitor.visitItemTerm(this);
-
-  String toString() => '[${text}]';
-}
-
-class Expressions extends Expression {
-  List<Expression> _expressions;
-
-  Expressions(SourceSpan span): super(span), _expressions = [];
-
-  add(Expression expression) {
-    _expressions.add(expression);
-  }
-
-  List<Expression> get expressions => _expressions;
-
-  visit(TreeVisitor visitor) => visitor.visitExpressions(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    int idx = 0;
-    for (final expression in _expressions) {
-      // Add space seperator between terms without an operator.
-      // TODO(terry): Should have a BinaryExpression to solve this problem.
-      if (idx > 0 &&
-          !(expression is OperatorComma || expression is OperatorSlash)) {
-        buff.write(' ');
-      }
-      buff.write(expression.toString());
-      idx++;
-    }
-    return buff.toString();
-  }
-}
-
-class BinaryExpression extends Expression {
-  Token op;
-  Expression x;
-  Expression y;
-
-  BinaryExpression(this.op, this.x, this.y, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitBinaryExpression(this);
-}
-
-class UnaryExpression extends Expression {
-  Token op;
-  Expression self;
-
-  UnaryExpression(this.op, this.self, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitUnaryExpression(this);
-}
-
-abstract class TreeVisitor {
-  void visitCssComment(CssComment node);
-  void visitCommentDefinition(CommentDefinition node);
-  void visitStylesheet(Stylesheet node);
-  void visitTopLevelProduction(TopLevelProduction node);
-  void visitDirective(Directive node);
-  void visitMediaDirective(MediaDirective node);
-  void visitPageDirective(PageDirective node);
-  void visitImportDirective(ImportDirective node);
-  void visitKeyFrameDirective(KeyFrameDirective node);
-  void visitKeyFrameBlock(KeyFrameBlock node);
-  void visitFontFaceDirective(FontFaceDirective node);
-  void visitIncludeDirective(IncludeDirective node);
-  void visitStyletDirective(StyletDirective node);
-
-  void visitRuleSet(RuleSet node);
-  void visitDeclarationGroup(DeclarationGroup node);
-  void visitDeclaration(Declaration node);
-  void visitSelectorGroup(SelectorGroup node);
-  void visitSelector(Selector node);
-  void visitSimpleSelectorSequence(SimpleSelectorSequence node);
-  void visitSimpleSelector(SimpleSelector node);
-  void visitElementSelector(ElementSelector node);
-  void visitNamespaceSelector(NamespaceSelector node);
-  void visitAttributeSelector(AttributeSelector node);
-  void visitIdSelector(IdSelector node);
-  void visitClassSelector(ClassSelector node);
-  void visitPseudoClassSelector(PseudoClassSelector node);
-  void visitPseudoElementSelector(PseudoElementSelector node);
-  void visitNotSelector(NotSelector node);
-
-  void visitLiteralTerm(LiteralTerm node);
-  void visitHexColorTerm(HexColorTerm node);
-  void visitNumberTerm(NumberTerm node);
-  void visitUnitTerm(UnitTerm node);
-  void visitLengthTerm(LengthTerm node);
-  void visitPercentageTerm(PercentageTerm node);
-  void visitEmTerm(EmTerm node);
-  void visitExTerm(ExTerm node);
-  void visitAngleTerm(AngleTerm node);
-  void visitTimeTerm(TimeTerm node);
-  void visitFreqTerm(FreqTerm node);
-  void visitFractionTerm(FractionTerm node);
-  void visitUriTerm(UriTerm node);
-  void visitFunctionTerm(FunctionTerm node);
-  void visitGroupTerm(GroupTerm node);
-  void visitItemTerm(ItemTerm node);
-  void visitOperatorSlash(OperatorSlash node);
-  void visitOperatorComma(OperatorComma node);
-
-  void visitExpressions(Expressions node);
-  void visitBinaryExpression(BinaryExpression node);
-  void visitUnaryExpression(UnaryExpression node);
-
-  void visitIdentifier(Identifier node);
-  void visitWildcard(Wildcard node);
-
-  // TODO(terry): Defined for ../tree.dart.
-  void visitTypeReference(TypeReference node);
-}
-
-class TreePrinter implements TreeVisitor {
-  var output;
-  TreePrinter(this.output) { output.printer = this; }
-
-  void visitStylesheet(Stylesheet node) {
-    output.heading('Stylesheet', node.span);
-    output.depth++;
-    output.writeNodeList('productions', node._topLevels);
-    output.depth--;
-  }
-
-  void visitTopLevelProduction(TopLevelProduction node) {
-    output.heading('TopLevelProduction', node.span);
-  }
-
-  void visitDirective(Directive node) {
-    output.heading('Directive', node.span);
-  }
-
-  void visitCssComment(CssComment node) {
-    output.heading('Comment', node.span);
-    output.depth++;
-    output.writeValue('comment value', node.comment);
-    output.depth--;
-  }
-
-  void visitCommentDefinition(CommentDefinition node) {
-    output.heading('CommentDefinition (CDO/CDC)', node.span);
-    output.depth++;
-    output.writeValue('comment value', node.comment);
-    output.depth--;
-  }
-
-  void visitMediaDirective(MediaDirective node) {
-    output.heading('MediaDirective', node.span);
-    output.depth++;
-    output.writeNodeList('media', node._media);
-    visitRuleSet(node._ruleset);
-    output.depth--;
-  }
-
-  void visitPageDirective(PageDirective node) {
-    output.heading('PageDirective', node.span);
-    output.depth++;
-    output.writeValue('pseudo page', node._pseudoPage);
-    visitDeclarationGroup(node._decls);
-    output.depth;
-}
-
-  void visitImportDirective(ImportDirective node) {
-    output.heading('ImportDirective', node.span);
-    output.depth++;
-    output.writeValue('import', node._import);
-    output.writeNodeList('media', node._media);
-    output.depth--;
-  }
-
-  void visitKeyFrameDirective(KeyFrameDirective node) {
-    output.heading('KeyFrameDirective', node.span);
-    output.depth++;
-    output.writeValue('name', node._name);
-    output.writeNodeList('blocks', node._blocks);
-    output.depth--;
-  }
-
-  void visitKeyFrameBlock(KeyFrameBlock node) {
-    output.heading('KeyFrameBlock', node.span);
-    output.depth++;
-    visitExpressions(node._blockSelectors);
-    visitDeclarationGroup(node._declarations);
-    output.depth--;
-  }
-
-  void visitFontFaceDirective(FontFaceDirective node) {
-    // TODO(terry): To Be Implemented
-  }
-
-  void visitIncludeDirective(IncludeDirective node) {
-    output.heading('IncludeDirective', node.span);
-    output.writeValue('include', node._include);
-    output.depth++;
-    if (node._stylesheet != null) {
-      visitStylesheet(node._stylesheet);
-    } else {
-      output.writeValue('StyleSheet', '<EMPTY>');
-    }
-    output.depth--;
-  }
-
-  void visitStyletDirective(StyletDirective node) {
-    output.heading('StyletDirective', node.span);
-    output.writeValue('dartClassName', node._dartClassName);
-    output.depth++;
-    output.writeNodeList('rulesets', node._rulesets);
-    output.depth--;
-}
-
-  void visitRuleSet(RuleSet node) {
-    output.heading('Ruleset', node.span);
-    output.depth++;
-    visitSelectorGroup(node._selectorGroup);
-    visitDeclarationGroup(node._declarationGroup);
-    output.depth--;
-  }
-
-  void visitDeclarationGroup(DeclarationGroup node) {
-    output.heading('DeclarationGroup', node.span);
-    output.depth++;
-    output.writeNodeList('declarations', node._declarations);
-    output.depth--;
-  }
-
-  void visitDeclaration(Declaration node) {
-    output.heading('Declaration', node.span);
-    output.depth++;
-    output.write('property');
-    visitIdentifier(node._property);
-    output.writeNode('expression', node._expression);
-    if (node.important) {
-      output.writeValue('!important', 'true');
-    }
-    output.depth--;
-  }
-
-  void visitSelectorGroup(SelectorGroup node) {
-    output.heading('Selector Group', node.span);
-    output.depth++;
-    output.writeNodeList('selectors', node.selectors);
-    output.depth--;
-  }
-
-  void visitSelector(Selector node) {
-    output.heading('Selector', node.span);
-    output.depth++;
-    output.writeNodeList('simpleSelectorsSequences',
-        node._simpleSelectorSequences);
-    output.depth--;
-  }
-
-  void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
-    output.heading('SimpleSelectorSequence', node.span);
-    output.depth++;
-    if (node.isCombinatorNone()) {
-      output.writeValue('combinator', "NONE");
-    } else if (node.isCombinatorDescendant()) {
-      output.writeValue('combinator', "descendant");
-    } else if (node.isCombinatorPlus()) {
-      output.writeValue('combinator', "+");
-    } else if (node.isCombinatorGreater()) {
-      output.writeValue('combinator', ">");
-    } else if (node.isCombinatorTilde()) {
-      output.writeValue('combinator', "~");
-    } else {
-      output.writeValue('combinator', "ERROR UNKNOWN");
-    }
-
-    var selector = node._selector;
-    if (selector is NamespaceSelector) {
-      visitNamespaceSelector(selector);
-    } else if (selector is ElementSelector) {
-      visitElementSelector(selector);
-    } else if (selector is IdSelector) {
-      visitIdSelector(selector);
-    } else if (selector is ClassSelector) {
-      visitClassSelector(selector);
-    } else if (selector is PseudoClassSelector) {
-      visitPseudoClassSelector(selector);
-    } else if (selector is PseudoElementSelector) {
-      visitPseudoElementSelector(selector);
-    } else if (selector is NotSelector) {
-      visitNotSelector(selector);
-    } else if (selector is AttributeSelector) {
-      visitAttributeSelector(selector);
-    } else {
-      output.heading('SimpleSelector', selector.span);
-      output.depth++;
-      visitSimpleSelector(selector);
-      output.depth--;
-    }
-
-    output.depth--;
-  }
-
-  void visitSimpleSelector(SimpleSelector node) {
-    visitIdentifier(node._name);
-  }
-
-  void visitNamespaceSelector(NamespaceSelector node) {
-    output.heading('Namespace Selector', node.span);
-    output.depth++;
-
-    var namespace = node._namespace;
-    if (namespace is Identifier) {
-      visitIdentifier(namespace);
-    } else if (namespace is Wildcard) {
-      visitWildcard(namespace);
-    } else {
-      output.writeln("NULL");
-    }
-
-    visitSimpleSelector(node.nameAsSimpleSelector);
-    output.depth--;
-  }
-
-  void visitElementSelector(ElementSelector node) {
-    output.heading('Element Selector', node.span);
-    output.depth++;
-    visitSimpleSelector(node);
-    output.depth--;
-  }
-
-  void visitAttributeSelector(AttributeSelector node) {
-    output.heading('AttributeSelector', node.span);
-    output.depth++;
-    visitSimpleSelector(node);
-    String tokenStr = node.matchOperatorAsTokenString();
-    output.writeValue('operator', '${node.matchOperator()} (${tokenStr})');
-    output.writeValue('value', node.valueToString());
-    output.depth--;
-  }
-
-  void visitIdSelector(IdSelector node) {
-    output.heading('Id Selector', node.span);
-    output.depth++;
-    visitSimpleSelector(node);
-    output.depth--;
-  }
-
-  void visitClassSelector(ClassSelector node) {
-    output.heading('Class Selector', node.span);
-    output.depth++;
-    visitSimpleSelector(node);
-    output.depth--;
-  }
-
-  void visitPseudoClassSelector(PseudoClassSelector node) {
-    output.heading('Pseudo Class Selector', node.span);
-    output.depth++;
-    visitSimpleSelector(node);
-    output.depth--;
-  }
-
-  void visitPseudoElementSelector(PseudoElementSelector node) {
-    output.heading('Pseudo Element Selector', node.span);
-    output.depth++;
-    visitSimpleSelector(node);
-    output.depth--;
-  }
-
-  void visitNotSelector(NotSelector node) {
-    visitSimpleSelector(node);
-    output.depth++;
-    output.heading('Not Selector', node.span);
-    output.depth--;
-  }
-
-  void visitLiteralTerm(LiteralTerm node) {
-    output.heading('LiteralTerm', node.span);
-    output.depth++;
-    output.writeValue('value', node.text);
-    output.depth--;
- }
-
-  void visitHexColorTerm(HexColorTerm node) {
-    output.heading('HexColorTerm', node.span);
-    output.depth++;
-    output.writeValue('hex value', node.text);
-    output.writeValue('decimal value', node.value);
-    output.depth--;
-  }
-
-  void visitNumberTerm(NumberTerm node) {
-    output.heading('NumberTerm', node.span);
-    output.depth++;
-    output.writeValue('value', node.text);
-    output.depth--;
-  }
-
-  void visitUnitTerm(UnitTerm node) {
-    String unitValue;
-
-    output.depth++;
-    output.writeValue('value', node.text);
-    output.writeValue('unit', node.unitToString());
-    output.depth--;
-  }
-
-  void visitLengthTerm(LengthTerm node) {
-    output.heading('LengthTerm', node.span);
-    visitUnitTerm(node);
-  }
-
-  void visitPercentageTerm(PercentageTerm node) {
-    output.heading('PercentageTerm', node.span);
-    output.depth++;
-    visitLiteralTerm(node);
-    output.depth--;
-  }
-
-  void visitEmTerm(EmTerm node) {
-    output.heading('EmTerm', node.span);
-    output.depth++;
-    visitLiteralTerm(node);
-    output.depth--;
-  }
-
-  void visitExTerm(ExTerm node) {
-    output.heading('ExTerm', node.span);
-    output.depth++;
-    visitLiteralTerm(node);
-    output.depth--;
-  }
-
-  void visitAngleTerm(AngleTerm node) {
-    output.heading('AngleTerm', node.span);
-    visitUnitTerm(node);
-  }
-
-  void visitTimeTerm(TimeTerm node) {
-    output.heading('TimeTerm', node.span);
-    visitUnitTerm(node);
-  }
-
-  void visitFreqTerm(FreqTerm node) {
-    output.heading('FreqTerm', node.span);
-    visitUnitTerm(node);
-  }
-
-  void visitFractionTerm(FractionTerm node) {
-    output.heading('FractionTerm', node.span);
-    output.depth++;
-    visitLiteralTerm(node);
-    output.depth--;
-  }
-
-  void visitUriTerm(UriTerm node) {
-    output.heading('UriTerm', node.span);
-    output.depth++;
-    visitLiteralTerm(node);
-    output.depth--;
-  }
-
-  void visitFunctionTerm(FunctionTerm node) {
-    output.heading('FunctionTerm', node.span);
-    output.depth++;
-    visitLiteralTerm(node);
-    visitExpressions(node._params);
-    output.depth--;
-  }
-
-  void visitGroupTerm(GroupTerm node) {
-    output.heading('GroupTerm', node.span);
-    output.depth++;
-    output.writeNodeList('grouped terms', node._terms);
-    output.depth--;
-  }
-
-  void visitItemTerm(ItemTerm node) {
-    output.heading('ItemTerm', node.span);
-    visitNumberTerm(node);
-  }
-
-  void visitOperatorSlash(OperatorSlash node) {
-    output.heading('OperatorSlash', node.span);
-  }
-
-  void visitOperatorComma(OperatorComma node) {
-    output.heading('OperatorComma', node.span);
-  }
-
-  void visitExpressions(Expressions node) {
-    output.heading('Expressions', node.span);
-    output.depth++;
-    output.writeNodeList('expressions', node._expressions);
-    output.depth--;
-  }
-
-  void visitBinaryExpression(BinaryExpression node) {
-    output.heading('BinaryExpression', node.span);
-    // TODO(terry): TBD
-  }
-
-  void visitUnaryExpression(UnaryExpression node) {
-    output.heading('UnaryExpression', node.span);
-    // TODO(terry): TBD
-  }
-
-  void visitIdentifier(Identifier node) {
-    output.heading('Identifier(${output.toValue(node.name)})', node.span);
-  }
-
-  void visitWildcard(Wildcard node) {
-    output.heading('Wildcard(*)', node.span);
-  }
-
-  // TODO(terry): Defined for frog/tree.dart.
-  void visitTypeReference(TypeReference node) {
-    output.heading('Unimplemented');
-  }
-}
diff --git a/utils/css/treebase.dart b/utils/css/treebase.dart
deleted file mode 100644
index 7bdc3e6..0000000
--- a/utils/css/treebase.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-/**
- * The base type for all nodes in a dart abstract syntax tree.
- */
-class ASTNode {
-  /** The source code this [ASTNode] represents. */
-  SourceSpan span;
-
-  ASTNode(this.span) {}
-
-  /** Classic double-dispatch visitor for implementing passes. */
-  abstract visit(TreeVisitor visitor);
-
-  /** A multiline string showing the node and its children. */
-  String toDebugString() {
-    var to = new TreeOutput();
-    var tp = new TreePrinter(to);
-    this.visit(tp);
-    return to.buf.toString();
-  }
-}
-
-/** The base type for expressions. */
-// TODO(terry): Should be abstract class; but frog doesn't support abstract.
-class Expression extends ASTNode {
-  Expression(SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) {}   // TODO(terry): remove when abstract.
-}
-
-/** The base type for a reference to a [Type]. */
-// TODO(terry): Should be abstract class; but frog doesn't support abstract.
-class TypeReference extends ASTNode {
-  TypeReference(SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) {}   // TODO(terry): remove when abstract.
-}
-
-// TODO(jimhug): Clean-up and factor out of core.
-/** Simple class to provide a textual dump of trees for debugging. */
-class TreeOutput {
-  int depth;
-  StringBuffer buf;
-
-  var printer;
-
-  static void dump(ASTNode node) {
-    var o = new TreeOutput();
-    node.visit(new TreePrinter(o));
-    print(o.buf);
-  }
-
-  TreeOutput(): this.depth = 0, this.buf = new StringBuffer() {
-  }
-
-  void write(String s) {
-    for (int i=0; i < depth; i++) {
-      buf.write(' ');
-    }
-    buf.write(s);
-  }
-
-  void writeln(String s) {
-    write(s);
-    buf.write('\n');
-  }
-
-  void heading(String name, span) {
-    write(name);
-    buf.write('  (${span.locationText})');
-    buf.write('\n');
-  }
-
-  String toValue(value) {
-    if (value == null) return 'null';
-    else if (value is Identifier) return value.name;
-    else return value.toString();
-  }
-
-  void writeNode(String label, ASTNode node) {
-    write(label + ': ');
-    depth += 1;
-    if (node != null) node.visit(printer);
-    else writeln('null');
-    depth -= 1;
-  }
-
-  void writeValue(String label, value) {
-    var v = toValue(value);
-    writeln('${label}: ${v}');
-  }
-
-  void writeList(String label, List list) {
-    write(label + ': ');
-    if (list == null) {
-      buf.write('null');
-      buf.write('\n');
-    } else {
-      for (var item in list) {
-        buf.write(item.toString());
-        buf.write(', ');
-      }
-      buf.write('\n');
-    }
-  }
-
-  void writeNodeList(String label, List list) {
-    writeln('${label} [');
-    if (list != null) {
-      depth += 1;
-      for (var node in list) {
-        if (node != null) {
-          node.visit(printer);
-        } else {
-          writeln('null');
-        }
-      }
-      depth -= 1;
-      writeln(']');
-    }
-  }
-}
diff --git a/utils/css/uitest.dart b/utils/css/uitest.dart
deleted file mode 100644
index bbbbad0..0000000
--- a/utils/css/uitest.dart
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'css.dart';
-import '../lib/file_system_memory.dart';
-
-void runCss([bool debug = false, bool parseOnly = false]) {
-  final Document doc = window.document;
-  final TextAreaElement classes = doc.query("#classes");
-  final TextAreaElement expression = doc.query('#expression');
-  final TableCellElement validity = doc.query('#validity');
-  final TableCellElement result = doc.query('#result');
-
-  List<String> knownWorld = classes.value.split("\n");
-  List<String> knownClasses = [];
-  List<String> knownIds = [];
-  for (final name in knownWorld) {
-    if (name.startsWith('.')) {
-      knownClasses.add(name.substring(1));
-    } else if (name.startsWith('#')) {
-      knownIds.add(name.substring(1));
-    }
-  }
-
-  CssWorld cssWorld = new CssWorld(knownClasses, knownIds);
-  bool templateValid = true;
-  String dumpTree = "";
-
-  String cssExpr = expression.value;
-  if (!debug) {
-    try {
-      cssParseAndValidate(cssExpr, cssWorld);
-    } catch (cssException) {
-      templateValid = false;
-      dumpTree = cssException.toString();
-    }
-  } else if (parseOnly) {
-    try {
-      Parser parser = new Parser(new SourceFile(
-          SourceFile.IN_MEMORY_FILE, cssExpr));
-      Stylesheet stylesheet = parser.parse();
-      StringBuffer stylesheetTree = new StringBuffer();
-      String prettyStylesheet = stylesheet.toString();
-      stylesheetTree.write("${prettyStylesheet}\n");
-      stylesheetTree.write("\n============>Tree Dump<============\n");
-      stylesheetTree.write(stylesheet.toDebugString());
-      dumpTree = stylesheetTree.toString();
-    } catch (cssParseException) {
-      templateValid = false;
-      dumpTree = cssParseException.toString();
-    }
-  } else {
-    try {
-      dumpTree = cssParseAndValidateDebug(cssExpr, cssWorld);
-    } catch (cssException) {
-      templateValid = false;
-      dumpTree = cssException.toString();
-    }
-  }
-
-  final bgcolor = templateValid ? "white" : "red";
-  final color = templateValid ? "black" : "white";
-  final valid = templateValid ? "VALID" : "NOT VALID";
-  String resultStyle = "resize:none; margin:0; height:100%; width:100%;"
-    "padding:5px 7px;";
-  String validityStyle = "font-weight:bold; background-color:$bgcolor;"
-    "color:$color; border:1px solid black; border-bottom:0px solid white;";
-  validity.innerHTML = '''
-    <div style="$validityStyle">
-      Expression: $cssExpr is $valid
-    </div>
-  ''';
-  result.innerHTML = "<textarea style=\"$resultStyle\">$dumpTree</textarea>";
-}
-
-void main() {
-  final element = new Element.tag('div');
-  element.innerHTML = '''
-    <table style="width: 100%; height: 100%;">
-      <tbody>
-        <tr>
-          <td style="vertical-align: top; width: 200px;">
-            <table style="height: 100%;">
-              <tbody>
-                <tr style="vertical-align: top; height: 1em;">
-                  <td>
-                    <span style="font-weight:bold;">Classes</span>
-                  </td>
-                </tr>
-                <tr style="vertical-align: top;">
-                  <td>
-                    <textarea id="classes" style="resize: none; width: 200px; height: 100%; padding: 5px 7px;">.foobar\n.xyzzy\n.test\n.dummy\n#myId\n#myStory</textarea>
-                  </td>
-                </tr>
-              </tbody>
-            </table>
-          </td>
-          <td>
-            <table style="width: 100%; height: 100%;" cellspacing=0 cellpadding=0 border=0>
-              <tbody>
-                <tr style="vertical-align: top; height: 100px;">
-                  <td>
-                    <table style="width: 100%;">
-                      <tbody>
-                        <tr>
-                          <td>
-                            <span style="font-weight:bold;">Selector Expression</span>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td>
-                            <textarea id="expression" style="resize: none; width: 100%; height: 100px; padding: 5px 7px;"></textarea>
-                          </td>
-                        </tr>
-                      </tbody>
-                    </table>
-                  </td>
-                </tr>
-
-                <tr style="vertical-align: top; height: 50px;">
-                  <td>
-                    <table>
-                      <tbody>
-                        <tr>
-                          <td>
-                            <button id=parse>Parse</button>
-                          </td>
-                          <td>
-                            <button id=check>Check</button>
-                          </td>
-                          <td>
-                            <button id=debug>Debug</button>
-                          </td>
-                        </tr>
-                      </tbody>
-                    </table>
-                  </td>
-                </tr>
-
-                <tr style="vertical-align: top;">
-                  <td>
-                    <table style="width: 100%; height: 100%;" border="0" cellpadding="0" cellspacing="0">
-                      <tbody>
-                        <tr style="vertical-align: top; height: 1em;">
-                          <td>
-                            <span style="font-weight:bold;">Result</span>
-                          </td>
-                        </tr>
-                        <tr style="vertical-align: top; height: 1em;">
-                          <td id="validity">
-                          </td>
-                        </tr>
-                        <tr style="vertical-align: top;">
-                          <td id="result">
-                            <textarea style="resize: none; width: 100%; height: 100%; border: black solid 1px; padding: 5px 7px;"></textarea>
-                          </td>
-                        </tr>
-                      </tbody>
-                    </table>
-                  </td>
-                </tr>
-              </tbody>
-            </table>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-  ''';
-
-  document.body.style.setProperty("background-color", "lightgray");
-  document.body.elements.add(element);
-
-  ButtonElement parseButton = window.document.query('#parse');
-  parseButton.on.click.add((MouseEvent e) {
-    runCss(true, true);
-  });
-
-  ButtonElement checkButton = window.document.query('#check');
-  checkButton.on.click.add((MouseEvent e) {
-    runCss();
-  });
-
-  ButtonElement debugButton = window.document.query('#debug');
-  debugButton.on.click.add((MouseEvent e) {
-    runCss(true);
-  });
-
-  initCssWorld(false);
-}
diff --git a/utils/css/validate.dart b/utils/css/validate.dart
deleted file mode 100644
index 9babe3d..0000000
--- a/utils/css/validate.dart
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Validate {
-  static int _classNameCheck(var selector, int matches) {
-    if (selector.isCombinatorDescendant() ||
-        (selector.isCombinatorNone() && matches == 0)) {
-      if (matches < 0) {
-        String tooMany = selector.simpleSelector.toString();
-        throw new CssSelectorException(
-            'Can not mix Id selector with class selector(s). Id ' +
-            'selector must be singleton too many starting at $tooMany');
-      }
-  
-      return matches + 1;
-    } else {
-      String error = selector.toString();
-      throw new CssSelectorException(
-          'Selectors can not have combinators (>, +, or ~) before $error');
-    }
-  }
-
-  static int _elementIdCheck(var selector, int matches) {
-    if (selector.isCombinatorNone() && matches == 0) {
-      // Perfect just one element id returns matches of -1.
-      return -1;
-    } else if (selector.isCombinatorDescendant()) {
-        String tooMany = selector.simpleSelector.toString();
-        throw new CssSelectorException(
-            'Use of Id selector must be singleton starting at $tooMany');
-    } else {
-      String error = selector.simpleSelector.toString();
-      throw new CssSelectorException(
-          'Selectors can not have combinators (>, +, or ~) before $error');
-    }
-  }
-
-  // Validate the @{css expression} only .class and #elementId are valid inside
-  // of @{...}.
-  static template(List<ASTNode> selectors, CssWorld cssWorld) {
-    var errorSelector;                  // signal which selector didn't match.
-    bool found = false;                 // signal if a selector is matched.
-    int matches = 0;                    // < 0 IdSelectors, > 0 ClassSelector
-
-    // At most one selector group (any number of simple selector sequences).
-    assert(selectors.length <= 1);
-
-    for (final sels in selectors) {
-      for (final selector in sels.simpleSelectorSequences) {
-        found = false;
-        var simpleSelector = selector.simpleSelector;
-        if (simpleSelector is ClassSelector) {
-          // Any class name starting with an underscore is a private class name
-          // that doesn't have to match the world of known classes.
-          if (!simpleSelector.name.startsWith('_')) {
-            // TODO(terry): For now iterate through all classes look for faster
-            //              mechanism hash map, etc.
-            for (final className in cssWorld.classes) {
-              if (selector.simpleSelector.name == className) {
-                matches = _classNameCheck(selector, matches);
-                found = true;              // .class found.
-                break;
-              }
-              for (final className2 in cssWorld.classes) {
-                print(className2);
-              }
-            }
-
-          } else {
-            // Don't check any class name that is prefixed with an underscore.
-            // However, signal as found and bump up matches; it's a valid class
-            // name.
-            matches = _classNameCheck(selector, matches);
-            found = true;                 // ._class are always okay.
-          }
-        } else if (simpleSelector is IdSelector) {
-          // Any element id starting with an underscore is a private element id
-          // that doesn't have to match the world of known elemtn ids.
-          if (!simpleSelector.name.startsWith('_')) {
-            for (final id in cssWorld.ids) {
-              if (simpleSelector.name == id) {
-                matches = _elementIdCheck(selector, matches);
-                found = true;             // #id found.
-                break;
-              }
-            }
-          } else {
-            // Don't check any element ID that is prefixed with an underscore.
-            // Signal as found and bump up matches; it's a valid element ID.
-            matches = _elementIdCheck(selector, matches);
-            found = true;                 // #_id are always okay
-          }
-        } else {
-          String badSelector = simpleSelector.toString();
-          throw new CssSelectorException(
-              'Invalid template selector $badSelector');
-        }
-
-        if (!found) {
-          String unknownName = simpleSelector.toString();
-          throw new CssSelectorException('Unknown selector name $unknownName');
-        }
-      }
-    }
-
-    // Every selector must match.
-    var selector = selectors[0];
-    assert((matches >= 0 ? matches : -matches) ==
-        selector.simpleSelectorSequences.length);
-  }
-}
-
diff --git a/utils/css/world.dart b/utils/css/world.dart
deleted file mode 100644
index 837eefd..0000000
--- a/utils/css/world.dart
+++ /dev/null
@@ -1,170 +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.
-
-/** The one true [World]. */
-World world;
-
-typedef void MessageHandler(String prefix, String message, SourceSpan span);
-typedef void PrintHandler(String message);
-
-/**
- * Should be called exactly once to setup singleton world.
- * Can use world.reset() to reinitialize.
- */
-void initializeWorld(var files) {
-  assert(world == null);
-  world = new World(files);
-  world.init();
-}
-
-/** Can be thrown on any compiler error and includes source location. */
-class CompilerException implements Exception {
-  final String _message;
-  final SourceSpan _location;
-
-  CompilerException(this._message, this._location);
-
-  String toString() {
-    if (_location != null) {
-      return 'CompilerException: ${_location.toMessageString(_message)}';
-    } else {
-      return 'CompilerException: $_message';
-    }
-  }
-}
-
-/** Represents a Dart template "world". */
-class World {
-  String template;
-
-  var files;
-
-  int errors = 0, warnings = 0;
-  bool seenFatal = false;
-  MessageHandler messageHandler;
-  PrintHandler printHandler;
-
-  World(this.files);
-
-  void reset() {
-    errors = warnings = 0;
-    seenFatal = false;
-    init();
-  }
-
-  init() {
-  }
-
-
-  // ********************** Message support ***********************
-
-  void _message(String color, String prefix, String message,
-      SourceSpan span, SourceSpan span1, SourceSpan span2, bool throwing) {
-    if (messageHandler != null) {
-      // TODO(jimhug): Multiple spans cleaner...
-      messageHandler(prefix, message, span);
-      if (span1 != null) {
-        messageHandler(prefix, message, span1);
-      }
-      if (span2 != null) {
-        messageHandler(prefix, message, span2);
-      }
-    } else {
-      final messageWithPrefix = options.useColors
-          ? (color + prefix + _NO_COLOR + message) : (prefix + message);
-
-      var text = messageWithPrefix;
-      if (span != null) {
-        text = span.toMessageString(messageWithPrefix);
-      }
-
-      String span1Text = span1 != null ?
-          span1.toMessageString(messageWithPrefix) : "";
-      String span2Text = span2 != null ?
-          span2.toMessageString(messageWithPrefix) : "";
-
-      if (printHandler == null) {
-        print(text);
-        if (span1 != null) {
-          print(span1Text);
-        }
-        if (span2 != null) {
-          print(span2Text);
-        }
-      } else {
-        printHandler("${text}\r${span1Text}\r${span2Text}");
-      }
-    }
-
-    if (throwing) {
-      throw new CompilerException(prefix + message, span);
-    }
-  }
-
-  /** [message] is considered a static compile-time error by the Dart lang. */
-  void error(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    errors++;
-    _message(_RED_COLOR, 'error: ', message,
-        span, span1, span2, options.throwOnErrors);
-  }
-
-  /** [message] is considered a type warning by the Dart lang. */
-  void warning(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    if (options.warningsAsErrors) {
-      error(message, span, span1, span2);
-      return;
-    }
-    warnings++;
-    if (options.showWarnings) {
-      _message(_MAGENTA_COLOR, 'warning: ', message,
-          span, span1, span2, options.throwOnWarnings);
-    }
-  }
-
-  /** [message] at [location] is so bad we can't generate runnable code. */
-  void fatal(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    errors++;
-    seenFatal = true;
-    _message(_RED_COLOR, 'fatal: ', message,
-        span, span1, span2, options.throwOnFatal || options.throwOnErrors);
-  }
-
-  /** [message] at [location] is about a bug in the compiler. */
-  void internalError(String message,
-      {SourceSpan span, SourceSpan span1, SourceSpan span2}) {
-    _message(_NO_COLOR,
-        'We are sorry, but...', message, span, span1, span2, true);
-  }
-
-  /**
-   * [message] at [location] will tell the user about what the compiler
-   * is doing.
-   */
-  void info(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    if (options.showInfo) {
-      _message(_GREEN_COLOR, 'info: ', message, span, span1, span2, false);
-    }
-  }
-
-  bool get hasErrors => errors > 0;
-
-  withTiming(String name, f()) {
-    final sw = new Stopwatch();
-    sw.start();
-    var result = f();
-    sw.stop();
-    info('$name in ${sw.elapsedMilliseconds}msec');
-    return result;
-  }
-}
-
-// Color constants used for generating messages.
-String _GREEN_COLOR = '\u001b[32m';
-String _RED_COLOR = '\u001b[31m';
-String _MAGENTA_COLOR = '\u001b[35m';
-String _NO_COLOR = '\u001b[0m';
diff --git a/utils/lib/file_system.dart b/utils/lib/file_system.dart
deleted file mode 100644
index 306be7a..0000000
--- a/utils/lib/file_system.dart
+++ /dev/null
@@ -1,75 +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.
-
-// TODO(terry): Investigate common library for file I/O shared between frog and tools.
-
-/** Abstraction for file systems and utility functions to manipulate paths. */
-library file_system;
-
-/**
- * Abstraction around file system access to work in a variety of different
- * environments.
- */
-abstract class FileSystem {
-  String readAll(String filename);
-
-  void writeString(String outfile, String text);
-
-  bool fileExists(String filename);
-
-  void createDirectory(String path, [bool recursive]);
-  void removeDirectory(String path, [bool recursive]);
-}
-
-/**
- * Replaces all back slashes (\) with forward slashes (/) in [path] and
- * return the result.
- */
-String canonicalizePath(String path) {
-  return path.replaceAll('\\', '/');
-}
-
-/** Join [path1] to [path2]. */
-String joinPaths(String path1, String path2) {
-  path1 = canonicalizePath(path1);
-  path2 = canonicalizePath(path2);
-
-  var pieces = path1.split('/');
-  for (var piece in path2.split('/')) {
-    if (piece == '..' && pieces.length > 0 && pieces.last != '.'
-      && pieces.last != '..') {
-      pieces.removeLast();
-    } else if (piece != '') {
-      if (pieces.length > 0 && pieces.last == '.') {
-        pieces.removeLast();
-      }
-      pieces.add(piece);
-    }
-  }
-  return pieces.join('/');
-}
-
-/** Returns the directory name for the [path]. */
-String dirname(String path) {
-  path = canonicalizePath(path);
-
-  int lastSlash = path.lastIndexOf('/', path.length);
-  if (lastSlash == -1) {
-    return '.';
-  } else {
-    return path.substring(0, lastSlash);
-  }
-}
-
-/** Returns the file name without directory for the [path]. */
-String basename(String path) {
-  path = canonicalizePath(path);
-
-  int lastSlash = path.lastIndexOf('/', path.length);
-  if (lastSlash == -1) {
-    return path;
-  } else {
-    return path.substring(lastSlash + 1);
-  }
-}
diff --git a/utils/lib/file_system_memory.dart b/utils/lib/file_system_memory.dart
deleted file mode 100644
index c1a15b9..0000000
--- a/utils/lib/file_system_memory.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(terry): Investigate common library for file I/O shared between frog and tools.
-
-library file_system_memory;
-
-import 'file_system.dart';
-
-/**
- * [FileSystem] implementation a memory buffer.
- */
-class MemoryFileSystem implements FileSystem {
-  StringBuffer buffer;
-
-  MemoryFileSystem() : this.buffer = new StringBuffer();
-
-  void writeString(String outfile, String text) {
-    buffer.write(text);
-  }
-
-  String readAll(String filename) {
-    return buffer.toString();
-  }
-
-  bool fileExists(String filename) {
-    return true;
-  }
-
-  void createDirectory(String path, [bool recursive]) {
-    // TODO(terry): To be implement.
-    throw 'createDirectory() is not implemented by MemoryFileSystem yet.';
-  }
-
-  void removeDirectory(String path, [bool recursive]) {
-    // TODO(terry): To be implement.
-    throw 'removeDirectory() is not implemented by MemoryFileSystem yet.';
-  }
-}
diff --git a/utils/lib/file_system_vm.dart b/utils/lib/file_system_vm.dart
deleted file mode 100644
index 99b936f..0000000
--- a/utils/lib/file_system_vm.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(terry): Investigate common library for file I/O shared between frog and tools.
-
-library file_system_vm;
-import 'dart:convert';
-import 'dart:io';
-import 'file_system.dart';
-
-/** File system implementation using the vm api's. */
-class VMFileSystem implements FileSystem {
-  void writeString(String path, String text) {
-    var file = new File(path).openSync(mode: FileMode.WRITE);
-    file.writeStringSync(text);
-    file.closeSync();
-  }
-
-  String readAll(String filename) {
-    var file = (new File(filename)).openSync();
-    var length = file.lengthSync();
-    var buffer = new List<int>(length);
-    var bytes = file.readIntoSync(buffer, 0, length);
-    file.closeSync();
-    return UTF8.decode(bytes);
-  }
-
-  bool fileExists(String filename) {
-    return new File(filename).existsSync();
-  }
-
-  void createDirectory(String path, [bool recursive = false]) {
-    // TODO(rnystrom): Implement.
-    throw 'createDirectory() is not implemented by VMFileSystem yet.';
-  }
-
-  void removeDirectory(String path, [bool recursive = false]) {
-    // TODO(rnystrom): Implement.
-    throw 'removeDirectory() is not implemented by VMFileSystem yet.';
-  }
-}
diff --git a/utils/template/codegen.dart b/utils/template/codegen.dart
deleted file mode 100644
index d2b07ab..0000000
--- a/utils/template/codegen.dart
+++ /dev/null
@@ -1,1013 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class CGBlock {
-  int _blockType;             // Code type of this block
-  int _indent;                // Number of spaces to prefix for each statement
-  bool _inEach;               // This block or any currently active blocks is a
-                              // #each.  If so then any element marked with a
-                              // var attribute is repeated therefore the var
-                              // is a List type instead of an Element type.
-  String _localName;          // optional local name for #each or #with
-  List<CGStatement> _stmts;
-  int localIndex;             // Local variable index (e.g., e0, e1, etc.)
-
-  // Block Types:
-  static const int CONSTRUCTOR = 0;
-  static const int EACH = 1;
-  static const int WITH = 2;
-
-  CGBlock([this._indent = 4,
-           this._blockType = CGBlock.CONSTRUCTOR,
-           this._inEach = false,
-           this._localName = null]) :
-      _stmts = new List<CGStatement>(), localIndex = 0 {
-    assert(_blockType >= CGBlock.CONSTRUCTOR && _blockType <= CGBlock.WITH);
-  }
-
-  bool get anyStatements => !_stmts.isEmpty;
-  bool get isConstructor => _blockType == CGBlock.CONSTRUCTOR;
-  bool get isEach => _blockType == CGBlock.EACH;
-  bool get isWith => _blockType == CGBlock.WITH;
-
-  bool get hasLocalName => _localName != null;
-  String get localName => _localName;
-
-  CGStatement push(var elem, var parentName, [bool exact = false]) {
-    var varName;
-    if (elem is TemplateElement && elem.hasVar) {
-      varName = elem.varName;
-    } else {
-      varName = localIndex++;
-    }
-
-    CGStatement stmt = new CGStatement(elem, _indent, parentName, varName,
-        exact, _inEach);
-    _stmts.add(stmt);
-
-    return stmt;
-  }
-
-  void pop() {
-    _stmts.removeLast();
-  }
-
-  void add(String value) {
-    if (_stmts.last != null) {
-      _stmts.last.add(value);
-    }
-  }
-
-  CGStatement get last => _stmts.length > 0 ? _stmts.last : null;
-
-  /**
-   * Returns mixed list of elements marked with the var attribute.  If the
-   * element is inside of a #each the name exposed is:
-   *
-   *      List varName;
-   *
-   * otherwise it's:
-   *
-   *      var varName;
-   *
-   * TODO(terry): For scalars var varName should be Element tag type e.g.,
-   *
-   *                   DivElement varName;
-   */
-  String get globalDeclarations {
-    StringBuffer buff = new StringBuffer();
-    for (final CGStatement stmt in _stmts) {
-      buff.write(stmt.globalDeclaration());
-    }
-
-    return buff.toString();
-  }
-
-  /**
-   * List of statement constructors for each var inside a #each.
-   *
-   *    ${#each products}
-   *      <div var=myVar>...</div>
-   *    ${/each}
-   *
-   * returns:
-   *
-   *    myVar = [];
-   */
-  String get globalInitializers {
-    StringBuffer buff = new StringBuffer();
-    for (final CGStatement stmt in _stmts) {
-      buff.write(stmt.globalInitializers());
-    }
-
-    return buff.toString();
-  }
-
-  String get codeBody {
-    StringBuffer buff = new StringBuffer();
-
-    for (final CGStatement stmt in _stmts) {
-      buff.write(stmt.emitDartStatement());
-    }
-
-    return buff.toString();
-  }
-}
-
-class CGStatement {
-  bool _exact;                  // If True not HTML construct instead exact stmt
-  bool _repeating;              // Stmt in a #each this block or nested block.
-  StringBuffer _buff;
-  var _elem;
-  int _indent;
-  var parentName;
-  String varName;
-  bool _globalVariable;
-  bool _closed;
-
-  CGStatement(this._elem, this._indent, this.parentName, var varNameOrIndex,
-      [this._exact = false, this._repeating = false]) :
-        _buff = new StringBuffer(), _closed = false {
-
-    if (varNameOrIndex is String) {
-      // We have the global variable name
-      varName = varNameOrIndex;
-      _globalVariable = true;
-    } else {
-      // local index generate local variable name.
-      varName = "e${varNameOrIndex}";
-      _globalVariable = false;
-    }
-  }
-
-  bool get hasGlobalVariable => _globalVariable;
-  String get variableName => varName;
-
-  String globalDeclaration() {
-    if (hasGlobalVariable) {
-      String spaces = Codegen.spaces(_indent);
-      return (_repeating) ?
-        "  List ${varName};    // Repeated elements.\n" : "  var ${varName};\n";
-    }
-
-    return "";
-  }
-
-  String globalInitializers() {
-    if (hasGlobalVariable && _repeating) {
-      return "    ${varName} = [];\n";
-    }
-
-    return "";
-  }
-
-  void add(String value) {
-    _buff.write(value);
-  }
-
-  bool get isClosed => _closed;
-
-  void close() {
-    if (_elem is TemplateElement && _elem.scoped) {
-      add("</${_elem.tagName}>");
-    }
-    _closed = true;
-  }
-
-  String emitDartStatement() {
-    StringBuffer statement = new StringBuffer();
-
-    String spaces = Codegen.spaces(_indent);
-
-    if (_exact) {
-      statement.add("${spaces}${_buff.toString()};\n");
-    } else {
-      String localVar = "";
-      String tmpRepeat;
-      if (hasGlobalVariable) {
-        if (_repeating) {
-          tmpRepeat = "tmp_${varName}";
-          localVar = "var ";
-        }
-      } else {
-        localVar = "var ";
-      }
-
-      /* Emiting the following code fragment where varName is the attribute
-         value for var=
-
-            varName = new Element.html('HTML GOES HERE');
-            parent.elements.add(varName);
-
-         for repeating elements in a #each:
-
-            var tmp_nnn = new Element.html('HTML GOES HERE');
-            varName.add(tmp_nnn);
-            parent.elements.add(tmp_nnn);
-
-         for elements w/o var attribute set:
-
-            var eNNN = new Element.html('HTML GOES HERE');
-            parent.elements.add(eNNN);
-       */
-      if (_elem is TemplateCall) {
-        // Call template NameEntry2
-        String cls = _elem.toCall;
-        String params = _elem.params;
-        statement.add("\n${spaces}// Call template ${cls}.\n");
-        statement.add(
-            "${spaces}${localVar}${varName} = new ${cls}${params};\n");
-        statement.add(
-            "${spaces}${parentName}.elements.add(${varName}.root);\n");
-      } else {
-        bool isTextNode = _elem is TemplateText;
-        String createType = isTextNode ? "Text" : "Element.html";
-        if (tmpRepeat == null) {
-          statement.add("${spaces}${localVar}${varName} = new ${createType}('");
-        } else {
-          statement.add(
-              "${spaces}${localVar}${tmpRepeat} = new ${createType}('");
-        }
-        statement.add(isTextNode ? _buff.toString().trim() : _buff.toString());
-
-        if (tmpRepeat == null) {
-          statement.add(
-            "');\n${spaces}${parentName}.elements.add(${varName});\n");
-        } else {
-          statement.add(
-            "');\n${spaces}${parentName}.elements.add(${tmpRepeat});\n");
-          statement.add("${spaces}${varName}.add(${tmpRepeat});\n");
-        }
-      }
-    }
-
-    return statement.toString();
-  }
-}
-
-class Codegen {
-  static const String SPACES = "                                              ";
-  static String spaces(int numSpaces) {
-    return SPACES.substring(0, numSpaces);
-  }
-
-  // TODO(terry): Before generating Dart class need a validate phase that
-  //              checks mangles all class names to be prefix with the
-  //              template name to avoid any class name collisions.  Also,
-  //              investigate possible runtime check mode to insure that only
-  //              valid CSS class names are used (in case someone uses strings
-  //              and not the generated getters to the CSS class selector.  This
-  //              mode would be slower would require that every class name set
-  //              (maybe jQuery too) is for a particular view (requires walking
-  //              the HTML tree looking for a parent template prefix that
-  //              matches the CSS prefix. (more thinking needed).
-  static String generate(List<Template> templates, String filename) {
-    List<String> fileParts = filename.split('.');
-    assert(fileParts.length == 2);
-    filename = fileParts[0];
-
-    StringBuffer buff = new StringBuffer();
-    int injectId = 0;         // Inject function id
-
-    buff.write("// Generated Dart class from HTML template.\n");
-    buff.write("// DO NOT EDIT.\n\n");
-
-    String addStylesheetFuncName = "add_${filename}_templatesStyles";
-
-    for (final template in templates) {
-      // Emit the template class.
-      TemplateSignature sig = template.signature;
-      buff.write(_emitClass(sig.name, sig.params, template.content,
-        addStylesheetFuncName));
-    }
-
-    // TODO(terry): Stylesheet aggregator should not be global needs to be
-    //              bound to this template file not global to the app.
-
-    // Emit the stylesheet aggregator.
-    buff.write("\n\n// Inject all templates stylesheet once into the head.\n");
-    buff.write("bool ${filename}_stylesheet_added = false;\n");
-    buff.write("void ${addStylesheetFuncName}() {\n");
-    buff.write("  if (!${filename}_stylesheet_added) {\n");
-    buff.write("    StringBuffer styles = new StringBuffer();\n\n");
-
-    buff.write("    // All templates stylesheet.\n");
-
-    for (final template in templates) {
-      TemplateSignature sig = template.signature;
-      buff.write("    styles.add(${sig.name}.stylesheet);\n");
-    }
-
-    buff.write("\n    ${filename}_stylesheet_added = true;\n");
-
-    buff.write("    document.head.elements.add(new Element.html('<style>"
-             "\${styles.toString()}</style>'));\n");
-    buff.write("  }\n");
-    buff.write("}\n");
-
-    return buff.toString();
-  }
-
-  static String _emitCSSSelectors(css.Stylesheet stylesheet) {
-    if (stylesheet == null) {
-      return "";
-    }
-
-    List<String> classes = [];
-
-    for (final production in stylesheet.topLevels) {
-      if (production is css.IncludeDirective) {
-        for (final topLevel in production.styleSheet.topLevels) {
-          if (topLevel is css.RuleSet) {
-            classes = css.Generate.computeClassSelectors(topLevel, classes);
-          }
-        }
-      } else if (production is css.RuleSet) {
-        classes = css.Generate.computeClassSelectors(production, classes);
-      }
-    }
-
-    List<String> dartNames = [];
-
-    for (final String knownClass in classes) {
-      StringBuffer dartName = new StringBuffer();
-      List<String> splits = knownClass.split('-');
-      if (splits.length > 0) {
-        dartName.add(splits[0]);
-        for (int idx = 1; idx < splits.length; idx++) {
-          String part = splits[idx];
-          // Character between 'a'..'z' mapped to 'A'..'Z'
-          dartName.add("${part[0].toUpperCase()}${part.substring(1)}");
-        }
-        dartNames.add(dartName.toString());
-      }
-    }
-
-    StringBuffer buff = new StringBuffer();
-    if (classes.length > 0) {
-      assert(classes.length == dartNames.length);
-      buff.write("\n  // CSS class selectors for this template.\n");
-      for (int i = 0; i < classes.length; i++) {
-        buff.write(
-          "  static String get ${dartNames[i]} => \"${classes[i]}\";\n");
-      }
-    }
-
-    return buff.toString();
-  }
-
-  static String _emitClass(String className,
-                           List<Map<Identifier, Identifier>> params,
-                           TemplateContent content,
-                           String addStylesheetFuncName) {
-    StringBuffer buff = new StringBuffer();
-
-    // Emit the template class.
-    buff.write("class ${className} {\n");
-
-    buff.write("  Map<String, Object> _scopes;\n");
-    buff.write("  Element _fragment;\n\n");
-
-    bool anyParams = false;
-    for (final param in params) {
-      buff.write("  ${param['type']} ${param['name']};\n");
-      anyParams = true;
-    }
-    if (anyParams) buff.write("\n");
-
-    ElemCG ecg = new ElemCG();
-
-    if (!ecg.pushBlock()) {
-      world.error("Error at ${content}");
-    }
-
-    var root = content.html.children.length > 0 ? content.html.children[0] :
-        content.html;
-    bool firstTime = true;
-    for (var child in root.children) {
-      if (child is TemplateText) {
-        if (!firstTime) {
-          ecg.closeStatement();
-        }
-
-        String textNodeValue = child.value.trim();
-        if (textNodeValue.length > 0) {
-          CGStatement stmt = ecg.pushStatement(child, "_fragment");
-        }
-      }
-      ecg.emitConstructHtml(child, "", "_fragment");
-      firstTime = false;
-    }
-
-    // Create all element names marked with var.
-    String decls = ecg.globalDeclarations;
-    if (decls.length > 0) {
-      buff.write("\n  // Elements bound to a variable:\n");
-      buff.write("${decls}\n");
-    }
-
-    // Create the constructor.
-    buff.write("  ${className}(");
-    bool firstParam = true;
-    for (final param in params) {
-      if (!firstParam) {
-        buff.write(", ");
-      }
-      buff.write("this.${param['name']}");
-      firstParam = false;
-    }
-    buff.write(") : _scopes = new Map<String, Object>() {\n");
-
-    String initializers = ecg.globalInitializers;
-    if (initializers.length > 0) {
-      buff.write("    //Global initializers.\n");
-      buff.write("${initializers}\n");
-    }
-
-    buff.write("    // Insure stylesheet for template exist in the document.\n");
-    buff.write("    ${addStylesheetFuncName}();\n\n");
-
-    buff.write("    _fragment = new DocumentFragment();\n");
-
-    buff.write(ecg.codeBody);     // HTML for constructor to build.
-
-    buff.write("  }\n\n");        // End constructor
-
-    buff.write(emitGetters(content.getters));
-
-    buff.write("  Element get root => _fragment;\n");
-
-    // Emit all CSS class selectors:
-    buff.write(_emitCSSSelectors(content.css));
-
-    // Emit the injection functions.
-    buff.write("\n  // Injection functions:");
-    for (final expr in ecg.expressions) {
-      buff.write("${expr}");
-    }
-
-    buff.write("\n  // Each functions:\n");
-    for (var eachFunc in ecg.eachs) {
-      buff.write("${eachFunc}\n");
-    }
-
-    buff.write("\n  // With functions:\n");
-    for (var withFunc in ecg.withs) {
-      buff.write("${withFunc}\n");
-    }
-
-    buff.write("\n  // CSS for this template.\n");
-    buff.write("  static const String stylesheet = ");
-
-    if (content.css != null) {
-      buff.write("\'\'\'\n    ${content.css.toString()}\n");
-      buff.write("  \'\'\';\n\n");
-
-      // TODO(terry): Emit all known selectors for this template.
-      buff.write("  // Stylesheet class selectors:\n");
-    } else {
-      buff.write("\"\";\n");
-    }
-
-    buff.write("  String safeHTML(String html) {\n");
-    buff.write("    // TODO(terry): Escaping for XSS vulnerabilities TBD.\n");
-    buff.write("    return html;\n");
-    buff.write("  }\n");
-
-    buff.write("}\n");              // End class
-
-    return buff.toString();
-  }
-
-  // TODO(terry): Need to generate function to inject any TemplateExpressions
-  //              to call SafeHTML wrapper.
-  static String emitGetters(List<TemplateGetter> getters) {
-    StringBuffer buff = new StringBuffer();
-    for (final TemplateGetter getter in getters) {
-      buff.write('  String ${getter.getterSignatureAsString()} {\n');
-      buff.write('    return \'\'\'');
-      var docFrag = getter.docFrag.children[0];
-      for (final child in docFrag.children) {
-        buff.write(child.toString().trim());
-      }
-      buff.write('\'\'\';\n');
-      buff.write('  }\n\n');
-    }
-
-    return buff.toString();
-  }
-}
-
-class ElemCG {
-  // List of identifiers and quoted strings (single and double quoted).
-  var identRe = new RegExp(
-    "\s*('\"\\'\\\"[^'\"\\'\\\"]+'\"\\'\\\"|[_A-Za-z][_A-Za-z0-9]*)");
-
-  List<CGBlock> _cgBlocks;
-  StringBuffer _globalDecls;        // Global var declarations for all blocks.
-  StringBuffer _globalInits;        // Global List var initializtion for all
-                                    // blocks in a #each.
-  String funcCall;                  // Func call after element creation?
-  List<String> expressions;         // List of injection function declarations.
-  List<String> eachs;               // List of each function declarations.
-  List<String> withs;               // List of with function declarations.
-
-  ElemCG() :
-    expressions = [],
-    eachs = [],
-    withs = [],
-    _cgBlocks = [],
-    _globalDecls = new StringBuffer(),
-    _globalInits = new StringBuffer();
-
-  bool get isLastBlockConstructor {
-    CGBlock block = _cgBlocks.last;
-    return block.isConstructor;
-  }
-
-  List<String> activeBlocksLocalNames() {
-    List<String> result = [];
-
-    for (final CGBlock block in _cgBlocks) {
-      if (block.isEach || block.isWith) {
-        if (block.hasLocalName) {
-          result.add(block.localName);
-        }
-      }
-    }
-
-    return result;
-  }
-
-  /**
-   * Active block with this localName.
-   */
-  bool matchBlocksLocalName(String name) {
-    for (final CGBlock block in _cgBlocks) {
-      if (block.isEach || block.isWith) {
-        if (block.hasLocalName && block.localName == name) {
-          return true;
-        }
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * Any active blocks?
-   */
-  bool isNestedBlock() {
-    for (final CGBlock block in _cgBlocks) {
-      if (block.isEach || block.isWith) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * Any active blocks with localName?
-   */
-  bool isNestedNamedBlock() {
-    for (final CGBlock block in _cgBlocks) {
-      if ((block.isEach || block.isWith) && block.hasLocalName) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  // Any current active #each blocks.
-  bool anyEachBlocks(int blockToCreateType) {
-    bool result = blockToCreateType == CGBlock.EACH;
-
-    for (final CGBlock block in _cgBlocks) {
-      if (block.isEach) {
-        result = result || true;
-      }
-    }
-
-    return result;
-  }
-
-  bool pushBlock([int indent = 4, int blockType = CGBlock.CONSTRUCTOR,
-                  String itemName = null]) {
-    if (itemName != null && matchBlocksLocalName(itemName)) {
-      world.error("Active block already exist with local name: ${itemName}.");
-      return false;
-    } else if (itemName == null && this.isNestedBlock()) {
-      world.error('''
-Nested #each or #with must have a localName;
- \n  #each list [localName]\n  #with object [localName]''');
-      return false;
-    }
-    _cgBlocks.add(
-        new CGBlock(indent, blockType, anyEachBlocks(blockType), itemName));
-
-    return true;
-  }
-
-  void popBlock() {
-    _globalDecls.add(lastBlock.globalDeclarations);
-    _globalInits.add(lastBlock.globalInitializers);
-    _cgBlocks.removeLast();
-  }
-
-  CGStatement pushStatement(var elem, var parentName) {
-    return lastBlock.push(elem, parentName, false);
-  }
-
-  CGStatement pushExactStatement(var elem, var parentName) {
-    return lastBlock.push(elem, parentName, true);
-  }
-
-  bool get isClosedStatement {
-    return (lastBlock != null && lastBlock.last != null) ?
-        lastBlock.last.isClosed : false;
-  }
-
-  void closeStatement() {
-    if (lastBlock != null && lastBlock.last != null &&
-        !lastBlock.last.isClosed) {
-      lastBlock.last.close();
-    }
-  }
-
-  String get lastVariableName {
-    if (lastBlock != null && lastBlock.last != null) {
-      return lastBlock.last.variableName;
-    }
-  }
-
-  String get lastParentName {
-    if (lastBlock != null && lastBlock.last != null) {
-      return lastBlock.last.parentName;
-    }
-  }
-
-  CGBlock get lastBlock => _cgBlocks.length > 0 ? _cgBlocks.last : null;
-
-  void add(String str) {
-    _cgBlocks.last.add(str);
-  }
-
-  String get globalDeclarations {
-    assert(_cgBlocks.length == 1);    // Only constructor body should be left.
-    _globalDecls.add(lastBlock.globalDeclarations);
-    return _globalDecls.toString();
-  }
-
-  String get globalInitializers {
-    assert(_cgBlocks.length == 1);    // Only constructor body should be left.
-    _globalInits.add(lastBlock.globalInitializers);
-    return _globalInits.toString();
-  }
-
-  String get codeBody {
-    closeStatement();
-    return _cgBlocks.last.codeBody;
-  }
-
-  /* scopeName for expression
-   * parentVarOrIndex if # it's a local variable if string it's an exposed
-   * name (specified by the var attribute) for this element.
-   *
-   */
-  emitElement(var elem,
-              [String scopeName = "",
-               var parentVarOrIdx = 0,
-               bool immediateNestedEach = false]) {
-    if (elem is TemplateElement) {
-      if (!elem.isFragment) {
-        add("<${elem.tagName}${elem.attributesToString()}>");
-      }
-      String prevParent = lastVariableName;
-      for (var childElem in elem.children) {
-        if (childElem is TemplateElement) {
-          closeStatement();
-          if (childElem.hasVar) {
-            emitConstructHtml(childElem, scopeName, prevParent,
-              childElem.varName);
-          } else {
-            emitConstructHtml(childElem, scopeName, prevParent);
-          }
-          closeStatement();
-        } else {
-          emitElement(childElem, scopeName, parentVarOrIdx);
-        }
-      }
-
-      // Close this tag.
-      closeStatement();
-    } else if (elem is TemplateText) {
-      String outputValue = elem.value.trim();
-      if (outputValue.length > 0) {
-        bool emitTextNode = false;
-        if (isClosedStatement) {
-          String prevParent = lastParentName;
-          CGStatement stmt = pushStatement(elem, prevParent);
-          emitTextNode = true;
-        }
-
-        // TODO(terry): Need to interpolate following:
-        //      {sp}  → space
-        //      {nil} → empty string
-        //      {\r}  → carriage return
-        //      {\n}  → new line (line feed)
-        //      {\t}  → tab
-        //      {lb}  → left brace
-        //      {rb}  → right brace
-
-        add("${outputValue}");            // remove leading/trailing whitespace.
-
-        if (emitTextNode) {
-          closeStatement();
-        }
-      }
-    } else if (elem is TemplateExpression) {
-      emitExpressions(elem, scopeName);
-    } else if (elem is TemplateEachCommand) {
-      // Signal to caller new block coming in, returns "each_" prefix
-      emitEach(elem, "List", elem.listName.name, "parent", immediateNestedEach,
-          elem.hasLoopItem ? elem.loopItem.name : null);
-    } else if (elem is TemplateWithCommand) {
-      // Signal to caller new block coming in, returns "each_" prefix
-      emitWith(elem, "var", elem.objectName.name, "parent",
-          elem.hasBlockItem ? elem.blockItem.name : null);
-    } else if (elem is TemplateCall) {
-      emitCall(elem, parentVarOrIdx);
-    }
-  }
-
-  // TODO(terry): Hack prefixing all names with "${scopeName}." but don't touch
-  //              quoted strings.
-  String _resolveNames(String expr, String prefixPart) {
-    StringBuffer newExpr = new StringBuffer();
-    Iterable<Match> matches = identRe.allMatches(expr);
-
-    int lastIdx = 0;
-    for (Match m in matches) {
-      if (m.start > lastIdx) {
-        newExpr.add(expr.substring(lastIdx, m.start));
-      }
-
-      bool identifier = true;
-      if (m.start > 0)  {
-        int charCode = expr.codeUnitAt(m.start - 1);
-        // Starts with ' or " then it's not an identifier.
-        identifier = charCode != 34 /* " */ && charCode != 39 /* ' */;
-      }
-
-      String strMatch = expr.substring(m.start, m.end);
-      if (identifier) {
-        newExpr.add("${prefixPart}.${strMatch}");
-      } else {
-        // Quoted string don't touch.
-        newExpr.add("${strMatch}");
-      }
-      lastIdx = m.end;
-    }
-
-    if (expr.length > lastIdx) {
-      newExpr.add(expr.substring(lastIdx));
-    }
-
-    return newExpr.toString();
-  }
-
-  /**
-   * Construct the HTML each top-level node get's it's own variable.
-   *
-   * TODO(terry): Might want to optimize if the other top-level nodes have no
-   *              control structures (with, each, if, etc.). We could
-   *              synthesize a root node and create all the top-level nodes
-   *              under the root node with one innerHTML.
-   */
-  void emitConstructHtml(var elem,
-                         [String scopeName = "",
-                          String parentName = "parent",
-                          var varIndex = 0,
-                          bool immediateNestedEach = false]) {
-    if (elem is TemplateElement) {
-      CGStatement stmt = pushStatement(elem, parentName);
-      emitElement(elem, scopeName, stmt.hasGlobalVariable ?
-          stmt.variableName : varIndex);
-    } else {
-      emitElement(elem, scopeName, varIndex, immediateNestedEach);
-    }
-  }
-
-  /* Any references to products.sales needs to be remaped to item.sales
-   * for now it's a hack look for first dot and replace with item.
-   */
-  String eachIterNameToItem(String iterName) {
-    String newName = iterName;
-    var dotForIter = iterName.indexOf('.');
-    if (dotForIter >= 0) {
-      newName = "_item${iterName.substring(dotForIter)}";
-    }
-
-    return newName;
-  }
-
-  emitExpressions(TemplateExpression elem, String scopeName) {
-    StringBuffer func = new StringBuffer();
-
-    String newExpr = elem.expression;
-    bool anyNesting = isNestedNamedBlock();
-    if (scopeName.length > 0 && !anyNesting) {
-      // In a block #command need the scope passed in.
-      add("\$\{inject_${expressions.length}(_item)\}");
-      func.add("\n  String inject_${expressions.length}(var _item) {\n");
-      // Escape all single-quotes, this expression is embedded as a string
-      // parameter for the call to safeHTML.
-      newExpr = _resolveNames(newExpr.replaceAll("'", "\\'"), "_item");
-    } else {
-      // Not in a block #command item isn't passed in.
-      add("\$\{inject_${expressions.length}()\}");
-      func.add("\n  String inject_${expressions.length}() {\n");
-
-      if (anyNesting) {
-        func.add(defineScopes());
-      }
-    }
-
-    // Construct the active scope names for name resolution.
-
-    func.add("    return safeHTML('\$\{${newExpr}\}');\n");
-    func.add("  }\n");
-
-    expressions.add(func.toString());
-  }
-
-  emitCall(TemplateCall elem, String scopeName) {
-    pushStatement(elem, scopeName);
-  }
-
-  emitEach(TemplateEachCommand elem, String iterType, String iterName,
-      var parentVarOrIdx, bool nestedImmediateEach, [String itemName = null]) {
-    TemplateDocument docFrag = elem.documentFragment;
-
-    int eachIndex = eachs.length;
-    eachs.add("");
-
-    StringBuffer funcBuff = new StringBuffer();
-    // Prepare function call "each_N(iterName," parent param computed later.
-    String funcName = "each_${eachIndex}";
-
-    funcBuff.add("  ${funcName}(${iterType} items, Element parent) {\n");
-
-    String paramName = injectParamName(itemName);
-    if (paramName == null) {
-      world.error("Use a different local name; ${itemName} is reserved.");
-    }
-    funcBuff.add("    for (var ${paramName} in items) {\n");
-
-    if (!pushBlock(6, CGBlock.EACH, itemName)) {
-      world.error("Error at ${elem}");
-    }
-
-    addScope(6, funcBuff, itemName);
-
-    TemplateElement docFragChild = docFrag.children[0];
-    var children = docFragChild.isFragment ?
-        docFragChild.children : docFrag.children;
-    for (var child in children) {
-      // If any immediate children of the parent #each is an #each then
-      // so we need to pass the outer #each parent not the last statement's
-      // variableName when calling the nested #each.
-      bool eachChild = (child is TemplateEachCommand);
-      emitConstructHtml(child, iterName, parentVarOrIdx, 0, eachChild);
-    }
-
-    funcBuff.add(codeBody);
-
-    removeScope(6, funcBuff, itemName);
-
-    popBlock();
-
-    funcBuff.add("    }\n");
-    funcBuff.add("  }\n");
-
-    eachs[eachIndex] = funcBuff.toString();
-
-    // If nested each then we want to pass the parent otherwise we'll use the
-    // varName.
-    var varName = nestedImmediateEach ? "parent" : lastBlockVarName;
-
-    pushExactStatement(elem, parentVarOrIdx);
-
-    // Setup call to each func as "each_n(xxxxx, " the parent param is filled
-    // in later when we known the parent variable.
-    String eachParam =
-        (itemName == null) ? eachIterNameToItem(iterName) : iterName;
-    add("${funcName}(${eachParam}, ${varName})");
-}
-
-  emitWith(TemplateWithCommand elem, String withType, String withName,
-      var parentVarIndex, [String itemName = null]) {
-    TemplateDocument docFrag = elem.documentFragment;
-
-    int withIndex = withs.length;
-    withs.add("");
-
-    StringBuffer funcBuff = new StringBuffer();
-    // Prepare function call "each_N(iterName," parent param computed later.
-    String funcName = "with_${withIndex}";
-
-    String paramName = injectParamName(itemName);
-    if (paramName == null) {
-      world.error("Use a different local name; ${itemName} is reserved.");
-    }
-    funcBuff.add("  ${funcName}(${withType} ${paramName}, Element parent) {\n");
-
-    if (!pushBlock(4, CGBlock.WITH, itemName)) {
-      world.error("Error at ${elem}");
-    }
-
-    TemplateElement docFragChild = docFrag.children[0];
-    var children = docFragChild.isFragment ?
-        docFragChild.children : docFrag.children;
-    for (var child in children) {
-      emitConstructHtml(child, withName, "parent");
-    }
-
-    addScope(4, funcBuff, itemName);
-    funcBuff.add(codeBody);
-    removeScope(4, funcBuff, itemName);
-
-    popBlock();
-
-    funcBuff.add("  }\n");
-
-    withs[withIndex] = funcBuff.toString();
-
-    // Compute parent node variable before pushing with statement.
-    String parentVarName = lastBlockVarName;
-
-    pushExactStatement(elem, parentVarIndex);
-
-    // Setup call to each func as "each_n(xxxxx, " the parent param is filled
-    // in later when we known the parent variable.
-    add("${funcName}(${withName}, ${parentVarName})");
-  }
-
-  String get lastBlockVarName {
-    var varName;
-    if (lastBlock != null && lastBlock.anyStatements) {
-      varName = lastBlock.last.variableName;
-    } else {
-      varName = "_fragment";
-    }
-
-    return varName;
-  }
-
-  String injectParamName(String name) {
-    // Local name _item is reserved.
-    if (name != null && name == "_item") {
-      return null;    // Local name is not valid.
-    }
-
-    return (name == null) ? "_item" : name;
-  }
-
-  addScope(int indent, StringBuffer buff, String item) {
-    String spaces = Codegen.spaces(indent);
-
-    if (item == null) {
-      item = "_item";
-    }
-    buff.write("${spaces}_scopes[\"${item}\"] = ${item};\n");
-  }
-
-  removeScope(int indent, StringBuffer buff, String item) {
-    String spaces = Codegen.spaces(indent);
-
-    if (item == null) {
-      item = "_item";
-    }
-    buff.write("${spaces}_scopes.remove(\"${item}\");\n");
-  }
-
-  String defineScopes() {
-    StringBuffer buff = new StringBuffer();
-
-    // Construct the active scope names for name resolution.
-    List<String> names = activeBlocksLocalNames();
-    if (names.length > 0) {
-      buff.write("    // Local scoped block names.\n");
-      for (String name in names) {
-        buff.write("    var ${name} = _scopes[\"${name}\"];\n");
-      }
-      buff.write("\n");
-    }
-
-    return buff.toString();
-  }
-
-}
diff --git a/utils/template/htmltree.dart b/utils/template/htmltree.dart
deleted file mode 100644
index e4618db..0000000
--- a/utils/template/htmltree.dart
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Generated by scripts/tree_gen.py.
-
-/////////////////////////////////////////////////////////////////////////
-// CSS specific types:
-/////////////////////////////////////////////////////////////////////////
-
-class Identifier extends ASTNode {
-  String name;
-
-  Identifier(this.name, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitIdentifier(this);
-
-  String toString() => name;
-}
-
-class StringValue extends ASTNode {
-  String value;
-
-  StringValue(this.value, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitStringValue(this);
-
-  String toString() => value;
-}
-
-// CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
-class CommentDefinition extends ASTNode {
-  String comment;
-
-  CommentDefinition(this.comment, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitCommentDefinition(this);
-
-  String toString() => '<!-- ${comment} -->';
-}
-
-class Template extends ASTNode {
-  TemplateSignature signature;
-  TemplateContent content;
-
-  Template(this.signature, this.content, SourceSpan span):
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplate(this);
-
-  String toString() => "${signature.toString()} \r{\r${content.toString()}\r}\r";
-}
-
-class TemplateSignature extends ASTNode {
-  String name;
-  List<Map<Identifier, Identifier>> params;   // Map of {type:, name:}
-
-  TemplateSignature(this.name, this.params, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateSignature(this);
-
-  String paramsAsString() {
-    StringBuffer buff = new StringBuffer();
-    bool first = true;
-    for (final param in params) {
-      if (!first) {
-        buff.write(", ");
-      }
-      if (param['type'] != null) {
-        buff.write(param['type']);
-        buff.write(' ');
-      }
-      buff.write(param['name']);
-      first = false;
-    }
-
-    return buff.toString();
-  }
-
-  String toString() => "template ${name}(${paramsAsString()})";
-}
-
-class TemplateChildren extends ASTNode {
-  List<ASTNode> children;
-
-  TemplateChildren(this.children, SourceSpan span): super(span);
-  TemplateChildren.empty(SourceSpan span): children = [], super(span);
-
-  add(var child) {
-    if (children == null) {
-      children = new List<ASTNode>();
-    }
-    children.add(child);
-  }
-
-  ASTNode get last => children.last;
-  ASTNode removeLast() => children.removeLast();
-  bool get anyChildren => children != null && children.length > 0;
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateChildren(this);
-
-  String toString() {
-    StringBuffer buff = new StringBuffer();
-    if (children != null) {
-      for (final child in children) {
-        buff.write(child.toString());
-      }
-    }
-
-    return buff.toString();
-  }
-}
-
-class TemplateGetter extends ASTNode {
-  String name;
-  List<Map<Identifier, Identifier>> params;
-  TemplateDocument docFrag;
-
-  TemplateGetter(this.name, this.params, this.docFrag, SourceSpan span) :
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateGetter(this);
-
-  String paramsAsString() {
-    StringBuffer buff = new StringBuffer();
-    bool first = true;
-    for (final param in params) {
-      if (!first) {
-        buff.write(", ");
-      }
-      if (param['type'] != null && param['type'].length > 0) {
-        buff.write(param['type']);
-        buff.write(' ');
-      }
-      buff.write(param['name']);
-      first = false;
-    }
-
-    return buff.toString();
-  }
-
-  String getterSignatureAsString() => "${name}(${paramsAsString()})";
-}
-
-class TemplateContent extends ASTNode {
-  css.Stylesheet css;
-  TemplateDocument html;
-  List<TemplateGetter> getters;
-
-  TemplateContent(this.css, this.html, this.getters, SourceSpan span) :
-      super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateContent(this);
-}
-
-class TemplateDocument extends TemplateChildren {
-  TemplateDocument(List<ASTNode> children, SourceSpan span):
-    super(children, span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateDocument(this);
-}
-
-class TemplateElement extends TemplateChildren {
-  int tagTokenId;
-  List<TemplateAttribute> attributes;
-  StringValue _varName;
-
-  TemplateElement(this.tagTokenId, SourceSpan span): super.empty(span);
-  TemplateElement.fragment(SourceSpan span) : super.empty(span), tagTokenId = -1;
-  TemplateElement.attributes(this.tagTokenId, this.attributes, this._varName,
-    SourceSpan span): super.empty(span);
-
-  bool get isFragment => tagTokenId == -1;
-  bool get anyAttributes => attributes != null;
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateElement(this);
-
-  bool get hasVar => _varName != null;
-  String get varName => hasVar ? _varName.value : null;
-
-  String attributesToString() {
-    StringBuffer buff = new StringBuffer();
-
-    if (attributes != null) {
-      for (final attr in attributes) {
-        buff.write(' ${attr.toString()}');
-      }
-    }
-
-    return buff.toString();
-  }
-
-  String get tagName => isFragment ?
-    'root' : TokenKind.tagNameFromTokenId(tagTokenId);
-
-  bool get scoped => !TokenKind.unscopedTag(tagTokenId);
-
-  String tagStartToString() => "<${tagName}${attributesToString()}>";
-
-  String tagEndToString() => "</${tagName}>";
-
-  String toString() {
-    StringBuffer buff = new StringBuffer(tagStartToString());
-
-    if (children != null) {
-      for (final child in children) {
-        buff.write(child.toString());
-      }
-
-      buff.write(tagEndToString());
-    }
-
-    return buff.toString();
-  }
-}
-
-class TemplateAttribute extends ASTNode {
-  String name;
-  String value;
-
-  TemplateAttribute(this.name, this.value, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateAttribute(this);
-
-  String toString() => "${name}=\"${value}\"";
-}
-
-class TemplateText extends ASTNode {
-  String value;
-
-  TemplateText(this.value, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateText(this);
-
-  String toString() => value;
-}
-
-class TemplateExpression extends ASTNode {
-  String expression;
-
-  TemplateExpression(this.expression, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateExpression(this);
-
-  String toString() => "\$\{${expression}}";
-}
-
-class TemplateEachCommand extends ASTNode {
-  String listName;
-  String loopItem;
-  TemplateDocument documentFragment;
-
-  TemplateEachCommand(this.listName, this.loopItem, this.documentFragment,
-      SourceSpan span): super(span);
-
-  bool get hasLoopItem => loopItem != null;
-  String get loopNameOptional => hasLoopItem ? " ${loopItem}" : "";
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateEachCommand(this);
-
-  String toString() => "\$\{#each ${listName}${loopNameOptional}}";
-}
-
-class TemplateWithCommand extends ASTNode {
-  String objectName;
-  String blockItem;
-  TemplateDocument documentFragment;
-
-  TemplateWithCommand(this.objectName, this.blockItem, this.documentFragment,
-      SourceSpan span): super(span);
-
-  bool get hasBlockItem => blockItem != null;
-  String get blockNameOptional => hasBlockItem ? " ${blockItem}" : "";
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateWithCommand(this);
-
-  String toString() => "\$\{#with ${objectName}${blockNameOptional}}";
-}
-
-class TemplateCall extends ASTNode {
-  String toCall;
-  String params;
-
-  TemplateCall(this.toCall, this.params, SourceSpan span): super(span);
-
-  visit(TreeVisitor visitor) => visitor.visitTemplateCall(this);
-
-  String toString() => "\$\{#${toCall}${params}}";
-}
-
-abstract class TreeVisitor {
-  void visitIdentifier(Identifier node);
-  void visitStringValue(StringValue node);
-  void visitCommentDefinition(CommentDefinition node);
-  void visitTemplate(Template node);
-  void visitTemplateSignature(TemplateSignature node);
-  void visitTemplateChildren(TemplateChildren node);
-  void visitTemplateDocument(TemplateDocument node);
-  void visitTemplateContent(TemplateContent node);
-  void visitTemplateElement(TemplateElement node);
-  void visitTemplateAttribute(TemplateAttribute node);
-  void visitTemplateText(TemplateText node);
-  void visitTemplateExpression(TemplateExpression node);
-  void visitTemplateEachCommand(TemplateEachCommand node);
-  void visitTemplateWithCommand(TemplateWithCommand node);
-  void visitTemplateCall(TemplateCall node);
-  void visitTemplateGetter(TemplateGetter node);
-}
-
-class TreePrinter implements TreeVisitor {
-  var output;
-  TreePrinter(this.output) { output.printer = this; }
-
-  void visitIdentifier(Identifier node) {
-    output.heading('Identifier(${output.toValue(node.name)})', node.span);
-  }
-
-  void visitStringValue(StringValue node) {
-    output.heading('"${output.toValue(node.value)}"', node.span);
-  }
-
-  void visitCommentDefinition(CommentDefinition node) {
-    output.heading('CommentDefinition (CDO/CDC)', node.span);
-    output.depth++;
-    output.writeValue('comment value', node.comment);
-    output.depth--;
-  }
-
-  void visitTemplate(Template node) {
-    output.heading('Template', node.span);
-    output.depth++;
-    visitTemplateSignature(node.signature);
-    visitTemplateContent(node.content);
-    output.depth--;
-  }
-
-  void visitTemplateSignature(TemplateSignature node) {
-    output.heading('TemplateSignature', node.span);
-    output.depth++;
-    output.writeValue('Template', node);
-    output.depth--;
-  }
-
-  void visitTemplateChildren(TemplateChildren node) {
-    output.writeNodeList('children', node.children);
-  }
-
-  void visitTemplateContent(TemplateContent node) {
-    visitTemplateDocument(node.html);
-    if (node.css != null) {
-      output.depth++;
-      output.writeValue('---CSS---', node.css.toString());
-      output.depth--;
-    }
-    if (node.getters != null) {
-      output.depth++;
-      output.writeNodeList('---GETTERS---', node.getters);
-      output.depth--;
-    }
-  }
-
-  void visitTemplateDocument(TemplateDocument node) {
-    output.heading('Content', node.span);
-    output.depth++;
-    // TODO(terry): Ugly use of 'as dynamic' instead of children[0] to
-    //              surpress warning.
-    assert(node.children.length == 1 &&
-        (node.children as dynamic)[0].tagTokenId == -1);
-    output.writeNodeList("document", node.children);
-    output.depth--;
-  }
-
-  void visitTemplateElement(TemplateElement node) {
-    output.heading('Element', node.span);
-    output.depth++;
-    output.writeValue('tag', node.tagName);
-    if (node.attributes != null && (node.attributes.length > 0)) {
-      output.writeNodeList("attributes", node.attributes);
-    }
-    visitTemplateChildren(node);
-    output.depth--;
-  }
-
-  void visitTemplateAttribute(TemplateAttribute node) {
-    output.heading('Attribute', node.span);
-    output.depth++;
-    output.writeValue('name', node.name);
-    output.writeValue('value', node.value);
-    output.depth--;
-  }
-
-  void visitTemplateText(TemplateText node) {
-    output.heading('Text', node.span);
-    output.writeValue('value', node.value);
-  }
-
-  void visitTemplateExpression(TemplateExpression node) {
-    output.heading('Interpolate', node.span);
-    output.writeValue('expression', "\$\{${node.expression}\}");
-  }
-
-  void visitTemplateEachCommand(TemplateEachCommand node) {
-    output.heading('#each', node.span);
-    output.writeValue('list', node.listName);
-    visitTemplateDocument(node.documentFragment);
-  }
-
-  void visitTemplateWithCommand(TemplateWithCommand node) {
-    output.heading('#with', node.span);
-    output.writeValue('object', node.objectName);
-    visitTemplateDocument(node.documentFragment);
-  }
-
-  void visitTemplateCall(TemplateCall node) {
-    output.heading('#call template', node.span);
-    output.writeValue('templateToCall', node.toCall);
-    output.writeValue('params', node.params);
-  }
-
-  void visitTemplateGetter(TemplateGetter node) {
-    output.heading('template getter', node.span);
-    output.writeValue('getter Signature', node.getterSignatureAsString());
-    visitTemplateDocument(node.docFrag);
-  }
-}
-
diff --git a/utils/template/parser.dart b/utils/template/parser.dart
deleted file mode 100644
index 9f23d8a..0000000
--- a/utils/template/parser.dart
+++ /dev/null
@@ -1,720 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-
-class TagStack {
-  List<ASTNode> _stack;
-
-  TagStack(var elem) : _stack = [] {
-    _stack.add(elem);
-  }
-
-  void push(var elem) {
-    _stack.add(elem);
-  }
-
-  ASTNode pop() {
-    return _stack.removeLast();
-  }
-
-  top() {
-    return _stack.last;
-  }
-}
-
-// TODO(terry): Cleanup returning errors from CSS to common World error
-//              handler.
-class ErrorMsgRedirector {
-  void displayError(String msg) {
-    if (world.printHandler != null) {
-      world.printHandler(msg);
-    } else {
-      print("Unhandler Error: ${msg}");
-    }
-    world.errors++;
-  }
-}
-
-/**
- * A simple recursive descent parser for HTML.
- */
-class Parser {
-  Tokenizer tokenizer;
-
-  var _fs;                        // If non-null filesystem to read files.
-
-  final SourceFile source;
-
-  Token _previousToken;
-  Token _peekToken;
-
-  PrintHandler printHandler;
-
-  Parser(this.source, [int start = 0, this._fs = null]) {
-    tokenizer = new Tokenizer(source, true, start);
-    _peekToken = tokenizer.next();
-    _previousToken = null;
-  }
-
-  // Main entry point for parsing an entire HTML file.
-  List<Template> parse([PrintHandler handler = null]) {
-    printHandler = handler;
-
-    List<Template> productions = [];
-
-    int start = _peekToken.start;
-    while (!_maybeEat(TokenKind.END_OF_FILE)) {
-      Template template = processTemplate();
-      if (template != null) {
-        productions.add(template);
-      }
-    }
-
-    return productions;
-  }
-
-  /** Generate an error if [source] has not been completely consumed. */
-  void checkEndOfFile() {
-    _eat(TokenKind.END_OF_FILE);
-  }
-
-  /** Guard to break out of parser when an unexpected end of file is found. */
-  // TODO(jimhug): Failure to call this method can lead to inifinite parser
-  //   loops.  Consider embracing exceptions for more errors to reduce
-  //   the danger here.
-  bool isPrematureEndOfFile() {
-    if (_maybeEat(TokenKind.END_OF_FILE)) {
-      _error('unexpected end of file', _peekToken.span);
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  ///////////////////////////////////////////////////////////////////
-  // Basic support methods
-  ///////////////////////////////////////////////////////////////////
-  int _peek() {
-    return _peekToken.kind;
-  }
-
-  Token _next([bool inTag = true]) {
-    _previousToken = _peekToken;
-    _peekToken = tokenizer.next(inTag);
-    return _previousToken;
-  }
-
-  bool _peekKind(int kind) {
-    return _peekToken.kind == kind;
-  }
-
-  /* Is the next token a legal identifier?  This includes pseudo-keywords. */
-  bool _peekIdentifier([String name = null]) {
-    if (TokenKind.isIdentifier(_peekToken.kind)) {
-      return (name != null) ? _peekToken.text == name : true;
-    }
-
-    return false;
-  }
-
-  bool _maybeEat(int kind) {
-    if (_peekToken.kind == kind) {
-      _previousToken = _peekToken;
-      if (kind == TokenKind.GREATER_THAN) {
-        _peekToken = tokenizer.next(false);
-      } else {
-        _peekToken = tokenizer.next();
-      }
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  void _eat(int kind) {
-    if (!_maybeEat(kind)) {
-      _errorExpected(TokenKind.kindToString(kind));
-    }
-  }
-
-  void _eatSemicolon() {
-    _eat(TokenKind.SEMICOLON);
-  }
-
-  void _errorExpected(String expected) {
-    var tok = _next();
-    var message;
-    try {
-      message = 'expected $expected, but found $tok';
-    } catch (e) {
-      message = 'parsing error expected $expected';
-    }
-    _error(message, tok.span);
-  }
-
-  void _error(String message, [SourceSpan location=null]) {
-    if (location == null) {
-      location = _peekToken.span;
-    }
-
-    if (printHandler == null) {
-      world.fatal(message, location);    // syntax errors are fatal for now
-    } else {
-      // TODO(terry):  Need common World view for css and template parser.
-      //               For now this is how we return errors from CSS - ugh.
-      printHandler(message);
-    }
-  }
-
-  void _warning(String message, [SourceSpan location=null]) {
-    if (location == null) {
-      location = _peekToken.span;
-    }
-
-    if (printHandler == null) {
-      world.warning(message, location);
-    } else {
-      // TODO(terry):  Need common World view for css and template parser.
-      //               For now this is how we return errors from CSS - ugh.
-      printHandler(message);
-    }
-  }
-
-  SourceSpan _makeSpan(int start) {
-    return new SourceSpan(source, start, _previousToken.end);
-  }
-
-  ///////////////////////////////////////////////////////////////////
-  // Top level productions
-  ///////////////////////////////////////////////////////////////////
-
-  Template processTemplate() {
-    var template;
-
-    int start = _peekToken.start;
-
-    // Handle the template keyword followed by template signature.
-    _eat(TokenKind.TEMPLATE_KEYWORD);
-
-    if (_peekIdentifier()) {
-      final templateName = identifier();
-
-      List<Map<Identifier, Identifier>> params =
-        new List<Map<Identifier, Identifier>>();
-
-      _eat(TokenKind.LPAREN);
-
-      start = _peekToken.start;
-      while (true) {
-        // TODO(terry): Need robust Dart argument parser (e.g.,
-        //              List<String> arg1, etc).
-        var type = processAsIdentifier();
-        var paramName = processAsIdentifier();
-        if (type != null && paramName != null) {
-          params.add({'type': type, 'name' : paramName});
-
-          if (!_maybeEat(TokenKind.COMMA)) {
-            break;
-          }
-        } else {
-          // No parameters we're done.
-          break;
-        }
-      }
-
-      _eat(TokenKind.RPAREN);
-
-      TemplateSignature sig =
-        new TemplateSignature(templateName.name, params, _makeSpan(start));
-
-      TemplateContent content = processTemplateContent();
-
-      template = new Template(sig, content, _makeSpan(start));
-    }
-
-    return template;
-  }
-
-  // All tokens are identifiers tokenizer is geared to HTML if identifiers are
-  // HTML element or attribute names we need them as an identifier.  Used by
-  // template signatures and expressions in ${...}
-  Identifier processAsIdentifier() {
-    int start = _peekToken.start;
-
-    if (_peekIdentifier()) {
-      return identifier();
-    } else if (TokenKind.validTagName(_peek())) {
-      var tok = _next();
-      return new Identifier(TokenKind.tagNameFromTokenId(tok.kind),
-        _makeSpan(start));
-    }
-  }
-
-  css.Stylesheet processCSS() {
-    // Is there a CSS block?
-    if (_peekIdentifier('css')) {
-      _next();
-
-      int start = _peekToken.start;
-      _eat(TokenKind.LBRACE);
-
-      css.Stylesheet cssCtx = processCSSContent(source, tokenizer.startIndex);
-
-      // TODO(terry): Hack, restart template parser where CSS parser stopped.
-      tokenizer.index = lastCSSIndexParsed;
-     _next(false);
-
-      _eat(TokenKind.RBRACE);       // close } of css block
-
-      return cssCtx;
-    }
-  }
-
-  // TODO(terry): get should be able to use all template control flow but return
-  //              a string instead of a node.  Maybe expose both html and get
-  //              e.g.,
-  //
-  //              A.)
-  //              html {
-  //                <div>...</div>
-  //              }
-  //
-  //              B.)
-  //              html foo() {
-  //                <div>..</div>
-  //              }
-  //
-  //              C.)
-  //              get {
-  //                <div>...</div>
-  //              }
-  //
-  //              D.)
-  //              get foo {
-  //                <div>..</div>
-  //              }
-  //
-  //              Only one default allower either A or C the constructor will
-  //              generate a string or a node.
-  //              Examples B and D would generate getters that either return
-  //              a node for B or a String for D.
-  //
-  List<TemplateGetter> processGetters() {
-    List<TemplateGetter> getters = [];
-
-    while (true) {
-      if (_peekIdentifier('get')) {
-        _next();
-
-        int start = _peekToken.start;
-        if (_peekIdentifier()) {
-          String getterName = identifier().name;
-
-          List<Map<Identifier, Identifier>> params =
-            new List<Map<Identifier, Identifier>>();
-
-          _eat(TokenKind.LPAREN);
-
-          start = _peekToken.start;
-          while (true) {
-            // TODO(terry): Need robust Dart argument parser (e.g.,
-            //              List<String> arg1, etc).
-            var type = processAsIdentifier();
-            var paramName = processAsIdentifier();
-            if (paramName == null && type != null) {
-              paramName = type;
-              type = "";
-            }
-            if (type != null && paramName != null) {
-              params.add({'type': type, 'name' : paramName});
-
-              if (!_maybeEat(TokenKind.COMMA)) {
-                break;
-              }
-            } else {
-              // No parameters we're done.
-              break;
-            }
-          }
-
-          _eat(TokenKind.RPAREN);
-
-          _eat(TokenKind.LBRACE);
-
-          var elems = new TemplateElement.fragment(_makeSpan(_peekToken.start));
-          var templateDoc = processHTML(elems);
-
-          _eat(TokenKind.RBRACE);       // close } of get block
-
-          getters.add(new TemplateGetter(getterName, params, templateDoc,
-            _makeSpan(_peekToken.start)));
-        }
-      } else {
-        break;
-      }
-    }
-
-    return getters;
-
-/*
-    get newTotal(value) {
-      <div class="alignleft">${value}</div>
-    }
-
-    String get HTML_newTotal(value) {
-      return '<div class="alignleft">${value}</div>
-    }
-
-*/
-  }
-
-  TemplateContent processTemplateContent() {
-    css.Stylesheet ss;
-
-    _eat(TokenKind.LBRACE);
-
-    int start = _peekToken.start;
-
-    ss = processCSS();
-
-    // TODO(terry): getters should be allowed anywhere not just after CSS.
-    List<TemplateGetter> getters = processGetters();
-
-    var elems = new TemplateElement.fragment(_makeSpan(_peekToken.start));
-    var templateDoc = processHTML(elems);
-
-    // TODO(terry): Should allow css { } to be at beginning or end of the
-    //              template's content.  Today css only allow at beginning
-    //              because the css {...} is sucked in as a text node.  We'll
-    //              need a special escape for css maybe:
-    //
-    //                  ${#css}
-    //                  ${/css}
-    //
-    //              uggggly!
-
-
-    _eat(TokenKind.RBRACE);
-
-    return new TemplateContent(ss, templateDoc, getters, _makeSpan(start));
-  }
-
-  int lastCSSIndexParsed;       // TODO(terry): Hack, last good CSS parsed.
-
-  css.Stylesheet processCSSContent(var cssSource, int start) {
-    try {
-      css.Parser parser = new css.Parser(new SourceFile(
-          SourceFile.IN_MEMORY_FILE, cssSource.text), start);
-
-      css.Stylesheet stylesheet = parser.parse(false, new ErrorMsgRedirector());
-
-      var lastParsedChar = parser.tokenizer.startIndex;
-
-      lastCSSIndexParsed = lastParsedChar;
-
-      return stylesheet;
-    } catch (cssParseException) {
-      // TODO(terry): Need SourceSpan from CSS parser to pass onto _error.
-      _error("Unexcepted CSS error: ${cssParseException.toString()}");
-    }
-  }
-
-  /* TODO(terry): Assume template {   },  single close curley as a text node
-   *              inside of the template would need to be escaped maybe \}
-   */
-  processHTML(TemplateElement root) {
-    assert(root.isFragment);
-    TagStack stack = new TagStack(root);
-
-    int start = _peekToken.start;
-
-    bool done = false;
-    while (!done) {
-      if (_maybeEat(TokenKind.LESS_THAN)) {
-        // Open tag
-        start = _peekToken.start;
-
-        if (TokenKind.validTagName(_peek())) {
-          Token tagToken = _next();
-
-          Map<String, TemplateAttribute> attrs = processAttributes();
-
-          String varName;
-          if (attrs.containsKey('var')) {
-            varName = attrs['var'].value;
-            attrs.remove('var');
-          }
-
-          int scopeType;     // 1 implies scoped, 2 implies non-scoped element.
-          if (_maybeEat(TokenKind.GREATER_THAN)) {
-            // Scoped unless the tag is explicitly known as an unscoped tag
-            // e.g., <br>.
-            scopeType = TokenKind.unscopedTag(tagToken.kind) ? 2 : 1;
-          } else if (_maybeEat(TokenKind.END_NO_SCOPE_TAG)) {
-            scopeType = 2;
-          }
-          if (scopeType > 0) {
-            var elem = new TemplateElement.attributes(tagToken.kind,
-              attrs.values.toList(), varName, _makeSpan(start));
-            stack.top().add(elem);
-
-            if (scopeType == 1) {
-              // Maybe more nested tags/text?
-              stack.push(elem);
-            }
-          }
-        } else {
-          // Close tag
-          _eat(TokenKind.SLASH);
-          if (TokenKind.validTagName(_peek())) {
-            Token tagToken = _next();
-
-            _eat(TokenKind.GREATER_THAN);
-
-            var elem = stack.pop();
-            if (elem is TemplateElement && !elem.isFragment) {
-              if (elem.tagTokenId != tagToken.kind) {
-                _error('Tag doesn\'t match expected </${elem.tagName}> got ' +
-                  '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>');
-              }
-            } else {
-              // Too many end tags.
-              _error('Too many end tags at ' +
-                  '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>');
-            }
-          }
-        }
-      } else if (_maybeEat(TokenKind.START_COMMAND)) {
-        Identifier commandName = processAsIdentifier();
-        if (commandName != null) {
-          switch (commandName.name) {
-            case "each":
-            case "with":
-              var listName = processAsIdentifier();
-              if (listName != null) {
-                var loopItem = processAsIdentifier();
-                // Is the optional item name specified?
-                //    #each lists [item]
-                //    #with expression [item]
-
-                _eat(TokenKind.RBRACE);
-
-                var frag = new TemplateElement.fragment(
-                    _makeSpan(_peekToken.start));
-                TemplateDocument docFrag = processHTML(frag);
-
-                if (docFrag != null) {
-                  var span = _makeSpan(start);
-                  var cmd;
-                  if (commandName.name == "each") {
-                    cmd = new TemplateEachCommand(listName, loopItem, docFrag,
-                        span);
-                  } else if (commandName.name == "with") {
-                    cmd = new TemplateWithCommand(listName, loopItem, docFrag,
-                        span);
-                  }
-
-                  stack.top().add(cmd);
-                  stack.push(cmd);
-                }
-
-                // Process ${/commandName}
-                _eat(TokenKind.END_COMMAND);
-
-                // Close command ${/commandName}
-                if (_peekIdentifier()) {
-                  commandName = identifier();
-                  switch (commandName.name) {
-                    case "each":
-                    case "with":
-                    case "if":
-                    case "else":
-                      break;
-                    default:
-                      _error('Unknown command \${#${commandName}}');
-                  }
-                  var elem = stack.pop();
-                  if (elem is TemplateEachCommand &&
-                      commandName.name == "each") {
-
-                  } else if (elem is TemplateWithCommand &&
-                    commandName.name == "with") {
-
-                  } /*else if (elem is TemplateIfCommand && commandName == "if") {
-
-                  }
-                  */else {
-                    String expectedCmd;
-                    if (elem is TemplateEachCommand) {
-                      expectedCmd = "\${/each}";
-                    } /* TODO(terry): else other commands as well */
-                    _error('mismatched command expected ${expectedCmd} got...');
-                    return;
-                  }
-                  _eat(TokenKind.RBRACE);
-                } else {
-                  _error('Missing command name \${/commandName}');
-                }
-              } else {
-                _error("Missing listname for #each command");
-              }
-              break;
-            case "if":
-              break;
-            case "else":
-              break;
-            default:
-              // Calling another template.
-              int startPos = this._previousToken.end;
-              // Gobble up everything until we hit }
-              while (_peek() != TokenKind.RBRACE &&
-                     _peek() != TokenKind.END_OF_FILE) {
-                _next(false);
-              }
-
-              if (_peek() == TokenKind.RBRACE) {
-                int endPos = this._previousToken.end;
-                TemplateCall callNode = new TemplateCall(commandName.name,
-                    source.text.substring(startPos, endPos), _makeSpan(start));
-                stack.top().add(callNode);
-
-                _next(false);
-              } else {
-                _error("Unknown template command");
-              }
-          }  // End of switch/case
-        }
-      } else if (_peekKind(TokenKind.END_COMMAND)) {
-        break;
-      } else {
-        // Any text or expression nodes?
-        var nodes = processTextNodes();
-        if (nodes.length > 0) {
-          assert(stack.top() != null);
-          for (var node in nodes) {
-            stack.top().add(node);
-          }
-        } else {
-          break;
-        }
-      }
-    }
-/*
-    if (elems.children.length != 1) {
-      print("ERROR: No closing end-tag for elems ${elems[elems.length - 1]}");
-    }
-*/
-    var docChildren = new List<ASTNode>();
-    docChildren.add(stack.pop());
-    return new TemplateDocument(docChildren, _makeSpan(start));
-  }
-
-  /* Map is used so only last unique attribute name is remembered and to quickly
-   * find the var attribute.
-   */
-  Map<String, TemplateAttribute> processAttributes() {
-    Map<String, TemplateAttribute> attrs = new Map();
-
-    int start = _peekToken.start;
-    String elemName;
-    while (_peekIdentifier() ||
-           (elemName = TokenKind.tagNameFromTokenId(_peek())) != null) {
-      var attrName;
-      if (elemName == null) {
-        attrName = identifier();
-      } else {
-        attrName = new Identifier(elemName, _makeSpan(start));
-        _next();
-      }
-
-      var attrValue;
-
-      // Attribute value?
-      if (_peek() == TokenKind.ATTR_VALUE) {
-        var tok = _next();
-        attrValue = new StringValue(tok.value, _makeSpan(tok.start));
-      }
-
-      attrs[attrName.name] =
-        new TemplateAttribute(attrName, attrValue, _makeSpan(start));
-
-      start = _peekToken.start;
-      elemName = null;
-    }
-
-    return attrs;
-  }
-
-  identifier() {
-    var tok = _next();
-    if (!TokenKind.isIdentifier(tok.kind)) {
-      _error('expected identifier, but found $tok', tok.span);
-    }
-
-    return new Identifier(tok.text, _makeSpan(tok.start));
-  }
-
-  List<ASTNode> processTextNodes() {
-    // May contain TemplateText and TemplateExpression.
-    List<ASTNode> nodes = [];
-
-    int start = _peekToken.start;
-    bool inExpression = false;
-    StringBuffer stringValue = new StringBuffer();
-
-    // Any text chars between close of tag and text node?
-    if (_previousToken.kind == TokenKind.GREATER_THAN) {
-      // If the next token is } could be the close template token.  If user
-      // needs } as token in text node use the entity &125;
-      // TODO(terry): Probably need a &RCURLY entity instead of 125.
-      if (_peek() == TokenKind.ERROR) {
-        // Backup, just past previous token, & rescan we're outside of the tag.
-        tokenizer.index = _previousToken.end;
-        _next(false);
-      } else if (_peek() != TokenKind.RBRACE) {
-        // Yes, grab the chars after the >
-        stringValue.write(_previousToken.source.text.substring(
-            this._previousToken.end, this._peekToken.start));
-      }
-    }
-
-    // Gobble up everything until we hit <
-    while (_peek() != TokenKind.LESS_THAN &&
-           _peek() != TokenKind.START_COMMAND &&
-           _peek() != TokenKind.END_COMMAND &&
-           (_peek() != TokenKind.RBRACE ||
-            (_peek() == TokenKind.RBRACE && inExpression)) &&
-           _peek() != TokenKind.END_OF_FILE) {
-
-      // Beginning of expression?
-      if (_peek() == TokenKind.START_EXPRESSION) {
-        if (stringValue.length > 0) {
-          // We have a real text node create the text node.
-          nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start)));
-          stringValue = new StringBuffer();
-          start = _peekToken.start;
-        }
-        inExpression = true;
-      }
-
-      var tok = _next(false);
-      if (tok.kind == TokenKind.RBRACE && inExpression) {
-        // We have an expression create the expression node, don't save the }
-        inExpression = false;
-        nodes.add(new TemplateExpression(stringValue.toString(),
-          _makeSpan(start)));
-        stringValue = new StringBuffer();
-        start = _peekToken.start;
-      } else if (tok.kind != TokenKind.START_EXPRESSION) {
-        // Only save the the contents between ${ and }
-        stringValue.write(tok.text);
-      }
-    }
-
-    if (stringValue.length > 0) {
-      nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start)));
-    }
-
-    return nodes;
-  }
-
-}
\ No newline at end of file
diff --git a/utils/template/source.dart b/utils/template/source.dart
deleted file mode 100644
index 5eeb0e2..0000000
--- a/utils/template/source.dart
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(jimhug): This should be an interface to work better with tools.
-/**
- * Represents a file of source code.
- */
-class SourceFile implements Comparable<SourceFile> {
-  // TODO(terry): This filename for in memory buffer.  May need to rework if
-  //              filename is used for more than informational.
-  static String IN_MEMORY_FILE = '<buffer>';
-
-  /** The name of the file. */
-  final String filename;
-
-  /** The text content of the file. */
-  String _text;
-
-  /**
-   * The order of the source file in a given library. This is used while we're
-   * writing code for a library. A single source file can be used
-   */
-  // TODO(jmesserly): I don't like having properties that are only valid
-  // sometimes. An alternative would be to store it in a Map that's used by
-  // WorldGenerator while it's emitting code. This seems simpler.
-  int orderInLibrary;
-
-  List<int> _lineStarts;
-
-  SourceFile(this.filename, this._text);
-
-  String get text => _text;
-
-  set text(String newText) {
-    if (newText != _text) {
-      _text = newText;
-      _lineStarts = null;
-      orderInLibrary = null;
-    }
-  }
-
-  List<int> get lineStarts {
-    if (_lineStarts == null) {
-      var starts = [0];
-      var index = 0;
-      while (index < text.length) {
-        index = text.indexOf('\n', index) + 1;
-        if (index <= 0) break;
-        starts.add(index);
-      }
-      starts.add(text.length + 1);
-      _lineStarts = starts;
-    }
-    return _lineStarts;
-  }
-
-  int getLine(int position) {
-    // TODO(jimhug): Implement as binary search.
-    var starts = lineStarts;
-    for (int i=0; i < starts.length; i++) {
-      if (starts[i] > position) return i-1;
-    }
-    world.internalError('bad position');
-  }
-
-  int getColumn(int line, int position) {
-    return position - lineStarts[line];
-  }
-
-  /**
-   * Create a pretty string representation from a character position
-   * in the file.
-   */
-  String getLocationMessage(String message, int start,
-      [int end, bool includeText=false]) {
-    var line = getLine(start);
-    var column = getColumn(line, start);
-
-    var buf = new StringBuffer(
-        '${filename}:${line + 1}:${column + 1}: $message');
-    if (includeText) {
-      buf.write('\n');
-      var textLine;
-      // +1 for 0-indexing, +1 again to avoid the last line of the file
-      if ((line + 2) < _lineStarts.length) {
-        textLine = text.substring(_lineStarts[line], _lineStarts[line+1]);
-      } else {
-        textLine = text.substring(_lineStarts[line]) + '\n';
-      }
-
-      int toColumn = Math.min(column + (end-start), textLine.length);
-      if (options.useColors) {
-        buf.write(textLine.substring(0, column));
-        buf.write(_RED_COLOR);
-        buf.write(textLine.substring(column, toColumn));
-        buf.write(_NO_COLOR);
-        buf.write(textLine.substring(toColumn));
-      } else {
-        buf.write(textLine);
-      }
-
-      int i = 0;
-      for (; i < column; i++) {
-        buf.write(' ');
-      }
-
-      if (options.useColors) buf.write(_RED_COLOR);
-      for (; i < toColumn; i++) {
-        buf.write('^');
-      }
-      if (options.useColors) buf.write(_NO_COLOR);
-    }
-
-    return buf.toString();
-  }
-
-  /** Compares two source files. */
-  int compareTo(SourceFile other) {
-    if (orderInLibrary != null && other.orderInLibrary != null) {
-      return orderInLibrary - other.orderInLibrary;
-    } else {
-      return filename.compareTo(other.filename);
-    }
-  }
-}
-
-
-/**
- * A range of characters in a [SourceFile].  Used to represent the source
- * positions of [Token]s and [Node]s for error reporting or other tooling
- * work.
- */
- // TODO(jmesserly): Rename to Span - but first write cool refactoring tool
-class SourceSpan implements Comparable<SourceSpan> {
-  /** The [SourceFile] that contains this span. */
-  final SourceFile file;
-
-  /** The character position of the start of this span. */
-  final int start;
-
-  /** The character position of the end of this span. */
-  final int end;
-
-  SourceSpan(this.file, this.start, this.end);
-
-  /** Returns the source text corresponding to this [Span]. */
-  String get text {
-    return file.text.substring(start, end);
-  }
-
-  toMessageString(String message) {
-    return file.getLocationMessage(message, start, end: end, includeText: true);
-  }
-
-  int get line {
-    return file.getLine(start);
-  }
-
-  int get column {
-    return file.getColumn(line, start);
-  }
-
-  int get endLine {
-    return file.getLine(end);
-  }
-
-  int get endColumn {
-    return file.getColumn(endLine, end);
-  }
-
-  String get locationText {
-    var line = file.getLine(start);
-    var column = file.getColumn(line, start);
-    return '${file.filename}:${line + 1}:${column + 1}';
-  }
-
-  /** Compares two source spans by file and position. Handles nulls. */
-  int compareTo(SourceSpan other) {
-    if (file == other.file) {
-      int d = start - other.start;
-      return d == 0 ? (end - other.end) : d;
-    }
-    return file.compareTo(other.file);
-  }
-}
diff --git a/utils/template/template b/utils/template/template
deleted file mode 100755
index 0f87661..0000000
--- a/utils/template/template
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash
-
-# To process a template, run this script with the path to a .tmpl file, e.g.,
-#
-# $ $DART/utils/template/template srcfile [outfile]
-#
-# where:
-#    srcfile - the template file file.tmpl (if .tmpl missing .tmpl is assumed).
-#    outfile - the Dart class file to generate, if outfile not specified then
-#              outfile is srcfile.dart (srcfile name w/o ext).
-#
-# To use your Dart VM must be on your $PATH e.g.,
-#
-# export PATH=$PATH:/home/<your name>/dart-all/dart/out/Release_ia32/
-
-
-# Minimum/Maximum number of arguments
-MINARGS=1
-MAXARGS=2
-
-# get the number of command-line arguments given
-ARGC=$#
-
-SRCFILE=
-OUTFILE=
-
-# check to make sure enough arguments were given or exit
-if [[ $ARGC -eq $MINARGS ]];
-then
-  SRCFILE=$1
-  IDX=`expr index "$SRCFILE" .` 
-  if [[ $IDX -eq 0 ]];
-  then
-    # No extension
-    FILENAME=$SRCFILE
-    EXT=
-  else
-    FILENAME=${SRCFILE:0:(IDX-1)}
-    EXT=${SRCFILE:IDX}
-  fi
-
-  TMPL_EXT='tmpl'
-  if [ "$EXT" = "$TMPL_EXT" ];
-  then
-    SRCFILE="$PWD/$1"
-    OUTFILE="$PWD/$FILENAME.dart"
-  else 
-    SRCFILE="$PWD/$1.$TMPL_EXT"
-    OUTFILE="$PWD/$FILENAME.dart"
-  fi
-elif [[ $ARGC -eq 2 ]]
-then
-  SRCFILE="$PWD/$1"
-  OUTFILE="$PWD/$2"
-elif [[ $ARGC -lt $MINARGS ]];
-then
- echo -e "\033[31mToo few arguments given (Minimum $MINARGS argument)\033[0m"
- exit 1
-elif [[ $ARGC -gt $MAXARGS ]];
-then
- echo -e "\033[31mToo many arguments\033[0m"
- exit 1
-fi
-
-if [ "$SRCFILE" = "$OUTFILE" ];
-then
-  echo -e "\033[31msource file must be different from the output file \033[0m"
-  echo -e "source file: $SRCFILE"
-  echo -e "output file: $OUTFILE"
-  exit 1
-fi
-
-# Path of this bash script.
-BASE_DIR="$( cd "$( dirname "$0" )" && pwd )"
-
-# Pre-process the file
-dart $BASE_DIR/tool.dart $SRCFILE $OUTFILE
-
diff --git a/utils/template/template.dart b/utils/template/template.dart
deleted file mode 100644
index ca2dd12..0000000
--- a/utils/template/template.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library template;
-
-import 'dart:math' as Math;
-import '../css/css.dart' as css;
-import '../lib/file_system_memory.dart';
-
-part 'tokenkind.dart';
-part 'token.dart';
-part 'source.dart';
-part 'tokenizer_base.dart';
-part 'tokenizer.dart';
-part 'parser.dart';
-part 'codegen.dart';
-part 'tree.dart';
-part 'htmltree.dart';
-part 'utils.dart';
-part 'temploptions.dart';
-part 'world.dart';
-
-
-void initHtmlWorld([bool commandLine = true]) {
-  var fs = new MemoryFileSystem();
-  //  parseOptions([], fs);
-  initializeWorld(fs);
-
-  // TODO(terry): Should be set by arguments.  When run as a tool these aren't
-  // set when run internaly set these so we can compile CSS and catch any
-  // problems programmatically.
-  //  options.throwOnErrors = true;
-  //  options.throwOnFatal = true;
-  //  options.useColors = commandLine ? true : false;
-}
-
-// TODO(terry): Add obfuscation mapping file.
-List<Template> templateParseAndValidate(String template) {
-  Parser parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-    template));
-
-  return parser.parse();
-//  if (tree != null) {
-//    Validate.template(tree.selectors, world);
-//  }
-}
diff --git a/utils/template/template.html b/utils/template/template.html
deleted file mode 100644
index 9663d6e..0000000
--- a/utils/template/template.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!-- Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-     for details. All rights reserved. Use of this source code is governed by a
-     BSD-style license that can be found in the LICENSE file. -->
-<html>
-  <head>
-    <title>Template UITest</title>
-  </head>
-  <body>
-    <script type="application/dart" src="uitest.dart"></script>
-  </body>
-</html>
diff --git a/utils/template/template_tool.html b/utils/template/template_tool.html
deleted file mode 100644
index 1b3427f..0000000
--- a/utils/template/template_tool.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!-- Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-     for details. All rights reserved. Use of this source code is governed by a
-     BSD-style license that can be found in the LICENSE file. -->
-<html>
-  <head>
-    <title>Template Tool</title>
-  </head>
-  <body>
-    <script type="application/dart" src="tool.dart"></script>
-  </body>
-</html>
diff --git a/utils/template/temploptions.dart b/utils/template/temploptions.dart
deleted file mode 100644
index 33e0256..0000000
--- a/utils/template/temploptions.dart
+++ /dev/null
@@ -1,93 +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.
-
-/** General options used by the compiler. */
-TemplateOptions options;
-
-/** Extracts options from command-line arguments. */
-void parseOptions(List<String> args, var files) {
-  assert(options == null);
-  options = new TemplateOptions(args, files);
-}
-
-class TemplateOptions {
-  /** Location of corelib and other special dart libraries. */
-  String libDir;
-
-  /* The top-level dart script to compile. */
-  String dartScript;
-
-  /** Where to place the generated code. */
-  String outfile;
-
-  // Options that modify behavior significantly
-
-  bool warningsAsErrors = false;
-  bool checkOnly = false;
-
-  // Message support
-  bool throwOnErrors = false;
-  bool throwOnWarnings = false;
-  bool throwOnFatal = false;
-  bool showInfo = false;
-  bool showWarnings = true;
-  bool useColors = true;
-
-  /**
-   * Options to be used later for passing to the generated code. These are all
-   * the arguments after the first dart script, if any.
-   */
-  List<String> childArgs;
-
-  TemplateOptions(List<String> args, var files) {
-    bool ignoreUnrecognizedFlags = false;
-    bool passedLibDir = false;
-    childArgs = [];
-
-    // Start from 2 to skip arguments representing the compiler command
-    // (python followed by frog.py).
-    loop: for (int i = 2; i < args.length; i++) {
-      var arg = args[i];
-
-      switch (arg) {
-        case '--check-only':
-          checkOnly = true;
-          break;
-
-        case '--verbose':
-          showInfo = true;
-          break;
-
-        case '--suppress_warnings':
-          showWarnings = false;
-          break;
-
-        case '--warnings_as_errors':
-          warningsAsErrors = true;
-          break;
-
-        case '--throw_on_errors':
-          throwOnErrors = true;
-          break;
-
-        case '--throw_on_warnings':
-          throwOnWarnings = true;
-          break;
-
-        case '--no_colors':
-          useColors = false;
-          break;
-
-        case '--checked':
-          checkOnly = true;
-          break;
-
-        default:
-          if (!ignoreUnrecognizedFlags) {
-            print('unrecognized flag: "$arg"');
-          }
-      }
-    }
-  }
-}
diff --git a/utils/template/token.dart b/utils/template/token.dart
deleted file mode 100644
index 144e39c..0000000
--- a/utils/template/token.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * A single token in the Dart language.
- */
-class Token {
-  /** A member of [TokenKind] specifying what kind of token this is. */
-  final int kind;
-
-  /** The [SourceFile] this token came from. */
-  final SourceFile source;
-
-  /** The start and end indexes into the [SourceFile] of this [Token]. */
-  final int start, end;
-
-  Token(this.kind, this.source, this.start, this.end) {}
-
-  Token.fake(this.kind, span)
-    : this.source = span.file, this.start = span.start, this.end = span.end;
-
-  /** Returns the source text corresponding to this [Token]. */
-  String get text {
-    return source.text.substring(start, end);
-  }
-
-  /** Returns a pretty representation of this token for error messages. **/
-  String toString() {
-    var kindText = TokenKind.kindToString(kind);
-    var actualText = text;
-    if (kindText != actualText) {
-      if (actualText.length > 10) {
-        actualText = actualText.substring(0, 8) + '...';
-      }
-      return '$kindText($actualText)';
-    } else {
-      return kindText;
-    }
-  }
-
-  /** Returns a [SourceSpan] representing the source location. */
-  SourceSpan get span {
-    return new SourceSpan(source, start, end);
-  }
-}
-
-/** A token containing a parsed literal value. */
-class LiteralToken extends Token {
-  var value;
-  LiteralToken(kind, source, start, end, this.value)
-      : super(kind, source, start, end);
-}
-
-/** A token containing error information. */
-class ErrorToken extends Token {
-  String message;
-  ErrorToken(kind, source, start, end, this.message)
-      : super(kind, source, start, end);
-}
diff --git a/utils/template/tokenizer.dart b/utils/template/tokenizer.dart
deleted file mode 100644
index cb1b516..0000000
--- a/utils/template/tokenizer.dart
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Tokenizer extends TokenizerBase {
-  TokenKind tmplTokens;
-
-  bool _selectorParsing;
-
-  Tokenizer(SourceFile source, bool skipWhitespace, [int index = 0])
-    : super(source, skipWhitespace, index), _selectorParsing = false {
-      tmplTokens = new TokenKind();
-  }
-
-  int get startIndex => _startIndex;
-  void set index(int idx) {
-    _index = idx;
-  }
-
-  Token next([bool inTag = true]) {
-    // keep track of our starting position
-    _startIndex = _index;
-
-    if (_interpStack != null && _interpStack.depth == 0) {
-      var istack = _interpStack;
-      _interpStack = _interpStack.pop();
-
-      /* TODO(terry): Enable for variable and string interpolation.
-       * if (istack.isMultiline) {
-       *   return finishMultilineStringBody(istack.quote);
-       * } else {
-       *   return finishStringBody(istack.quote);
-       * }
-       */
-    }
-
-    int ch;
-    ch = _nextChar();
-    switch(ch) {
-      case 0:
-        return _finishToken(TokenKind.END_OF_FILE);
-      case tmplTokens.tokens[TokenKind.SPACE]:
-      case tmplTokens.tokens[TokenKind.TAB]:
-      case tmplTokens.tokens[TokenKind.NEWLINE]:
-      case tmplTokens.tokens[TokenKind.RETURN]:
-        if (inTag) {
-          return finishWhitespace();
-        } else {
-          return _finishToken(TokenKind.WHITESPACE);
-        }
-      case tmplTokens.tokens[TokenKind.END_OF_FILE]:
-        return _finishToken(TokenKind.END_OF_FILE);
-      case tmplTokens.tokens[TokenKind.LPAREN]:
-        return _finishToken(TokenKind.LPAREN);
-      case tmplTokens.tokens[TokenKind.RPAREN]:
-        return _finishToken(TokenKind.RPAREN);
-      case tmplTokens.tokens[TokenKind.COMMA]:
-        return _finishToken(TokenKind.COMMA);
-      case tmplTokens.tokens[TokenKind.LBRACE]:
-        return _finishToken(TokenKind.LBRACE);
-      case tmplTokens.tokens[TokenKind.RBRACE]:
-        return _finishToken(TokenKind.RBRACE);
-      case tmplTokens.tokens[TokenKind.LESS_THAN]:
-        return _finishToken(TokenKind.LESS_THAN);
-      case tmplTokens.tokens[TokenKind.GREATER_THAN]:
-        return _finishToken(TokenKind.GREATER_THAN);
-      case tmplTokens.tokens[TokenKind.EQUAL]:
-        if (inTag) {
-          if (_maybeEatChar(tmplTokens.tokens[TokenKind.SINGLE_QUOTE])) {
-            return finishQuotedAttrValue(
-              tmplTokens.tokens[TokenKind.SINGLE_QUOTE]);
-          } else if (_maybeEatChar(tmplTokens.tokens[TokenKind.DOUBLE_QUOTE])) {
-            return finishQuotedAttrValue(
-              tmplTokens.tokens[TokenKind.DOUBLE_QUOTE]);
-          } else if (TokenizerHelpers.isAttributeValueStart(_peekChar())) {
-            return finishAttrValue();
-          }
-        }
-        return _finishToken(TokenKind.EQUAL);
-      case tmplTokens.tokens[TokenKind.SLASH]:
-        if (_maybeEatChar(tmplTokens.tokens[TokenKind.GREATER_THAN])) {
-          return _finishToken(TokenKind.END_NO_SCOPE_TAG);          // />
-        } else if (_maybeEatChar(tmplTokens.tokens[TokenKind.ASTERISK])) {
-          return finishMultiLineComment();
-        } else {
-          return _finishToken(TokenKind.SLASH);
-        }
-      case tmplTokens.tokens[TokenKind.DOLLAR]:
-        if (_maybeEatChar(tmplTokens.tokens[TokenKind.LBRACE])) {
-          if (_maybeEatChar(tmplTokens.tokens[TokenKind.HASH])) {
-            return _finishToken(TokenKind.START_COMMAND);           // ${#
-          } else if (_maybeEatChar(tmplTokens.tokens[TokenKind.SLASH])) {
-            return _finishToken(TokenKind.END_COMMAND);             // ${/
-          } else {
-            return _finishToken(TokenKind.START_EXPRESSION);        // ${
-          }
-        } else {
-          return _finishToken(TokenKind.DOLLAR);
-        }
-
-      default:
-        if (TokenizerHelpers.isIdentifierStart(ch)) {
-          return this.finishIdentifier();
-        } else if (TokenizerHelpers.isDigit(ch)) {
-          return this.finishNumber();
-        } else {
-          return _errorToken();
-        }
-    }
-  }
-
-  // TODO(jmesserly): we need a way to emit human readable error messages from
-  // the tokenizer.
-  Token _errorToken([String message = null]) {
-    return _finishToken(TokenKind.ERROR);
-  }
-
-  int getIdentifierKind() {
-    // Is the identifier an element?
-    int tokId = TokenKind.matchElements(_text, _startIndex,
-      _index - _startIndex);
-    if (tokId == -1) {
-      // No, is it an attribute?
-//      tokId = TokenKind.matchAttributes(_text, _startIndex, _index - _startIndex);
-    }
-    if (tokId == -1) {
-      tokId = TokenKind.matchKeywords(_text, _startIndex, _index - _startIndex);
-    }
-
-    return tokId >= 0 ? tokId : TokenKind.IDENTIFIER;
-  }
-
-  // Need to override so CSS version of isIdentifierPart is used.
-  Token finishIdentifier() {
-    while (_index < _text.length) {
-//      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index++))) {
-      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index))) {
-//        _index--;
-        break;
-      } else {
-        _index += 1;
-      }
-    }
-    if (_interpStack != null && _interpStack.depth == -1) {
-      _interpStack.depth = 0;
-    }
-    int kind = getIdentifierKind();
-    if (kind == TokenKind.IDENTIFIER) {
-      return _finishToken(TokenKind.IDENTIFIER);
-    } else {
-      return _finishToken(kind);
-    }
-  }
-
-  Token _makeAttributeValueToken(List<int> buf) {
-    final s = new String.fromCharCodes(buf);
-    return new LiteralToken(TokenKind.ATTR_VALUE, _source, _startIndex, _index,
-      s);
-  }
-
-  /* quote if -1 signals to read upto first whitespace otherwise read upto
-   * single or double quote char.
-   */
-  Token finishQuotedAttrValue([int quote = -1]) {
-    var buf = new List<int>();
-    while (true) {
-      int ch = _nextChar();
-      if (ch == quote) {
-        return _makeAttributeValueToken(buf);
-      } else if (ch == 0) {
-        return _errorToken();
-      } else {
-        buf.add(ch);
-      }
-    }
-  }
-
-  Token finishAttrValue() {
-    var buf = new List<int>();
-    while (true) {
-      int ch = _peekChar();
-      if (TokenizerHelpers.isWhitespace(ch) || TokenizerHelpers.isSlash(ch) ||
-          TokenizerHelpers.isCloseTag(ch)) {
-        return _makeAttributeValueToken(buf);
-      } else if (ch == 0) {
-        return _errorToken();
-      } else {
-        buf.add(_nextChar());
-      }
-    }
-  }
-
-  Token finishNumber() {
-    eatDigits();
-
-    if (_peekChar() == 46/*.*/) {
-      // Handle the case of 1.toString().
-      _nextChar();
-      if (TokenizerHelpers.isDigit(_peekChar())) {
-        eatDigits();
-        return _finishToken(TokenKind.DOUBLE);
-      } else {
-        _index -= 1;
-      }
-    }
-
-    return _finishToken(TokenKind.INTEGER);
-  }
-
-  bool maybeEatDigit() {
-    if (_index < _text.length && TokenizerHelpers.isDigit(
-        _text.codeUnitAt(_index))) {
-      _index += 1;
-      return true;
-    }
-    return false;
-  }
-
-  void eatHexDigits() {
-    while (_index < _text.length) {
-     if (TokenizerHelpers.isHexDigit(_text.codeUnitAt(_index))) {
-       _index += 1;
-     } else {
-       return;
-     }
-    }
-  }
-
-  bool maybeEatHexDigit() {
-    if (_index < _text.length && TokenizerHelpers.isHexDigit(
-        _text.codeUnitAt(_index))) {
-      _index += 1;
-      return true;
-    }
-    return false;
-  }
-
-  Token finishMultiLineComment() {
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _finishToken(TokenKind.INCOMPLETE_COMMENT);
-      } else if (ch == 42/*'*'*/) {
-        if (_maybeEatChar(47/*'/'*/)) {
-          if (_skipWhitespace) {
-            return next();
-          } else {
-            return _finishToken(TokenKind.COMMENT);
-          }
-        }
-      } else if (ch == tmplTokens.tokens[TokenKind.MINUS]) {
-        /* Check if close part of Comment Definition --> (CDC). */
-        if (_maybeEatChar(tmplTokens.tokens[TokenKind.MINUS])) {
-          if (_maybeEatChar(tmplTokens.tokens[TokenKind.GREATER_THAN])) {
-            if (_skipWhitespace) {
-              return next();
-            } else {
-              return _finishToken(TokenKind.HTML_COMMENT);
-            }
-          }
-        }
-      }
-    }
-    return _errorToken();
-  }
-
-}
-
-
-/** Static helper methods. */
-class TokenizerHelpers {
-  static bool isIdentifierStart(int c) {
-    return ((c >= 97/*a*/ && c <= 122/*z*/) ||
-        (c >= 65/*A*/ && c <= 90/*Z*/) || c == 95/*_*/);
-  }
-
-  static bool isDigit(int c) {
-    return (c >= 48/*0*/ && c <= 57/*9*/);
-  }
-
-  static bool isHexDigit(int c) {
-    return (isDigit(c) || (c >= 97/*a*/ && c <= 102/*f*/) ||
-        (c >= 65/*A*/ && c <= 70/*F*/));
-  }
-
-  static bool isWhitespace(int c) {
-    return (c == 32/*' '*/ || c == 9/*'\t'*/ || c == 10/*'\n'*/ ||
-        c == 13/*'\r'*/);
-  }
-
-  static bool isIdentifierPart(int c) {
-    return (isIdentifierStart(c) || isDigit(c) || c == 45/*-*/ ||
-        c == 58/*:*/ || c == 46/*.*/);
-  }
-
-  static bool isInterpIdentifierPart(int c) {
-    return (isIdentifierStart(c) || isDigit(c));
-  }
-
-  static bool isAttributeValueStart(int c) {
-    return !isWhitespace(c) && !isSlash(c) && !isCloseTag(c);
-  }
-
-  static bool isSlash(int c) {
-    return (c == 47/* / */);
-  }
-
-  static bool isCloseTag(int c) {
-    return (c == 62/* > */);
-  }
-}
diff --git a/utils/template/tokenizer_base.dart b/utils/template/tokenizer_base.dart
deleted file mode 100644
index eb1bcdf..0000000
--- a/utils/template/tokenizer_base.dart
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Generated by scripts/tokenizer_gen.py.
-
-
-abstract class TokenSource {
-  Token next();
-}
-
-class InterpStack {
-  InterpStack next, previous;
-  final int quote;
-  final bool isMultiline;
-  int depth;
-
-  InterpStack(this.previous, this.quote, this.isMultiline): depth = -1;
-
-  InterpStack pop() {
-    return this.previous;
-  }
-
-  static InterpStack push(InterpStack stack, int quote, bool isMultiline) {
-    var newStack = new InterpStack(stack, quote, isMultiline);
-    if (stack != null) newStack.previous = stack;
-    return newStack;
-  }
-}
-
-/**
- * The base class for our tokenizer. The hand coded parts are in this file, with
- * the generated parts in the subclass Tokenizer.
- */
-class TokenizerBase extends TokenizerHelpers implements TokenSource {
-  final SourceFile _source;
-  final bool _skipWhitespace;
-  String _text;
-
-  int _index;
-  int _startIndex;
-
-  /** Keeps track of string interpolation state. */
-  InterpStack _interpStack;
-
-  TokenizerBase(this._source, this._skipWhitespace, [index = 0])
-      : this._index = index {
-    _text = _source.text;
-  }
-
-  abstract Token next();
-  abstract int getIdentifierKind();
-
-  int _nextChar() {
-    if (_index < _text.length) {
-      return _text.codeUnitAt(_index++);
-    } else {
-      return 0;
-    }
-  }
-
-  int _peekChar() {
-    if (_index < _text.length) {
-      return _text.codeUnitAt(_index);
-    } else {
-      return 0;
-    }
-  }
-
-  bool _maybeEatChar(int ch) {
-    if (_index < _text.length) {
-      if (_text.codeUnitAt(_index) == ch) {
-        _index++;
-        return true;
-      } else {
-        return false;
-      }
-    } else {
-      return false;
-    }
-  }
-
-  String _tokenText() {
-    if (_index < _text.length) {
-      return _text.substring(_startIndex, _index);
-    } else {
-      return _text.substring(_startIndex, _text.length);
-    }
-  }
-
-  Token _finishToken(int kind) {
-    return new Token(kind, _source, _startIndex, _index);
-  }
-
-  Token _errorToken([String message = null]) {
-    return new ErrorToken(
-        TokenKind.ERROR, _source, _startIndex, _index, message);
-  }
-
-  Token finishWhitespace() {
-    _index--;
-    while (_index < _text.length) {
-      final ch = _text.codeUnitAt(_index++);
-      if (ch == 32/*' '*/ || ch == 9/*'\t'*/ || ch == 13/*'\r'*/) {
-        // do nothing
-      } else if (ch == 10/*'\n'*/) {
-        if (!_skipWhitespace) {
-          return _finishToken(TokenKind.WHITESPACE); // note the newline?
-        }
-      } else {
-        _index--;
-        if (_skipWhitespace) {
-          return next();
-        } else {
-          return _finishToken(TokenKind.WHITESPACE);
-        }
-      }
-
-    }
-    return _finishToken(TokenKind.END_OF_FILE);
-  }
-
-  Token finishSingleLineComment() {
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0 || ch == 10/*'\n'*/ || ch == 13/*'\r'*/) {
-        if (_skipWhitespace) {
-          return next();
-        } else {
-          return _finishToken(TokenKind.COMMENT);
-        }
-      }
-    }
-  }
-
-  Token finishMultiLineComment() {
-    int nesting = 1;
-    do {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _errorToken();
-      } else if (ch == 42/*'*'*/) {
-        if (_maybeEatChar(47/*'/'*/)) {
-          nesting--;
-        }
-      } else if (ch == 47/*'/'*/) {
-        if (_maybeEatChar(42/*'*'*/)) {
-          nesting++;
-        }
-      }
-    } while (nesting > 0);
-
-    if (_skipWhitespace) {
-      return next();
-    } else {
-      return _finishToken(TokenKind.COMMENT);
-    }
-  }
-
-  void eatDigits() {
-    while (_index < _text.length) {
-      if (TokenizerHelpers.isDigit(_text.codeUnitAt(_index))) {
-        _index++;
-      } else {
-        return;
-      }
-    }
-  }
-
-  static int _hexDigit(int c) {
-    if(c >= 48/*0*/ && c <= 57/*9*/) {
-      return c - 48;
-    } else if (c >= 97/*a*/ && c <= 102/*f*/) {
-      return c - 87;
-    } else if (c >= 65/*A*/ && c <= 70/*F*/) {
-      return c - 55;
-    } else {
-      return -1;
-    }
-  }
-
-  int readHex([int hexLength]) {
-    int maxIndex;
-    if (hexLength == null) {
-      maxIndex = _text.length - 1;
-    } else {
-      // TODO(jimhug): What if this is too long?
-      maxIndex = _index + hexLength;
-      if (maxIndex >= _text.length) return -1;
-    }
-    var result = 0;
-    while (_index < maxIndex) {
-      final digit = _hexDigit(_text.codeUnitAt(_index));
-      if (digit == -1) {
-        if (hexLength == null) {
-          return result;
-        } else {
-          return -1;
-        }
-      }
-      _hexDigit(_text.codeUnitAt(_index));
-      // Multiply by 16 rather than shift by 4 since that will result in a
-      // correct value for numbers that exceed the 32 bit precision of JS
-      // 'integers'.
-      // TODO: Figure out a better solution to integer truncation. Issue 638.
-      result = (result * 16) + digit;
-      _index++;
-    }
-
-    return result;
-  }
-
-  Token finishNumber() {
-    eatDigits();
-
-    if (_peekChar() == 46/*.*/) {
-      // Handle the case of 1.toString().
-      _nextChar();
-      if (TokenizerHelpers.isDigit(_peekChar())) {
-        eatDigits();
-        return finishNumberExtra(TokenKind.DOUBLE);
-      } else {
-        _index--;
-      }
-    }
-
-    return finishNumberExtra(TokenKind.INTEGER);
-  }
-
-  Token finishNumberExtra(int kind) {
-    if (_maybeEatChar(101/*e*/) || _maybeEatChar(69/*E*/)) {
-      kind = TokenKind.DOUBLE;
-      _maybeEatChar(45/*-*/);
-      _maybeEatChar(43/*+*/);
-      eatDigits();
-    }
-    if (_peekChar() != 0 && TokenizerHelpers.isIdentifierStart(_peekChar())) {
-      _nextChar();
-      return _errorToken("illegal character in number");
-    }
-
-    return _finishToken(kind);
-  }
-
-  Token _makeStringToken(List<int> buf, bool isPart) {
-    final s = new String.fromCharCodes(buf);
-    final kind = isPart ? TokenKind.STRING_PART : TokenKind.STRING;
-    return new LiteralToken(kind, _source, _startIndex, _index, s);
-  }
-
-  Token _makeRawStringToken(bool isMultiline) {
-    String s;
-    if (isMultiline) {
-      // Skip initial newline in multiline strings
-      int start = _startIndex + 4;
-      if (_source.text[start] == '\n') start++;
-      s = _source.text.substring(start, _index - 3);
-    } else {
-      s = _source.text.substring(_startIndex + 2, _index - 1);
-    }
-    return new LiteralToken(TokenKind.STRING, _source, _startIndex, _index, s);
-  }
-
-  Token finishMultilineString(int quote) {
-    var buf = <int>[];
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _errorToken();
-      } else if (ch == quote) {
-        if (_maybeEatChar(quote)) {
-          if (_maybeEatChar(quote)) {
-            return _makeStringToken(buf, false);
-          }
-          buf.add(quote);
-        }
-        buf.add(quote);
-      } else if (ch == 36/*$*/) {
-        // start of string interp
-        _interpStack = InterpStack.push(_interpStack, quote, true);
-        return _makeStringToken(buf, true);
-      } else if (ch == 92/*\*/) {
-        var escapeVal = readEscapeSequence();
-        if (escapeVal == -1) {
-          return _errorToken("invalid hex escape sequence");
-        } else {
-          buf.add(escapeVal);
-        }
-      } else {
-        buf.add(ch);
-      }
-    }
-  }
-
-  Token _finishOpenBrace() {
-    if (_interpStack != null) {
-      if (_interpStack.depth == -1) {
-        _interpStack.depth = 1;
-      } else {
-        assert(_interpStack.depth >= 0);
-        _interpStack.depth += 1;
-      }
-    }
-    return _finishToken(TokenKind.LBRACE);
-  }
-
-  Token _finishCloseBrace() {
-    if (_interpStack != null) {
-      _interpStack.depth -= 1;
-      assert(_interpStack.depth >= 0);
-    }
-    return _finishToken(TokenKind.RBRACE);
-  }
-
-  Token finishString(int quote) {
-    if (_maybeEatChar(quote)) {
-      if (_maybeEatChar(quote)) {
-        // skip an initial newline
-        _maybeEatChar(10/*'\n'*/);
-        return finishMultilineString(quote);
-      } else {
-        return _makeStringToken(new List<int>(), false);
-      }
-    }
-    return finishStringBody(quote);
-  }
-
-  Token finishRawString(int quote) {
-    if (_maybeEatChar(quote)) {
-      if (_maybeEatChar(quote)) {
-        return finishMultilineRawString(quote);
-      } else {
-        return _makeStringToken(<int>[], false);
-      }
-    }
-    while (true) {
-      int ch = _nextChar();
-      if (ch == quote) {
-        return _makeRawStringToken(false);
-      } else if (ch == 0) {
-        return _errorToken();
-      }
-    }
-  }
-
-  Token finishMultilineRawString(int quote) {
-    while (true) {
-      int ch = _nextChar();
-      if (ch == 0) {
-        return _errorToken();
-      } else if (ch == quote && _maybeEatChar(quote) && _maybeEatChar(quote)) {
-        return _makeRawStringToken(true);
-      }
-    }
-  }
-
-  Token finishStringBody(int quote) {
-    var buf = new List<int>();
-    while (true) {
-      int ch = _nextChar();
-      if (ch == quote) {
-        return _makeStringToken(buf, false);
-      } else if (ch == 36/*$*/) {
-        // start of string interp
-        _interpStack = InterpStack.push(_interpStack, quote, false);
-        return _makeStringToken(buf, true);
-      } else if (ch == 0) {
-        return _errorToken();
-      } else if (ch == 92/*\*/) {
-        var escapeVal = readEscapeSequence();
-        if (escapeVal == -1) {
-          return _errorToken("invalid hex escape sequence");
-        } else {
-          buf.add(escapeVal);
-        }
-      } else {
-        buf.add(ch);
-      }
-    }
-  }
-
-  int readEscapeSequence() {
-    final ch = _nextChar();
-    int hexValue;
-    switch (ch) {
-      case 110/*n*/:
-        return 0x0a/*'\n'*/;
-      case 114/*r*/:
-        return 0x0d/*'\r'*/;
-      case 102/*f*/:
-        return 0x0c/*'\f'*/;
-      case 98/*b*/:
-        return 0x08/*'\b'*/;
-      case 116/*t*/:
-        return 0x09/*'\t'*/;
-      case 118/*v*/:
-        return 0x0b/*'\v'*/;
-      case 120/*x*/:
-        hexValue = readHex(2);
-        break;
-      case 117/*u*/:
-        if (_maybeEatChar(123/*{*/)) {
-          hexValue = readHex();
-          if (!_maybeEatChar(125/*}*/)) {
-            return -1;
-          } else {
-            break;
-          }
-        } else {
-          hexValue = readHex(4);
-          break;
-        }
-      default: return ch;
-    }
-
-    if (hexValue == -1) return -1;
-
-    // According to the Unicode standard the high and low surrogate halves
-    // used by UTF-16 (U+D800 through U+DFFF) and values above U+10FFFF
-    // are not legal Unicode values.
-    if (hexValue < 0xD800 || hexValue > 0xDFFF && hexValue <= 0xFFFF) {
-      return hexValue;
-    } else if (hexValue <= 0x10FFFF){
-      world.fatal('unicode values greater than 2 bytes not implemented yet');
-      return -1;
-    } else {
-      return -1;
-    }
-  }
-
-  Token finishDot() {
-    if (TokenizerHelpers.isDigit(_peekChar())) {
-      eatDigits();
-      return finishNumberExtra(TokenKind.DOUBLE);
-    } else {
-      return _finishToken(TokenKind.DOT);
-    }
-  }
-
-  Token finishIdentifier() {
-    if (_interpStack != null && _interpStack.depth == -1) {
-      _interpStack.depth = 0;
-      while (_index < _text.length) {
-        if (!TokenizerHelpers.isInterpIdentifierPart(
-            _text.codeUnitAt(_index++))) {
-          _index--;
-          break;
-        }
-      }
-    } else {
-      while (_index < _text.length) {
-        if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index++))) {
-          _index--;
-          break;
-        }
-      }
-    }
-    int kind = getIdentifierKind();
-    if (kind == TokenKind.IDENTIFIER) {
-      return _finishToken(TokenKind.IDENTIFIER);
-    } else {
-      return _finishToken(kind);
-    }
-  }
-}
-
diff --git a/utils/template/tokenkind.dart b/utils/template/tokenkind.dart
deleted file mode 100644
index 29da694..0000000
--- a/utils/template/tokenkind.dart
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(terry): Need to be consistent with tokens either they're ASCII tokens
-//              e.g., ASTERISK or they're CSS e.g., PSEUDO, COMBINATOR_*.
-class TokenKind {
-  // Common shared tokens used in TokenizerBase.
-  static const int UNUSED = 0;                  // Unused place holder...
-  static const int END_OF_FILE = 1;
-  static const int LPAREN = 2;                  // (
-  static const int RPAREN = 3;                  // )
-  static const int LBRACK = 4;                  // [
-  static const int RBRACK = 5;                  // ]
-  static const int LBRACE = 6;                  // {
-  static const int RBRACE = 7;                  // }
-  static const int DOT = 8;                     // .
-  static const int SEMICOLON = 9;               // ;
-  static const int SPACE = 10;                  // space character
-  static const int TAB = 11;                    // \t
-  static const int NEWLINE = 12;                // \n
-  static const int RETURN = 13;                 // \r
-  static const int COMMA = 14;                  // ,
-
-  // Unique tokens.
-  static const int LESS_THAN = 15;              // <
-  static const int GREATER_THAN = 16;           // >
-  static const int SLASH = 17;                  // /
-  static const int DOLLAR = 18;                 // $
-  static const int HASH = 19;                   // #
-  static const int MINUS = 20;                  // -
-  static const int EQUAL = 21;                  // =
-  static const int DOUBLE_QUOTE = 22;           // "
-  static const int SINGLE_QUOTE = 23;           // '
-  static const int ASTERISK = 24;               // *
-
-  // WARNING: END_TOKENS must be 1 greater than the last token above (last
-  //          character in our list).  Also add to kindToString function and the
-  //          constructor for TokenKind.
-
-  static const int END_TOKENS = 25;             // Marker for last token in list
-
-  // Synthesized tokens:
-
-  static const int END_NO_SCOPE_TAG = 50;       // />
-  static const int START_EXPRESSION = 51;       // ${
-  static const int START_COMMAND = 52;          // ${#
-  static const int END_COMMAND = 53;            // ${/
-  static const int EACH_COMMAND = 53;           // ${#each list}
-  static const int WITH_COMMAND = 54;           // ${#with object}
-  static const int IF_COMMAND = 55;             // ${#if (expression)}
-  static const int ELSE_COMMAND = 56;           // ${#else}
-
-  /** [TokenKind] representing integer tokens. */
-  static const int INTEGER = 60;                // TODO(terry): must match base
-
-  /** [TokenKind] representing hex integer tokens. */
-//  static const int HEX_INTEGER = 61;          // TODO(terry): must match base
-
-  /** [TokenKind] representing double tokens. */
-  static const int DOUBLE = 62;                 // TODO(terry): must match base
-
-  /** [TokenKind] representing whitespace tokens. */
-  static const int WHITESPACE = 63;             // TODO(terry): must match base
-
-  /** [TokenKind] representing comment tokens. */
-  static const int COMMENT = 64;                // TODO(terry): must match base
-
-  /** [TokenKind] representing error tokens. */
-  static const int ERROR = 65;                  // TODO(terry): must match base
-
-  /** [TokenKind] representing incomplete string tokens. */
-  static const int INCOMPLETE_STRING = 66;      // TODO(terry): must match base
-
-  /** [TokenKind] representing incomplete comment tokens. */
-  static const int INCOMPLETE_COMMENT = 67;     // TODO(terry): must match base
-
-  // Synthesized Tokens (no character associated with TOKEN).
-  // TODO(terry): Possible common names used by both Dart and CSS tokenizers.
-  static const int ATTR_VALUE = 500;
-  static const int NUMBER = 502;
-  static const int HEX_NUMBER = 503;
-  static const int HTML_COMMENT = 504;          // <!--
-  static const int IDENTIFIER = 511;
-  static const int STRING = 512;
-  static const int STRING_PART = 513;
-
-  static const int TEMPLATE_KEYWORD = 595;      // template keyword
-
-  // Elements
-  /* START_HTML_ELEMENT is first valid element tag name
-   * END_HTML_ELEMENT is the last valid element tag name
-   *
-   */
-  static const int START_HTML_ELEMENT = 600;      // First valid tag name.
-  static const int A_ELEMENT = 600;
-  static const int ABBR_ELEMENT = 601;
-  static const int ACRONYM_ELEMENT = 602;
-  static const int ADDRESS_ELEMENT = 603;
-  static const int APPLET_ELEMENT = 604;
-  static const int AREA_ELEMENT = 605;
-  static const int B_ELEMENT = 606;
-  static const int BASE_ELEMENT = 607;
-  static const int BASEFONT_ELEMENT = 608;
-  static const int BDO_ELEMENT = 609;
-  static const int BIG_ELEMENT = 610;
-  static const int BLOCKQUOTE_ELEMENT = 611;
-  static const int BODY_ELEMENT = 612;
-  static const int BR_ELEMENT = 613;
-  static const int BUTTON_ELEMENT = 614;
-  static const int CAPTION_ELEMENT = 615;
-  static const int CENTER_ELEMENT = 616;
-  static const int CITE_ELEMENT = 617;
-  static const int CODE_ELEMENT = 618;
-  static const int COL_ELEMENT = 619;
-  static const int COLGROUP_ELEMENT = 620;
-  static const int DD_ELEMENT = 621;
-  static const int DEL_ELEMENT = 622;
-  static const int DFN_ELEMENT = 623;
-  static const int DIR_ELEMENT = 624;
-  static const int DIV_ELEMENT = 625;
-  static const int DL_ELEMENT = 626;
-  static const int DT_ELEMENT = 627;
-  static const int EM_ELEMENT = 628;
-  static const int FIELDSET_ELEMENT = 629;
-  static const int FONT_ELEMENT = 630;
-  static const int FORM_ELEMENT = 631;
-  static const int FRAME_ELEMENT = 632;
-  static const int FRAMESET_ELEMENT = 633;
-  static const int H1_ELEMENT = 634;
-  static const int H2_ELEMENT = 635;
-  static const int H3_ELEMENT = 636;
-  static const int H4_ELEMENT = 637;
-  static const int H5_ELEMENT = 638;
-  static const int H6_ELEMENT = 639;
-  static const int HEAD_ELEMENT = 640;
-  static const int HR_ELEMENT = 641;
-  static const int HTML_ELEMENT = 642;
-  static const int I_ELEMENT = 643;
-  static const int IFRAME_ELEMENT = 644;
-  static const int IMG_ELEMENT = 645;
-  static const int INPUT_ELEMENT = 646;
-  static const int INS_ELEMENT = 647;
-  static const int ISINDEX_ELEMENT = 648;
-  static const int KBD_ELEMENT = 649;
-  static const int LABEL_ELEMENT = 650;
-  static const int LEGEND_ELEMENT = 651;
-  static const int LI_ELEMENT = 652;
-  static const int LINK_ELEMENT = 653;
-  static const int MAP_ELEMENT = 654;
-  static const int MENU_ELEMENT = 645;
-  static const int META_ELEMENT = 656;
-  static const int NOFRAMES_ELEMENT = 657;
-  static const int NOSCRIPT_ELEMENT = 658;
-  static const int OBJECT_ELEMENT = 659;
-  static const int OL_ELEMENT = 660;
-  static const int OPTGROUP_ELEMENT = 661;
-  static const int OPTION_ELEMENT = 662;
-  static const int P_ELEMENT = 663;
-  static const int PARAM_ELEMENT = 664;
-  static const int PRE_ELEMENT = 665;
-  static const int Q_ELEMENT = 666;
-  static const int S_ELEMENT = 667;
-  static const int SAMP_ELEMENT = 668;
-  static const int SCRIPT_ELEMENT = 669;
-  static const int SELECT_ELEMENT = 670;
-  static const int SMALL_ELEMENT = 671;
-  static const int SPAN_ELEMENT = 672;
-  static const int STRIKE_ELEMENT = 673;
-  static const int STRONG_ELEMENT = 674;
-  static const int STYLE_ELEMENT = 675;
-  static const int SUB_ELEMENT = 676;
-  static const int SUP_ELEMENT = 677;
-  static const int TABLE_ELEMENT = 678;
-  static const int TBODY_ELEMENT = 679;
-  static const int TD_ELEMENT = 680;
-  static const int TEXTAREA_ELEMENT = 681;
-  static const int TFOOT_ELEMENT = 682;
-  static const int TH_ELEMENT = 683;
-  static const int THEAD_ELEMENT = 684;
-  static const int TITLE_ELEMENT = 685;
-  static const int TR_ELEMENT = 686;
-  static const int TT_ELEMENT = 687;
-  static const int U_ELEMENT = 688;
-  static const int UL_ELEMENT = 689;
-  static const int VAR_ELEMENT = 690;
-  static const int END_HTML_ELEMENT = VAR_ELEMENT;    // Last valid tag name.
-
-  static bool validTagName(int tokId) {
-    return tokId >= TokenKind.START_HTML_ELEMENT &&
-      tokId <= TokenKind.END_HTML_ELEMENT;
-  }
-
-  static const List<Map<int, String>> _KEYWORDS = const [
-    const {'type': TokenKind.TEMPLATE_KEYWORD, 'value' : 'template'},
-  ];
-
-  static const List<int> _NON_SCOPED_ELEMENTS = const [
-    BR_ELEMENT,
-  ];
-
-  // tag values starting with a minus sign implies tag can be unscoped e.g.,
-  // <br> is valid without <br></br> or <br/>
-  static const List<Map<int, String>> _ELEMENTS = const [
-    const {'type': TokenKind.A_ELEMENT, 'value' : 'a'},
-    const {'type': TokenKind.ABBR_ELEMENT, 'value' : 'abbr'},
-    const {'type': TokenKind.ACRONYM_ELEMENT, 'value' : 'acronym'},
-    const {'type': TokenKind.ADDRESS_ELEMENT, 'value' : 'address'},
-    const {'type': TokenKind.APPLET_ELEMENT, 'value' : 'applet'},
-    const {'type': TokenKind.AREA_ELEMENT, 'value' : 'area'},
-    const {'type': TokenKind.B_ELEMENT, 'value' : 'b'},
-    const {'type': TokenKind.BASE_ELEMENT, 'value' : 'base'},
-    const {'type': TokenKind.BASEFONT_ELEMENT, 'value' : 'basefont'},
-    const {'type': TokenKind.BDO_ELEMENT, 'value' : 'bdo'},
-    const {'type': TokenKind.BIG_ELEMENT, 'value' : 'big'},
-    const {'type': TokenKind.BLOCKQUOTE_ELEMENT, 'value' : 'blockquote'},
-    const {'type': TokenKind.BODY_ELEMENT, 'value' : 'body'},
-    const {'type': TokenKind.BR_ELEMENT, 'value' : 'br'},
-    const {'type': TokenKind.BUTTON_ELEMENT, 'value' : 'button'},
-    const {'type': TokenKind.CAPTION_ELEMENT, 'value' : 'caption'},
-    const {'type': TokenKind.CENTER_ELEMENT, 'value' : 'center'},
-    const {'type': TokenKind.CITE_ELEMENT, 'value' : 'cite'},
-    const {'type': TokenKind.CODE_ELEMENT, 'value' : 'code'},
-    const {'type': TokenKind.COL_ELEMENT, 'value' : 'col'},
-    const {'type': TokenKind.COLGROUP_ELEMENT, 'value' : 'colgroup'},
-    const {'type': TokenKind.DD_ELEMENT, 'value' : 'dd'},
-    const {'type': TokenKind.DEL_ELEMENT, 'value' : 'del'},
-    const {'type': TokenKind.DFN_ELEMENT, 'value' : 'dfn'},
-    const {'type': TokenKind.DIR_ELEMENT, 'value' : 'dir'},
-    const {'type': TokenKind.DIV_ELEMENT, 'value' : 'div'},
-    const {'type': TokenKind.DL_ELEMENT, 'value' : 'dl'},
-    const {'type': TokenKind.DT_ELEMENT, 'value' : 'dt'},
-    const {'type': TokenKind.EM_ELEMENT, 'value' : 'em'},
-    const {'type': TokenKind.FIELDSET_ELEMENT, 'value' : 'fieldset'},
-    const {'type': TokenKind.FONT_ELEMENT, 'value' : 'font'},
-    const {'type': TokenKind.FORM_ELEMENT, 'value' : 'form'},
-    const {'type': TokenKind.FRAME_ELEMENT, 'value' : 'frame'},
-    const {'type': TokenKind.FRAMESET_ELEMENT, 'value' : 'frameset'},
-    const {'type': TokenKind.H1_ELEMENT, 'value' : 'h1'},
-    const {'type': TokenKind.H2_ELEMENT, 'value' : 'h2'},
-    const {'type': TokenKind.H3_ELEMENT, 'value' : 'h3'},
-    const {'type': TokenKind.H4_ELEMENT, 'value' : 'h4'},
-    const {'type': TokenKind.H5_ELEMENT, 'value' : 'h5'},
-    const {'type': TokenKind.H6_ELEMENT, 'value' : 'h6'},
-    const {'type': TokenKind.HEAD_ELEMENT, 'value' : 'head'},
-    const {'type': TokenKind.HR_ELEMENT, 'value' : 'hr'},
-    const {'type': TokenKind.HTML_ELEMENT, 'value' : 'html'},
-    const {'type': TokenKind.I_ELEMENT, 'value' : 'i'},
-    const {'type': TokenKind.IFRAME_ELEMENT, 'value' : 'iframe'},
-    const {'type': TokenKind.IMG_ELEMENT, 'value' : 'img'},
-    const {'type': TokenKind.INPUT_ELEMENT, 'value' : 'input'},
-    const {'type': TokenKind.INS_ELEMENT, 'value' : 'ins'},
-    const {'type': TokenKind.ISINDEX_ELEMENT, 'value' : 'isindex'},
-    const {'type': TokenKind.KBD_ELEMENT, 'value' : 'kbd'},
-    const {'type': TokenKind.LABEL_ELEMENT, 'value' : 'label'},
-    const {'type': TokenKind.LEGEND_ELEMENT, 'value' : 'legend'},
-    const {'type': TokenKind.LI_ELEMENT, 'value' : 'li'},
-    const {'type': TokenKind.LINK_ELEMENT, 'value' : 'link'},
-    const {'type': TokenKind.MAP_ELEMENT, 'value' : 'map'},
-    const {'type': TokenKind.MENU_ELEMENT, 'value' : 'menu'},
-    const {'type': TokenKind.META_ELEMENT, 'value' : 'meta'},
-    const {'type': TokenKind.NOFRAMES_ELEMENT, 'value' : 'noframes'},
-    const {'type': TokenKind.NOSCRIPT_ELEMENT, 'value' : 'noscript'},
-    const {'type': TokenKind.OBJECT_ELEMENT, 'value' : 'object'},
-    const {'type': TokenKind.OL_ELEMENT, 'value' : 'ol'},
-    const {'type': TokenKind.OPTGROUP_ELEMENT, 'value' : 'optgroup'},
-    const {'type': TokenKind.OPTION_ELEMENT, 'value' : 'option'},
-    const {'type': TokenKind.P_ELEMENT, 'value' : 'p'},
-    const {'type': TokenKind.PARAM_ELEMENT, 'value' : 'param'},
-    const {'type': TokenKind.PRE_ELEMENT, 'value' : 'pre'},
-    const {'type': TokenKind.Q_ELEMENT, 'value' : 'q'},
-    const {'type': TokenKind.S_ELEMENT, 'value' : 's'},
-    const {'type': TokenKind.SAMP_ELEMENT, 'value' : 'samp'},
-    const {'type': TokenKind.SCRIPT_ELEMENT, 'value' : 'script'},
-    const {'type': TokenKind.SELECT_ELEMENT, 'value' : 'select'},
-    const {'type': TokenKind.SMALL_ELEMENT, 'value' : 'small'},
-    const {'type': TokenKind.SPAN_ELEMENT, 'value' : 'span'},
-    const {'type': TokenKind.STRIKE_ELEMENT, 'value' : 'strike'},
-    const {'type': TokenKind.STRONG_ELEMENT, 'value' : 'strong'},
-    const {'type': TokenKind.STYLE_ELEMENT, 'value' : 'style'},
-    const {'type': TokenKind.SUB_ELEMENT, 'value' : 'sub'},
-    const {'type': TokenKind.SUP_ELEMENT, 'value' : 'sup'},
-    const {'type': TokenKind.TABLE_ELEMENT, 'value' : 'table'},
-    const {'type': TokenKind.TBODY_ELEMENT, 'value' : 'tbody'},
-    const {'type': TokenKind.TD_ELEMENT, 'value' : 'td'},
-    const {'type': TokenKind.TEXTAREA_ELEMENT, 'value' : 'textarea'},
-    const {'type': TokenKind.TFOOT_ELEMENT, 'value' : 'tfoot'},
-    const {'type': TokenKind.TH_ELEMENT, 'value' : 'th'},
-    const {'type': TokenKind.THEAD_ELEMENT, 'value' : 'thead'},
-    const {'type': TokenKind.TITLE_ELEMENT, 'value' : 'title'},
-    const {'type': TokenKind.TR_ELEMENT, 'value' : 'tr'},
-    const {'type': TokenKind.TT_ELEMENT, 'value' : 'tt'},
-    const {'type': TokenKind.U_ELEMENT, 'value' : 'u'},
-    const {'type': TokenKind.UL_ELEMENT, 'value' : 'ul'},
-    const {'type': TokenKind.VAR_ELEMENT, 'value' : 'var'},
-  ];
-
-  // Some more constants:
-  static const int ASCII_UPPER_A = 65;    // ASCII value for uppercase A
-  static const int ASCII_UPPER_Z = 90;    // ASCII value for uppercase Z
-
-  List<int> tokens;
-
-  /*
-   * Return the token that matches the unit ident found.
-   */
-  static int matchList(var identList, String tokenField, String text,
-                       int offset, int length) {
-    for (final entry in identList) {
-      String ident = entry['value'];
-      if (length == ident.length) {
-        int idx = offset;
-        bool match = true;
-        for (int identIdx = 0; identIdx < ident.length; identIdx++) {
-          int identChar = ident.codeUnitAt(identIdx);
-          int char = text.codeUnitAt(idx++);
-          // Compare lowercase to lowercase then check if char is uppercase.
-          match = match && (char == identChar ||
-              ((char >= ASCII_UPPER_A && char <= ASCII_UPPER_Z) &&
-               (char + 32) == identChar));
-          if (!match) {
-            break;
-          }
-        }
-
-        if (match) {
-          // Completely matched; return the token for this unit.
-          return entry[tokenField];
-        }
-      }
-    }
-
-    return -1;  // Not a unit token.
-  }
-
-  /*
-   * Return the token that matches the element ident found.
-   */
-  static int matchElements(String text, int offset, int length) {
-    return matchList(_ELEMENTS, 'type', text, offset, length);
-  }
-
-  static String tagNameFromTokenId(int tagTokenId) {
-    if (TokenKind.validTagName(tagTokenId)) {
-      for (final tag in TokenKind._ELEMENTS) {
-        if (tag['type'] == tagTokenId) {
-          return tag['value'];
-        }
-      }
-    }
-  }
-
-  static bool unscopedTag(int tagTokenId) {
-    for (final tagId in TokenKind._NON_SCOPED_ELEMENTS) {
-      if (tagId == tagTokenId) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  static int matchKeywords(String text, int offset, int length) {
-    return matchList(_KEYWORDS, 'type', text, offset, length);
-  }
-
-  static String kindToString(int kind) {
-    switch(kind) {
-      case TokenKind.UNUSED: return "ERROR";
-      case TokenKind.END_OF_FILE: return "end of file";
-      case TokenKind.LPAREN: return "(";
-      case TokenKind.RPAREN: return ")";
-      case TokenKind.LBRACK: return "[";
-      case TokenKind.RBRACK: return "]";
-      case TokenKind.LBRACE: return "{";
-      case TokenKind.RBRACE: return "}";
-      case TokenKind.DOT: return ".";
-      case TokenKind.SEMICOLON: return ";";
-      case TokenKind.SPACE: return " ";
-      case TokenKind.TAB: return "\t";
-      case TokenKind.NEWLINE: return "\n";
-      case TokenKind.RETURN: return "\r";
-      case TokenKind.COMMA: return ",";
-      case TokenKind.LESS_THAN: return "<";
-      case TokenKind.GREATER_THAN: return ">";
-      case TokenKind.SLASH: return "/";
-      case TokenKind.DOLLAR: return "\$";
-      case TokenKind.HASH: return "#";
-      case TokenKind.MINUS: return '-';
-      case TokenKind.EQUAL: return '=';
-      case TokenKind.DOUBLE_QUOTE: return '"';
-      case TokenKind.SINGLE_QUOTE: return "'";
-      case TokenKind.ASTERISK: return "*";
-      case TokenKind.END_NO_SCOPE_TAG: return '/>';
-      case TokenKind.START_EXPRESSION: return '\${';
-      case TokenKind.START_COMMAND: return '\${#';
-      case TokenKind.END_COMMAND: return '\${/';
-      case TokenKind.EACH_COMMAND: return '\${#each list}';
-      case TokenKind.WITH_COMMAND: return '\${with object}';
-      case TokenKind.IF_COMMAND: return '\${#if (expression)}';
-      case TokenKind.ELSE_COMMAND: return '\${#end}';
-      case TokenKind.INTEGER: return 'integer';
-      case TokenKind.DOUBLE: return 'double';
-      case TokenKind.WHITESPACE: return 'whitespace';
-      case TokenKind.COMMENT: return 'comment';
-      case TokenKind.ERROR: return 'error';
-      case TokenKind.INCOMPLETE_STRING : return 'incomplete string';
-      case TokenKind.INCOMPLETE_COMMENT: return 'incomplete comment';
-      case TokenKind.ATTR_VALUE: return 'attribute value';
-      case TokenKind.NUMBER: return 'number';
-      case TokenKind.HEX_NUMBER: return 'hex number';
-      case TokenKind.HTML_COMMENT: return 'HTML comment <!-- -->';
-      case TokenKind.IDENTIFIER: return 'identifier';
-      case TokenKind.STRING: return 'string';
-      case TokenKind.STRING_PART: return 'string part';
-      case TokenKind.TEMPLATE_KEYWORD: return 'template';
-      default:
-        throw "Unknown TOKEN";
-    }
-  }
-
-  TokenKind() {
-    tokens = [];
-
-    // All tokens must be in TokenKind order.
-    tokens.add(-1);                 // TokenKind.UNUSED
-    tokens.add(0);                  // TokenKind.END_OF_FILE match base
-    tokens.add(TokenKind.kindToString(TokenKind.LPAREN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RPAREN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.LBRACK).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RBRACK).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.LBRACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RBRACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.DOT).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SEMICOLON).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SPACE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.TAB).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.NEWLINE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.RETURN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.COMMA).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.LESS_THAN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.GREATER_THAN).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SLASH).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.DOLLAR).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.HASH).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.MINUS).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.EQUAL).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.DOUBLE_QUOTE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.SINGLE_QUOTE).codeUnitAt(0));
-    tokens.add(TokenKind.kindToString(TokenKind.ASTERISK).codeUnitAt(0));
-
-    assert(tokens.length == TokenKind.END_TOKENS);
-  }
-
-  static bool isIdentifier(int kind) {
-    return kind == IDENTIFIER;
-  }
-}
-
-class NoElementMatchException implements Exception {
-  String _tagName;
-  NoElementMatchException(this._tagName);
-
-  String get name => _tagName;
-}
diff --git a/utils/template/tool.dart b/utils/template/tool.dart
deleted file mode 100644
index 8b075ee..0000000
--- a/utils/template/tool.dart
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library templatetool;
-
-import 'dart:io';
-import 'template.dart';
-import '../lib/file_system.dart';
-import '../lib/file_system_vm.dart';
-
-
-FileSystem files;
-
-/** Invokes [callback] and returns how long it took to execute in ms. */
-num time(callback()) {
-  final watch = new Stopwatch();
-  watch.start();
-  callback();
-  watch.stop();
-  return watch.elapsedMilliseconds;
-}
-
-String GREEN_COLOR = '\u001b[32m';
-String NO_COLOR = '\u001b[0m';
-
-printStats(String phase, num elapsed, [String filename = '']) {
-  print('${phase} ${GREEN_COLOR}${filename}${NO_COLOR} in ${elapsed} msec.');
-}
-
-/**
- * Run from the `utils/css` directory.
- */
-void main(List<String> optionArgs) {
-  // argument 0 - sourcefile full path
-  // argument 1 - outputfile full path
-  String sourceFullFn = optionArgs[0];
-  String outputFullFn = optionArgs[1];
-
-  String sourcePath;
-  String sourceFilename;
-  int idxBeforeFilename = sourceFullFn.lastIndexOf('/');
-  if (idxBeforeFilename >= 0) {
-    sourcePath = sourceFullFn.substring(0, idxBeforeFilename + 1);
-    sourceFilename = sourceFullFn.substring(idxBeforeFilename + 1);
-  }
-
-  String outPath;
-  String outFilename;
-  idxBeforeFilename = outputFullFn.lastIndexOf('/');
-  if (idxBeforeFilename >= 0) {
-    outPath = outputFullFn.substring(0, idxBeforeFilename + 1);
-    outFilename = outputFullFn.substring(idxBeforeFilename + 1);
-  }
-
-  if (sourceFilename.length == 0 || outFilename.length == 0) {
-    print("Unknown command:\r");
-    print("    Format: sourcefile outputfile [--options]");
-    print("      outputfile - template file filename.tmpl");
-    print("      outputfile - generated dart source file filename.dart");
-    return;
-  }
-
-//  files = new NodeFileSystem();
-  files = new VMFileSystem();
-
-  // TODO(terry): Cleanup options handling need common options between template
-  //              and CSS parsers also cleanup above cruft.
-
-  // TODO(terry): Pass on switches.
-  var args = [];
-  parseOptions(args, files);
-
-  initHtmlWorld(false);
-
-  if (!files.fileExists(sourceFullFn)) {
-    // Display colored error message if file is missing.
-    print(world.fatal("CSS source file missing - ${sourceFullFn}"));
-  } else {
-
-    String source = files.readAll(sourceFullFn);
-
-    List<Template> templates;
-    final parsedElapsed = time(() {
-      templates = templateParseAndValidate(source);
-    });
-
-    StringBuffer code = new StringBuffer();
-
-    num codegenElapsed;
-    if (world.errors == 0) {
-      // Generate the Dart class(es) for all template(s).
-      codegenElapsed = time(() {
-        code.write(Codegen.generate(templates, outFilename));
-      });
-    }
-
-    printStats("Parsed", parsedElapsed, sourceFullFn);
-    printStats("Codegen", codegenElapsed, sourceFullFn);
-
-    final outputElapsed = time(() {
-      files.writeString(outputFullFn, code.toString());
-    });
-
-    printStats("Wrote file", codegenElapsed, outputFullFn);
-  }
-}
diff --git a/utils/template/tree.dart b/utils/template/tree.dart
deleted file mode 100644
index 6fd1cf0..0000000
--- a/utils/template/tree.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-/**
- * The base type for all nodes in a dart abstract syntax tree.
- */
-class ASTNode {
-  /** The source code this [ASTNode] represents. */
-  SourceSpan span;
-
-  ASTNode(this.span) {}
-
-  /** Classic double-dispatch visitor for implementing passes. */
-  abstract visit(TreeVisitor visitor);
-
-  /** A multiline string showing the node and its children. */
-  String toDebugString() {
-    var to = new TreeOutput();
-    var tp = new TreePrinter(to);
-    this.visit(tp);
-    return to.buf.toString();
-  }
-}
-
-// TODO(jimhug): Clean-up and factor out of core.
-/** Simple class to provide a textual dump of trees for debugging. */
-class TreeOutput {
-  int depth;
-  StringBuffer buf;
-
-  var printer;
-
-  static void dump(ASTNode node) {
-    var o = new TreeOutput();
-    node.visit(new TreePrinter(o));
-    print(o.buf);
-  }
-
-  TreeOutput(): this.depth = 0, this.buf = new StringBuffer() {
-  }
-
-  void write(String s) {
-    for (int i=0; i < depth; i++) {
-      buf.write(' ');
-    }
-    buf.write(s);
-  }
-
-  void writeln(String s) {
-    buf.writeln(s);
-  }
-
-  void heading(String name, span) {
-    write(name);
-    buf.writeln('  (${span.locationText})');
-  }
-
-  String toValue(value) {
-    if (value == null) return 'null';
-    else if (value is Identifier) return value.name;
-    else return value.toString();
-  }
-
-  void writeNode(String label, ASTNode node) {
-    write(label + ': ');
-    depth += 1;
-    if (node != null) node.visit(printer);
-    else writeln('null');
-    depth -= 1;
-  }
-
-  void writeValue(String label, value) {
-    var v = toValue(value);
-    writeln('${label}: ${v}');
-  }
-
-  void writeList(String label, List list) {
-    write(label + ': ');
-    if (list == null) {
-      buf.writeln('null');
-    } else {
-      for (var item in list) {
-        buf.write(item.toString());
-        buf.write(', ');
-      }
-      buf.write('\n');
-    }
-  }
-
-  void writeNodeList(String label, List list) {
-    writeln('${label} [');
-    if (list != null) {
-      depth += 1;
-      for (var node in list) {
-        if (node != null) {
-          node.visit(printer);
-        } else {
-          writeln('null');
-        }
-      }
-      depth -= 1;
-      writeln(']');
-    }
-  }
-}
diff --git a/utils/template/uitest.dart b/utils/template/uitest.dart
deleted file mode 100644
index 7aed1ff..0000000
--- a/utils/template/uitest.dart
+++ /dev/null
@@ -1,573 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'template.dart';
-import '../lib/file_system_memory.dart';
-
-String currSampleTemplate;
-
-void changeTemplate() {
-  final Document doc = window.document;
-  final SelectElement samples = doc.query('#templateSamples');
-  final TextAreaElement template = doc.query('#template');
-  template.value = sample(samples.value);
-}
-
-String sample(String sampleName) {
-  final String each = '\${#each';
-  final String endEach = '\${/each}';
-  final String with = '\${#with';
-  final String endWith = '\${/with}';
-
-  final String simpleTemplate = r'''
-template NameEntry(String name, int age) {
-  <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span>-</span>
-    <span>${age}</span>
-  </div>
-}
-  ''';
-
-  final String simpleTemplate2 = r'''
-template NameEntry(String name, int age) {
-  <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <h1>
-      <h2>
-        <h3>
-          <span var=spanElem>${name}</span>
-          <span>-</span>
-          <span>${age}</span>
-        </h3>
-      </h2>
-    </h1>
-  </div>
-}
-  ''';
-
-  final String simpleTemplateCSS = r'''
-template NameEntry(String name, int age) {
-  css {
-    .foo {
-      left: 10px;
-    }
-  }
-  <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span>-</span>
-    <span>${age}</span>
-  </div>
-}
-  ''';
-
-
-  final String eachTemplate = r'''
-template Applications(var products) {
-  <div>
-    ${each} products
-      <div>
-        <span>${name}</span>
-        <span>-</span>
-        <span>${users}</span>
-      </div>
-    ${endEach}
-  </div>
-}
-  ''';
-
-  final String withTemplate = r'''
-template Product(Person person) {
-  <div>
-    ${with} person
-      <div>
-        <span>${name}</span>
-        <span>-</span>
-        <span>${age}</span>
-      </div>
-    ${endWith}
-  </div>
-}
-  ''';
-
-  final String withTemplate2 = r'''
-template Product(Person person) {
-  <div>
-    <span var=a1>
-      <h1>
-        ${with} person
-          <div>
-            <span>${name}</span>
-            <span>-</span>
-            <span>${age}</span>
-          </div>
-        ${endWith}
-      </h1>
-    </span>
-  </div>
-}
-  ''';
-
-  final String complexTemplate = r'''
-template ProductsForPerson(Person person, var products) {
-  <div>
-    ${with} person person
-      <div>
-        <span>${person.name}</span>
-        <span>-</span>
-        <span>${person.age}</span>
-      </div>
-      ${each} products product
-        <div>
-          <span>product=${product.name},users=${product.users}</span>
-        </div>
-      ${endEach}
-    ${endWith}
-  </div>
-}
-  ''';
-
-  final String complexTemplate2 = r'''
-template ProductsForPerson(Person person, var products) {
-  <div>
-    ${with} person person
-      <div>
-        <span>${person.name}</span>
-        <span>-</span>
-        <span>${person.age}</span>
-      </div>
-      <div>
-        ${each} products product
-          <span>product=${product.name},users=${product.users}</span>
-        ${endEach}
-      </div>
-    ${endWith}
-  </div>
-}
-  ''';
-
-  final String complexTemplate3 = r'''
-template ProductsForPerson(Person person, var products) {
-  css {
-    .sales-item {
-      font-family: arial;
-      background-color: lightgray;
-      margin-left: 10px;
-      border-bottom: 1px solid white;
-    }
-    .ytd-sales {
-      position: absolute;
-      left: 100px;
-    }
-  }
-  <div>
-    ${with} person person
-      <div>
-        <span>${person.name}</span>
-        <span>-</span>
-        <span>${person.age}</span>
-      </div>
-      <div>
-        ${each} products product
-          <div>product=${product.name},users=${product.users}</div>
-          ${each} products.sales sale
-            <div class="sales-item">
-              <span>${sale.country}</span>
-              <span class="ytd-sales">\$${sale.yearly}</span>
-            </div>
-          ${endEach}
-        ${endEach}
-      </div>
-    ${endWith}
-  </div>
-}
-
-
-template NameEntry(String name, int age) {
-  css {
-    .name-item {
-      font-size: 18pt;
-      font-weight: bold;
-    }
-  }
-  <div var=topDiv class="name-item" attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span> - </span>
-    <span>${age}</span>
-  </div>
-}
-''';
-
-  // Test #each in a #each where the nested #each is a top-level child of the
-  // outer #each.
-  final String complexTemplate4 = r'''
-template DivisionSales(var divisions) {
-  <div>
-    ${each} divisions division
-      <div>
-        <span>${division.name}</span>
-        <span>-</span>
-        <span>${division.id}</span>
-      </div>
-      <div>
-        ${each} divisions.products divProduct
-          <div>
-            <span var=productItem>&#9654;</span>
-            <span>Product</span>
-            <span>${divProduct.name}</span>
-            <span>${divProduct.users}&nbsp;users</span>
-          </div>
-          ${each} products.sales sale
-            <div>
-              <span>${sale.country}</span>
-              <span>\$${sale.yearly}</span>
-            </div>
-          ${endEach}
-        ${endEach}
-      </div>
-    ${endEach}
-  </div>
-}
-''';
-
-
-  final String realWorldList = r'''
-template DivisionSales(var divisions) {
-  css {
-    .division-item {
-      background-color: #bbb;
-      border-top: 2px solid white;
-      line-height: 20pt;
-      padding-left: 5px;
-    }
-    .product-item {
-      background-color: lightgray;
-      margin-left: 10px;
-      border-top: 2px solid white;
-      line-height: 20pt;
-    }
-    .product-title {
-      position: absolute;
-      left: 45px;
-    }
-    .product-name {
-      font-weight: bold;
-      position: absolute;
-      left: 100px;
-    }
-    .product-users {
-      position: absolute;
-      left: 150px;
-      font-style: italic;
-      color: gray;
-      width: 110px;
-    }
-    .expand-collapse {
-      margin-left: 5px;
-      margin-right: 5px;
-      vertical-align: top;
-      cursor: pointer;
-    }
-    .expand {
-      font-size: 9pt;
-    }
-    .collapse {
-      font-size: 8pt;
-    }
-    .show-sales {
-      display: inherit;
-    }
-    .hide-sales {
-      display: none;
-    }
-    .sales-item {
-      font-family: arial;
-      background-color: lightgray;
-      margin-left: 10px;
-      border-top: 1px solid white;
-      line-height: 18pt;
-      padding-left: 5px;
-    }
-    .ytd-sales {
-      position: absolute;
-      left: 100px;
-    }
-  }
-  <div>
-    ${each} divisions division
-      <div class="division-item">
-        <span>${division.name}</span>
-        <span>-</span>
-        <span>${division.id}</span>
-      </div>
-      <div>
-        ${each} divisions.products divProduct
-          <div class="product-item">
-            <span var=productZippy class="expand-collapse expand">&#9660;</span>
-            <span class='product-title'>Product</span>
-            <span class="product-name">${divProduct.name}</span>
-            <span class="product-users" align=right>${divProduct.users
-              }&nbsp;users</span>
-            <div class="show-sales">
-              ${each} products.sales sale
-                <div class="sales-item">
-                  <span>${sale.country}</span>
-                  <span class="ytd-sales">\$${sale.yearly}</span>
-                </div>
-              ${endEach}
-            </div>
-          </div>
-        ${endEach}
-      </div>
-    ${endEach}
-  </div>
-}
-
-template Header(String company, DateTime date) {
-  css {
-    .header {
-      background-color: slateGray;
-      font-family: arial;
-      color: lightgray;
-      font-weight: bold;
-      padding-top: 20px;
-    }
-  }
-  <div class='header' align=center>
-    <h2>${company}</h2>
-    <div align=right>${date}</div>
-  </div>
-}
-''';
-
-  switch (sampleName) {
-    case "simple":
-      return simpleTemplate;
-    case "simple2":
-      return simpleTemplate2;
-    case "simpleCSS":
-      return simpleTemplateCSS;
-    case "with":
-      return withTemplate;
-    case "with2":
-      return withTemplate2;
-    case "list":
-      return eachTemplate;
-    case "complex":
-      return complexTemplate;
-    case "complex2":
-      return complexTemplate2;
-    case "complex3":
-      return complexTemplate3;
-    case "complex4":
-      return complexTemplate4;
-    case "realWorldList":
-      return realWorldList;
-    default:
-      print("ERROR: Unknown sample template");
-  }
-}
-
-void runTemplate([bool debug = false, bool parseOnly = false]) {
-  final Document doc = window.document;
-  final TextAreaElement dartClass = doc.query("#dart");
-  final TextAreaElement template = doc.query('#template');
-  final TableCellElement validity = doc.query('#validity');
-  final TableCellElement result = doc.query('#result');
-
-  bool templateValid = true;
-  StringBuffer dumpTree = new StringBuffer();
-  StringBuffer code = new StringBuffer();
-  String htmlTemplate = template.value;
-
-  if (debug) {
-    try {
-      List<Template> templates = templateParseAndValidate(htmlTemplate);
-      for (var tmpl in templates) {
-        dumpTree.write(tmpl.toDebugString());
-      }
-
-      // Generate the Dart class(es) for all template(s).
-      // Pass in filename of 'foo' for testing in UITest.
-      code.write(Codegen.generate(templates, 'foo'));
-    } catch (htmlException) {
-      // TODO(terry): TBD
-      print("ERROR unhandled EXCEPTION");
-    }
-  }
-
-/*
-  if (!debug) {
-    try {
-      cssParseAndValidate(cssExpr, cssWorld);
-    } catch (cssException) {
-      templateValid = false;
-      dumpTree = cssException.toString();
-    }
-  } else if (parseOnly) {
-    try {
-      Parser parser = new Parser(new lang.SourceFile(
-          lang.SourceFile.IN_MEMORY_FILE, cssExpr));
-      Stylesheet stylesheet = parser.parse();
-      StringBuffer stylesheetTree = new StringBuffer();
-      String prettyStylesheet = stylesheet.toString();
-      stylesheetTree.add("${prettyStylesheet}\n");
-      stylesheetTree.add("\n============>Tree Dump<============\n");
-      stylesheetTree.add(stylesheet.toDebugString());
-      dumpTree = stylesheetTree.toString();
-    } catch (cssParseException) {
-      templateValid = false;
-      dumpTree = cssParseException.toString();
-    }
-  } else {
-    try {
-      dumpTree = cssParseAndValidateDebug(cssExpr, cssWorld);
-    } catch (cssException) {
-      templateValid = false;
-      dumpTree = cssException.toString();
-    }
-  }
-*/
-
-  final bgcolor = templateValid ? "white" : "red";
-  final color = templateValid ? "black" : "white";
-  final valid = templateValid ? "VALID" : "NOT VALID";
-  String resultStyle = "resize: none; margin: 0; height: 100%; width: 100%;"
-    "padding: 5px 7px;";
-
-  result.innerHTML = '''
-    <textarea style="${resultStyle}">${dumpTree.toString()}</textarea>
-  ''';
-
-  dartClass.value = code.toString();
-}
-
-void main() {
-  final element = new Element.tag('div');
-
-  element.innerHTML = '''
-    <table style="width: 100%; height: 100%;">
-      <tbody>
-        <tr>
-          <td style="vertical-align: top; width: 50%; padding-right: 7px;">
-            <table style="height: 100%; width: 100%;" cellspacing=0 cellpadding=0 border=0>
-              <tbody>
-                <tr style="vertical-align: top; height: 1em;">
-                  <td>
-                    <span style="font-weight:bold;">Generated Dart</span>
-                  </td>
-                </tr>
-                <tr>
-                  <td>
-                    <textarea id="dart" style="resize: none; width: 100%; height: 100%; padding: 5px 7px;"></textarea>
-                  </td>
-                </tr>
-              </tbody>
-            </table>
-          </td>
-          <td>
-            <table style="width: 100%; height: 100%;" cellspacing=0 cellpadding=0 border=0>
-              <tbody>
-                <tr style="vertical-align: top; height: 50%;">
-                  <td>
-                    <table style="width: 100%; height: 100%;" cellspacing=0 cellpadding=0 border=0>
-                      <tbody>
-                        <tr>
-                          <td>
-                            <span style="font-weight:bold;">HTML Template</span>
-                          </td>
-                        </tr>
-                        <tr style="height: 100%;">
-                          <td>
-                            <textarea id="template" style="resize: none; width: 100%; height: 100%; padding: 5px 7px;">${sample("simple")}</textarea>
-                          </td>
-                        </tr>
-                      </tbody>
-                    </table>
-                  </td>
-                </tr>
-
-                <tr style="vertical-align: top; height: 50px;">
-                  <td>
-                    <table>
-                      <tbody>
-                        <tr>
-                          <td>
-                            <button id=generate>Generate</button>
-                          </td>
-                          <td align="right">
-                            <select id=templateSamples>
-                              <option value="simple">Simple Template</option>
-                              <option value="simple2">Simple Template #2</option>
-                              <option value="simpleCSS">Simple Template w/ CSS</option>
-                              <option value="with">With Template</option>
-                              <option value="with2">With Template #2</option>
-                              <option value="list">List Template</option>
-                              <option value="complex">Complex Template</option>
-                              <option value="complex2">Complex Template #2</option>
-                              <option value="complex3">Complex Template #3 w/ CSS</option>
-                              <option value="complex4">Complex Template #4</option>
-                              <option value="realWorldList">Real world</option>
-                            </select>
-                          </td>
-                        </tr>
-                      </tbody>
-                    </table>
-                  </td>
-                </tr>
-
-                <tr style="vertical-align: top;">
-                  <td>
-                    <table style="width: 100%; height: 100%;" border="0" cellpadding="0" cellspacing="0">
-                      <tbody>
-                        <tr style="vertical-align: top; height: 1em;">
-                          <td>
-                            <span style="font-weight:bold;">Parse Tree</span>
-                          </td>
-                        </tr>
-                        <tr style="vertical-align: top; height: 1em;">
-                          <td id="validity">
-                          </td>
-                        </tr>
-                        <tr>
-                          <td id="result">
-                            <textarea style="resize: none; width: 100%; height: 100%; border: black solid 1px; padding: 5px 7px;"></textarea>
-                          </td>
-                        </tr>
-                      </tbody>
-                    </table>
-                  </td>
-                </tr>
-              </tbody>
-            </table>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-  ''';
-
-  document.body.style.setProperty("background-color", "lightgray");
-  document.body.elements.add(element);
-
-  ButtonElement genElem = window.document.query('#generate');
-  genElem.on.click.add((MouseEvent e) {
-    runTemplate(true, true);
-  });
-
-  SelectElement cannedTemplates = window.document.query('#templateSamples');
-  cannedTemplates.on.change.add((e) {
-    changeTemplate();
-  });
-
-  parseOptions([], null);
-  initHtmlWorld(false);
-
-  // Don't display any colors in the UI.
-  options.useColors = false;
-
-  // Replace error handler bring up alert for any problems.
-  world.printHandler = (String msg) {
-    window.alert(msg);
-  };
-}
diff --git a/utils/template/utils.dart b/utils/template/utils.dart
deleted file mode 100644
index ca36fc6..0000000
--- a/utils/template/utils.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Collection<T> supports most of the ES 5 Array methods, but it's missing
-// map and reduce.
-
-// TODO(jmesserly): we might want a version of this that return an iterable,
-// however JS, Python and Ruby versions are all eager.
-List map(Iterable source, mapper(source)) {
-  List result = new List();
-  if (source is List) {
-    List list = source; // TODO: shouldn't need this
-    result.length = list.length;
-    for (int i = 0; i < list.length; i++) {
-      result[i] = mapper(list[i]);
-    }
-  } else {
-    for (final item in source) {
-      result.add(mapper(item));
-    }
-  }
-  return result;
-}
-
-reduce(Iterable source, callback, [initialValue]) {
-  final i = source.iterator;
-
-  var current = initialValue;
-  if (current == null && i.moveNext()) {
-    current = i.current;
-  }
-  while (i.moveNext()) {
-    current = callback(current, i.current);
-  }
-  return current;
-}
-
-List zip(Iterable left, Iterable right, mapper(left, right)) {
-  List result = new List();
-  var x = left.iterator;
-  var y = right.iterator;
-  while (x.moveNext()) {
-    if (!y.moveNext()) {
-      throw new ArgumentError();
-    }
-    result.add(mapper(x.current, y.current));
-  }
-  if (y.moveNext()) {
-    throw new ArgumentError();
-  }
-  return result;
-}
-
-
diff --git a/utils/template/world.dart b/utils/template/world.dart
deleted file mode 100644
index d11c008..0000000
--- a/utils/template/world.dart
+++ /dev/null
@@ -1,169 +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.
-
-/** The one true [World]. */
-World world;
-
-typedef void MessageHandler(String prefix, String message, SourceSpan span);
-typedef void PrintHandler(String message);
-
-/**
- * Should be called exactly once to setup singleton world.
- * Can use world.reset() to reinitialize.
- */
-void initializeWorld(var files) {
-  assert(world == null);
-  world = new World(files);
-  world.init();
-}
-
-/** Can be thrown on any compiler error and includes source location. */
-class CompilerException implements Exception {
-  final String _message;
-  final SourceSpan _location;
-
-  CompilerException(this._message, this._location);
-
-  String toString() {
-    if (_location != null) {
-      return 'CompilerException: ${_location.toMessageString(_message)}';
-    } else {
-      return 'CompilerException: $_message';
-    }
-  }
-}
-
-/** Represents a Dart template "world". */
-class World {
-  String template;
-
-  var files;
-
-  int errors = 0, warnings = 0;
-  bool seenFatal = false;
-  MessageHandler messageHandler;
-  PrintHandler printHandler;
-
-  World(this.files);
-
-  void reset() {
-    errors = warnings = 0;
-    seenFatal = false;
-    init();
-  }
-
-  init() {
-  }
-
-
-  // ********************** Message support ***********************
-
-  void _message(String color, String prefix, String message,
-      SourceSpan span, SourceSpan span1, SourceSpan span2, bool throwing) {
-    if (messageHandler != null) {
-      // TODO(jimhug): Multiple spans cleaner...
-      messageHandler(prefix, message, span);
-      if (span1 != null) {
-        messageHandler(prefix, message, span1);
-      }
-      if (span2 != null) {
-        messageHandler(prefix, message, span2);
-      }
-    } else {
-      final messageWithPrefix = options.useColors
-          ? "$color$prefix$_NO_COLOR$message" : "$prefix$message";
-
-      var text = messageWithPrefix;
-      if (span != null) {
-        text = span.toMessageString(messageWithPrefix);
-      }
-
-      String span1Text = span1 != null ?
-          span1.toMessageString(messageWithPrefix) : "";
-      String span2Text = span2 != null ?
-          span2.toMessageString(messageWithPrefix) : "";
-
-      if (printHandler == null) {
-        print(text);
-        if (span1 != null) {
-          print(span1Text);
-        }
-        if (span2 != null) {
-          print(span2Text);
-        }
-      } else {
-        printHandler("${text}\r${span1Text}\r${span2Text}");
-      }
-    }
-
-    if (throwing) {
-      throw new CompilerException("$prefix$message", span);
-    }
-  }
-
-  /** [message] is considered a static compile-time error by the Dart lang. */
-  void error(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    errors++;
-    _message(_RED_COLOR, 'error: ', message,
-        span, span1, span2, options.throwOnErrors);
-  }
-
-  /** [message] is considered a type warning by the Dart lang. */
-  void warning(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    if (options.warningsAsErrors) {
-      error(message, span, span1, span2);
-      return;
-    }
-    warnings++;
-    if (options.showWarnings) {
-      _message(_MAGENTA_COLOR, 'warning: ', message,
-          span, span1, span2, options.throwOnWarnings);
-    }
-  }
-
-  /** [message] at [location] is so bad we can't generate runnable code. */
-  void fatal(String message,
-      {SourceSpan span, SourceSpan span1, SourceSpan span2}) {
-    errors++;
-    seenFatal = true;
-    _message(_RED_COLOR, 'fatal: ', message,
-        span, span1, span2, options.throwOnFatal || options.throwOnErrors);
-  }
-
-  /** [message] at [location] is about a bug in the compiler. */
-  void internalError(String message,
-      {SourceSpan span, SourceSpan span1, SourceSpan span2}) {
-    _message(_NO_COLOR,
-        'We are sorry, but...', message, span, span1, span2, true);
-  }
-
-  /**
-   * [message] at [location] will tell the user about what the compiler
-   * is doing.
-   */
-  void info(String message,
-      [SourceSpan span, SourceSpan span1, SourceSpan span2]) {
-    if (options.showInfo) {
-      _message(_GREEN_COLOR, 'info: ', message, span, span1, span2, false);
-    }
-  }
-
-  bool get hasErrors => errors > 0;
-
-  withTiming(String name, f()) {
-    final sw = new Stopwatch();
-    sw.start();
-    var result = f();
-    sw.stop();
-    info('$name in ${sw.elapsedMilliseconds}msec');
-    return result;
-  }
-}
-
-String _GREEN_COLOR = '\u001b[32m';
-String _RED_COLOR = '\u001b[31m';
-String _MAGENTA_COLOR = '\u001b[35m';
-String _NO_COLOR = '\u001b[0m';
diff --git a/utils/tests/css/css.status b/utils/tests/css/css.status
deleted file mode 100644
index 6b7ba1c..0000000
--- a/utils/tests/css/css.status
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[$runtime == opera]
-*: Skip
-
-[ $arch == x64 ]
-*: Skip
-
-[ $arch == arm ]
-*: Skip
-
-[ $arch == simarm ]
-*: Skip
-
-[ $arch == mips ]
-*: Skip
-
-[ $arch == simmips ]
-*: Skip
diff --git a/utils/tests/css/declaration_test.dart b/utils/tests/css/declaration_test.dart
deleted file mode 100644
index e0aea84..0000000
--- a/utils/tests/css/declaration_test.dart
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library declaration_tests;
-import '../../css/css.dart';
-
-void main() {
-  initCssWorld();
-
-  testSimpleTerms();
-  testMoreDecls();
-  testIdentifiers();
-  testComposites();
-  testNewerCss();
-  testCssFile();
-}
-
-void testSimpleTerms() {
-  final String input =
-    ".foo {\n" +
-    "  background-color: #191919;\n" +
-    "  width: 10PX;\n" +
-    "  height: 22mM !important;\n" +
-    "  border-width: 20cm;\n" +
-    "  margin-width: 33%;\n" +
-    "  border-height: 30EM;\n" +
-    "  width: .6in;\n" +
-    "  length: 1.2in;\n" +
-    "  -web-stuff: -10Px;\n" +
-    "}\n";
-  final String generated =
-    "\n" +
-    ".foo {\n" +
-    "  background-color: #191919;\n" +
-    "  width: 10px;\n" +
-    "  height: 22mm !important;\n" +
-    "  border-width: 20cm;\n" +
-    "  margin-width: 33%;\n" +
-    "  border-height: 30em;\n" +
-    "  width: .6in;\n" +          // Check double values.
-    "  length: 1.2in;\n" +
-    "  -web-stuff: -10px;\n" +
-    "}\n";
-
-  Parser parser =
-      new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE, input));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(generated, stylesheet.toString());
-}
-
-void testMoreDecls() {
-  final String input =
-    ".more {\n" +
-      "  color: red;\n" +
-      "  color: #aabbcc;  /* test -- 3 */\n" +
-      "  color: blue;\n" +
-      "  background-image: url(http://test.jpeg);\n" +
-      "  background-image: url(\"http://double_quote.html\");\n" +
-      "  background-image: url('http://single_quote.html');\n" +
-      "  color: rgba(10,20,255);  <!-- test CDO/CDC  -->\n" +
-      "  color: #123aef;   /* hex # part integer and part identifier */\n" +
-      "}\n";
-  final String generated =
-    "\n" +
-    ".more {\n" +
-      "  color: #ff0000;\n" +
-      "  color: #aabbcc;\n" +
-      "  color: #0ff;\n" +
-      "  background-image: url(http://test.jpeg);\n" +
-      "  background-image: url(http://double_quote.html);\n" +
-      "  background-image: url(http://single_quote.html);\n" +
-      "  color: rgba(10, 20, 255);\n" +
-      "  color: #123aef;\n" +
-      "}\n";
-
-  Parser parser =
-    new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE, input));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(generated, stylesheet.toString());
-}
-
-void testIdentifiers() {
-  final String input =
-    // Make sure identifiers that could look like hex are handled.
-    "#da {\n" +
-    "  height: 100px;\n" +
-    "}\n" +
-    // Make sure elements that contain a leading dash (negative) are valid.
-    "#-foo {\n" +
-    "  width: 10px;\n" +
-    "  color: #ff00cc;\n" +
-    "}\n";
-  final String generated =
-    "\n" +
-    "#da {\n" +
-    "  height: 100px;\n" +
-    "}\n" +
-    "\n" +
-    "#-foo {\n" +
-    "  width: 10px;\n" +
-    "  color: #ff00cc;\n" +
-    "}\n";
-
-  Parser parser =
-    new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE, input));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(generated, stylesheet.toString());
-}
-
-void testComposites() {
-  final String input =
-    // Composites
-    ".xyzzy {\n" +
-    "  border: 10px 80px 90px 100px;\n" +
-    "  width: 99%;\n" +
-    "}\n" +
-    "@-webkit-keyframes pulsate {\n" +
-    "  0% {\n" +
-    "    -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n" +
-    "  }\n" +
-    "}\n";
-  final String generated =
-    "\n" +
-    ".xyzzy {\n" +
-    "  border: 10px 80px 90px 100px;\n" +
-    "  width: 99%;\n" +
-    "}\n" +
-    "@-webkit-keyframes pulsate {\n" +
-    "  0% {\n" +
-    "  -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n" +
-    "  }\n" +
-    "}\n";
-  Parser parser =
-    new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE, input));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(generated, stylesheet.toString());
-}
-
-void testNewerCss() {
-  final String input =
-    // Newer things in CSS
-    "@media screen,print {\n" +
-    "  .foobar_screen {\n" +
-    "    width: 10px;\n" +
-    "  }\n" +
-    "}\n" +
-    "@page : test {\n" +
-    "  width: 10px;\n" +
-    "}\n" +
-    "@page {\n" +
-    "  height: 22px;\n" +
-    "}\n";
-  final String generated =
-    "@media screen,print {\n" +
-    "\n" +
-    ".foobar_screen {\n" +
-    "  width: 10px;\n" +
-    "}\n" +
-    "\n" +
-    "}\n" +
-    "@page : test {\n" +
-    "  width: 10px;\n" +
-    "\n" +
-    "}\n" +
-    "@page {\n" +
-    "  height: 22px;\n" +
-    "\n" +
-    "}\n";
-
-  Parser parser =
-    new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE, input));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(generated, stylesheet.toString());
-}
-
-void testCssFile() {
-  final String scss =
-    "@import 'simple.css'\n" +
-    "@import \"test.css\" print\n" +
-    "@import url(test.css) screen, print\n" +
-
-    "div[href^='test'] {\n" +
-    "  height: 10px;\n" +
-    "}\n" +
-
-    "@-webkit-keyframes pulsate {\n" +
-    "  from {\n" +
-    "    -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n" +
-    "  }\n" +
-    "  10% {\n" +
-    "    -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n" +
-    "  }\n" +
-    "  30% {\n" +
-    "    -webkit-transform: translate3d(0, 2, 0) scale(1.0);\n" +
-    "  }\n" +
-    "}\n" +
-
-    ".foobar {\n" +
-    "    grid-columns: 10px (\"content\" 1fr 10px)[4];\n" +
-    "}\n";
-
-  final String generated =
-    "@import url(simple.css)\n" +
-    "@import url(test.css) print\n" +
-    "@import url(test.css) screen,print\n" +
-    "\n" +
-    "div[href ^= \"test\"] {\n" +
-    "  height: 10px;\n" +
-    "}\n" +
-    "@-webkit-keyframes pulsate {\n" +
-    "  from {\n" +
-    "  -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n" +
-    "  }\n" +
-    "  10% {\n" +
-    "  -webkit-transform: translate3d(0, 0, 0) scale(1.0);\n" +
-    "  }\n" +
-    "  30% {\n" +
-    "  -webkit-transform: translate3d(0, 2, 0) scale(1.0);\n" +
-    "  }\n" +
-    "}\n" +
-    "\n" +
-    ".foobar {\n" +
-    "  grid-columns: 10px (\"content\" 1fr 10px) [4];\n" +
-    "}\n";
-
-  Parser parser =
-    new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE, scss));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(generated, stylesheet.toString());
-}
diff --git a/utils/tests/css/expression_test.dart b/utils/tests/css/expression_test.dart
deleted file mode 100644
index 95c79e0..0000000
--- a/utils/tests/css/expression_test.dart
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library expression_tests;
-import '../../css/css.dart';
-
-main() {
-  initCssWorld();
-
-  testClass();
-  testId();
-  testElement();
-  testNamespace();
-  testSelectorGroups();
-  testCombinator();
-  testWildcard();
-  testPseudo();
-  testAttribute();
-  testNegation();
-}
-
-void testClass() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE, ".foobar {}"));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  List<SimpleSelectorSequence> simpleSeqs =
-      ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-  Expect.equals(simpleSeqs.length, 1);
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    Expect.isTrue(simpSelector is ClassSelector);
-    Expect.isTrue(selector.isCombinatorNone());
-    Expect.equals(simpSelector.name, "foobar");
-  }
-
-  parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      ".foobar .bar .no-story {}"));
-
-  stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  var idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals(simpSelector.name, "foobar");
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "bar");
-    } else if (idx == 2) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "no-story");
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-
-  Expect.equals(simpleSeqs.length, idx);
-}
-
-void testId() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE, "#elemId {}"));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  List<SimpleSelectorSequence> simpleSeqs =
-      ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    Expect.isTrue(simpSelector is IdSelector);
-    Expect.isTrue(selector.isCombinatorNone());
-    Expect.equals(simpSelector.name, "elemId");
-  }
-}
-
-void testElement() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE, "div {}"));
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  List<SimpleSelectorSequence> simpleSeqs =
-      ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    Expect.isTrue(simpSelector is ElementSelector);
-    Expect.isTrue(selector.isCombinatorNone());
-    Expect.equals(simpSelector.name, "div");
-  }
-
-  parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      "div div span {}"));
-  stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  var idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is ElementSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals(simpSelector.name, "div");
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ElementSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "div");
-    } else if (idx == 2) {
-      Expect.isTrue(simpSelector is ElementSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "span");
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-  Expect.equals(simpleSeqs.length, idx);
-}
-
-void testNamespace() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE, "ns1|div {}"));
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  List<SimpleSelectorSequence> simpleSeqs =
-      ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    Expect.isTrue(simpSelector is NamespaceSelector);
-    Expect.isTrue(selector.isCombinatorNone());
-    Expect.isFalse(simpSelector.isNamespaceWildcard());
-    Expect.equals(simpSelector.namespace, "ns1");
-    ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-    Expect.isTrue(elementSelector is ElementSelector);
-    Expect.isFalse(elementSelector.isWildcard());
-    Expect.equals(elementSelector.name, "div");
-  }
-
-  parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      "ns1|div div ns2|span .foobar {}"));
-  stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  var idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is NamespaceSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals(simpSelector.namespace, "ns1");
-      ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-      Expect.isTrue(elementSelector is ElementSelector);
-      Expect.isFalse(elementSelector.isWildcard());
-      Expect.equals(elementSelector.name, "div");
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ElementSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "div");
-    } else if (idx == 2) {
-      Expect.isTrue(simpSelector is NamespaceSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.namespace, "ns2");
-      ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-      Expect.isTrue(elementSelector is ElementSelector);
-      Expect.isFalse(elementSelector.isWildcard());
-      Expect.equals(elementSelector.name, "span");
-    } else if (idx == 3) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "foobar");
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-
-  Expect.equals(simpleSeqs.length, idx);
-}
-
-void testSelectorGroups() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE,
-      "div, .foobar ,#elemId, .xyzzy .test, ns1|div div #elemId .foobar {}"));
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 5);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  var groupIdx = 0;
-  for (final selectorGroup in ruleset.selectorGroup.selectors) {
-    var idx = 0;
-    for (final selector in selectorGroup.simpleSelectorSequences) {
-      final simpSelector = selector.simpleSelector;
-      switch (groupIdx) {
-        case 0:                       // First selector group.
-          Expect.isTrue(simpSelector is ElementSelector);
-          Expect.isTrue(selector.isCombinatorNone());
-          Expect.equals(simpSelector.name, "div");
-          break;
-        case 1:                       // Second selector group.
-          Expect.isTrue(simpSelector is ClassSelector);
-          Expect.isTrue(selector.isCombinatorNone());
-          Expect.equals(simpSelector.name, "foobar");
-          break;
-        case 2:                       // Third selector group.
-          Expect.isTrue(simpSelector is IdSelector);
-          Expect.isTrue(selector.isCombinatorNone());
-          Expect.equals(simpSelector.name, "elemId");
-          break;
-        case 3:                       // Fourth selector group.
-          Expect.equals(selectorGroup.simpleSelectorSequences.length, 2);
-          if (idx == 0) {
-            Expect.isTrue(simpSelector is ClassSelector);
-            Expect.isTrue(selector.isCombinatorNone());
-            Expect.equals(simpSelector.name, "xyzzy");
-          } else if (idx == 1) {
-            Expect.isTrue(simpSelector is ClassSelector);
-            Expect.isTrue(selector.isCombinatorDescendant());
-            Expect.equals(simpSelector.name, "test");
-          } else {
-            Expect.fail("unexpected expression");
-          }
-          break;
-        case 4:                       // Fifth selector group.
-          Expect.equals(selectorGroup.simpleSelectorSequences.length, 4);
-          if (idx == 0) {
-            Expect.isTrue(simpSelector is NamespaceSelector);
-            Expect.isTrue(selector.isCombinatorNone());
-            Expect.equals(simpSelector.namespace, "ns1");
-            ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-            Expect.isTrue(elementSelector is ElementSelector);
-            Expect.isFalse(elementSelector.isWildcard());
-            Expect.equals(elementSelector.name, "div");
-          } else if (idx == 1) {
-            Expect.isTrue(simpSelector is ElementSelector);
-            Expect.isTrue(selector.isCombinatorDescendant());
-            Expect.equals(simpSelector.name, "div");
-          } else if (idx == 2) {
-            Expect.isTrue(simpSelector is IdSelector);
-            Expect.isTrue(selector.isCombinatorDescendant());
-            Expect.equals(simpSelector.name, "elemId");
-          } else if (idx == 3) {
-            Expect.isTrue(simpSelector is ClassSelector);
-            Expect.isTrue(selector.isCombinatorDescendant());
-            Expect.equals(simpSelector.name, "foobar");
-          } else {
-            Expect.fail("unexpected expression");
-          }
-          break;
-      }
-      idx++;
-    }
-    groupIdx++;
-  }
-}
-
-void testCombinator() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE,
-      ".foobar > .bar + .no-story ~ myNs|div #elemId {}"));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  List<SimpleSelectorSequence> simpleSeqs =
-    ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  Expect.equals(simpleSeqs.length, 5);
-  var idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals(simpSelector.name, "foobar");
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorGreater());
-      Expect.equals(simpSelector.name, "bar");
-    } else if (idx == 2) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorPlus());
-      Expect.equals(simpSelector.name, "no-story");
-    } else if (idx == 3) {
-      Expect.isTrue(simpSelector is NamespaceSelector);
-      Expect.isTrue(selector.isCombinatorTilde());
-      Expect.equals(simpSelector.namespace, "myNs");
-      ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-      Expect.isTrue(elementSelector is ElementSelector);
-      Expect.isFalse(elementSelector.isWildcard());
-      Expect.equals(elementSelector.name, "div");
-    } else if (idx == 4) {
-      Expect.isTrue(simpSelector is IdSelector);
-      Expect.isTrue(selector.isCombinatorDescendant());
-      Expect.equals(simpSelector.name, "elemId");
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-}
-
-void testWildcard() {
-  Parser parser = new Parser(new SourceFile(
-      SourceFile.IN_MEMORY_FILE, "* {}"));
-
-  Stylesheet stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  RuleSet ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  List<SimpleSelectorSequence> simpleSeqs =
-      ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    Expect.isTrue(simpSelector is ElementSelector);
-    Expect.isTrue(selector.isCombinatorNone());
-    Expect.isTrue(simpSelector.isWildcard());
-    Expect.equals(simpSelector.name, "*");
-  }
-
-  parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      "*.foobar {}"));
-
-  stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  Expect.equals(simpleSeqs.length, 2);
-  var idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is ElementSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.isTrue(simpSelector.isWildcard());
-      Expect.equals(simpSelector.name, "*");
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals(simpSelector.name, "foobar");
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-
-  parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      "myNs|*.foobar {}"));
-
-  stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-  Expect.equals(stylesheet.topLevels.length, 1);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  Expect.equals(simpleSeqs.length, 2);
-  idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is NamespaceSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.isFalse(simpSelector.isNamespaceWildcard());
-      ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-      Expect.equals("myNs", simpSelector.namespace);
-      Expect.isTrue(elementSelector.isWildcard());
-      Expect.equals("*", elementSelector.name);
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals("foobar", simpSelector.name);
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-
-  parser = new Parser(new SourceFile(SourceFile.IN_MEMORY_FILE,
-      "*|*.foobar {}"));
-
-  stylesheet = parser.parse();
-  Expect.isNotNull(stylesheet);
-
-  Expect.isTrue(stylesheet.topLevels[0] is RuleSet);
-  ruleset = stylesheet.topLevels[0];
-  Expect.equals(ruleset.selectorGroup.selectors.length, 1);
-  Expect.equals(ruleset.declarationGroup.declarations.length, 0);
-
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
-
-  Expect.equals(simpleSeqs.length, 2);
-  idx = 0;
-  for (final selector in simpleSeqs) {
-    final simpSelector = selector.simpleSelector;
-    if (idx == 0) {
-      Expect.isTrue(simpSelector is NamespaceSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.isTrue(simpSelector.isNamespaceWildcard());
-      Expect.equals("*", simpSelector.namespace);
-      ElementSelector elementSelector = simpSelector.nameAsSimpleSelector;
-      Expect.isTrue(elementSelector.isWildcard());
-      Expect.equals("*", elementSelector.name);
-    } else if (idx == 1) {
-      Expect.isTrue(simpSelector is ClassSelector);
-      Expect.isTrue(selector.isCombinatorNone());
-      Expect.equals("foobar", simpSelector.name);
-    } else {
-      Expect.fail("unexpected expression");
-    }
-
-    idx++;
-  }
-
-}
-
-void testPseudo() {
-  // TODO(terry): Implement
-}
-
-void testAttribute() {
-  // TODO(terry): Implement
-}
-
-void testNegation() {
-  // TODO(terry): Implement
-}
diff --git a/utils/tests/css/selector_literal_test.dart b/utils/tests/css/selector_literal_test.dart
deleted file mode 100644
index d5f0433..0000000
--- a/utils/tests/css/selector_literal_test.dart
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library selector_literal_tests;
-import '../../css/css.dart';
-
-final String ERROR = 'CompilerException: <buffer>:';
-
-main() {
-  initCssWorld();
-  options.useColors = false;
-
-  testSimpleClassSelectorSuccesses();
-  testSimpleClassSelectorFailures();
-  testPrivateNameFailures();
-}
-
-void testSimpleClassSelectorSuccesses() {
-  List<String> knownClasses = ['foobar', 'xyzzy', 'a-story', 'b-story'];
-  List<String> knownIds = ['id1', 'id2', 'id-number-3'];
-
-  CssWorld cssWorld = new CssWorld(knownClasses, knownIds);
-
-  try {
-    // Valid selectors for class names.
-    cssParseAndValidate('@{.foobar}', cssWorld);
-    cssParseAndValidate('@{.foobar .xyzzy}', cssWorld);
-    cssParseAndValidate('@{.foobar .a-story .xyzzy}', cssWorld);
-    cssParseAndValidate('@{.foobar .xyzzy .a-story .b-story}', cssWorld);
-
-    // Valid selectors for element IDs.
-    cssParseAndValidate('@{#id1}', cssWorld);
-    cssParseAndValidate('@{#id-number-3}', cssWorld);
-    cssParseAndValidate('@{#_privateId}', cssWorld);
-
-    // Valid selectors for private class names (leading underscore).
-    cssParseAndValidate('@{.foobar ._privateClass}', cssWorld);
-    cssParseAndValidate('@{.foobar ._privateClass .xyzzy}', cssWorld);
-    cssParseAndValidate('@{.foobar ._private1 .xyzzy ._private2}', cssWorld);
-
-    // Valid selectors for private element IDs (leading underscore).
-    cssParseAndValidate('@{._privateClass}', cssWorld);
-  } catch (e) {
-    // CSS Expressions failed
-    Expect.fail(e.toString());
-  }
-}
-
-void testSimpleClassSelectorFailures() {
-  List<String> knownClasses = ['foobar', 'xyzzy', 'a-story', 'b-story'];
-  List<String> knownIds = ['id1', 'id2', 'id-number-3'];
-
-  CssWorld cssWorld = new CssWorld(knownClasses, knownIds);
-
-  // Invalid class name.
-  String css = '@{.-foobar}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Unknown selector name .-foobar",
-        e.toString());
-  }
-
-  // Error this class name is not known.
-  css = '@{.foobar1}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Unknown selector name .foobar1",
-        e.toString());
-  }
-
-  // Error if any class name is not known.
-  css = '@{.foobar .xyzzy1}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Unknown selector name .xyzzy1",
-        e.toString());
-  }
-
-  // Test for invalid class name (can't start with number).
-  css = '@{.foobar .1a-story .xyzzy}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("${ERROR}1:11: fatal: parsing error expected }\n" +
-        "${css}\n          ^^", e.toString());
-  }
-
-  // element id must be single selector.
-  css = '@{#id1 #id2}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Use of Id selector must be " +
-        "singleton starting at #id2", e.toString());
-  }
-
-  // element id must be single selector.
-  css = '@{#id-number-3 .foobar}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("@{#id-number-3 .foobar} should not succeed.");
-  } catch (e) {
-    // CSS Expressions failed
-    Expect.equals("CssSelectorException: Can not mix Id selector with "+
-        "class selector(s). Id selector must be singleton too many " +
-        "starting at .foobar", e.toString(), '');
-  }
-
-  // element id must be alone and only one element id.
-  css = '@{.foobar #id-number-3 #id1}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    // CSS Expressions failed
-    Expect.equals("CssSelectorException: Use of Id selector must be " +
-        "singleton starting at #id-number-3", e.toString());
-  }
-
-  // Namespace selector not valid in @{css_expression}
-  css = '@{foo|div}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Invalid template selector foo|div",
-        e.toString());
-  }
-
-  // class and element id not allowed together.
-  css = '@{.foobar foo|div}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("$css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Invalid template selector foo|div",
-        e.toString());
-  }
-
-  // Element id and namespace not allowed together.
-  css = '@{#id1 foo|div}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Invalid template selector foo|div",
-        e.toString());
-  }
-
-  // namespace and element id not allowed together.
-  css = '@{foo|div #id1}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Invalid template selector foo|div",
-        e.toString());
-  }
-
-  // namespace / element not allowed.
-  css = '@{foo|div .foobar}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Invalid template selector foo|div",
-        e.toString());
-  }
-
-  // Combinators not allowed.
-  css = '@{.foobar > .xyzzy}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Selectors can not have " +
-        "combinators (>, +, or ~) before >.xyzzy", e.toString());
-  }
-}
-
-void testPrivateNameFailures() {
-  List<String> knownClasses = ['foobar', 'xyzzy', 'a-story', 'b-story'];
-  List<String> knownIds = ['id1', 'id2', 'id-number-3'];
-
-  CssWorld cssWorld = new CssWorld(knownClasses, knownIds);
-
-  // Too many.
-  String css = '@{._private #id2}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Use of Id selector must be " +
-        "singleton starting at #id2", e.toString());
-  }
-
-  // Unknown class foobar2.
-  css = '@{._private .foobar2}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Unknown selector name .foobar2",
-        e.toString());
-  }
-
-  // Too many element IDs.
-  css = '@{#_privateId #id2}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Use of Id selector must be " +
-        "singleton starting at #id2", e.toString());
-  }
-
-  // Too many element IDs.
-  css = '@{#_privateId1 #_privateId2}';
-  try {
-    cssParseAndValidate('${css}', cssWorld);
-    Expect.fail("${css} should not succeed.");
-  } catch (e) {
-    Expect.equals("CssSelectorException: Use of Id selector must be " +
-        "singleton starting at #_privateId2", e.toString());
-  }
-}
diff --git a/utils/tests/template/README.txt b/utils/tests/template/README.txt
deleted file mode 100644
index 1e1ebd5..0000000
--- a/utils/tests/template/README.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-Simple Tests:
-   test_simple.dart (main application)
-
-   Works with templates:
-      name_entry.tmpl      - simple template expression with attributes
-      name_entry2.tmpl     - simple template expression inside nested tags
-      name_entry_css.tmpl  - simple template expression with CSS
-
-With Tests:
-   test_with.dart (main application)
-
-   Works with templates:
-      productview.tmpl     - simplest with template
-      productview2.tmpl    - with tested with var
-
-List Tests:
-   test_list.dart (main application)
-
-   Works with templates:
-      applications.tmpl     - simple list
-
-Complex Tests:
-   test_complex.dart (main application)
-
-   Works with templates:
-      top_searches.tmpl     - #each inside of a #with
-      top_searches_css.tmpl - #each inside of a #with with CSS
-
-Complex #2 Tests:
-   test_complex2.dart (main application)
-
-   Works with templates:
-      top_searches2.tmpl     - #each inside of a #with w/ CSS and data model
-
-Real World Application - Lists w/ events
-   real_app.dart (main application)
-
-   Works with templates:
-      realviews.tmpl         - more complex app with event hookup (using var)
-
-To build and run the above tests with frog in the browser.  Each .tmpl maps to
-a test name:
-
-  simple1        => name_entry.tmpl
-  simple2        => name_entry2.tmpl
-  simple3        => name_entry_css.tmpl
-  with1          => productview.tmpl
-  with2          => productview2.tmpl
-  list           => applications.tmpl
-  complex        => top_searches.tmpl
-  complexcss     => top_searches_css.tmpl
-  complex2       => top_searches2.tmpl
-  real           => realviews.tmpl
-
-  e.g. to run the Real World Application do:
-
-      cd utils/test/templates
-      ./run real
diff --git a/utils/tests/template/applications.tmpl b/utils/tests/template/applications.tmpl
deleted file mode 100644
index f5aa9ca..0000000
--- a/utils/tests/template/applications.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-template Applications(var products) {
-  <div>
-    ${#each products}
-      <div>
-        <span>${name}</span>
-        <span>-</span>
-        <span>${users}</span>
-      </div>
-    ${/each}
-  </div>
-}
-
diff --git a/utils/tests/template/applications2.tmpl b/utils/tests/template/applications2.tmpl
deleted file mode 100644
index 284ccc5..0000000
--- a/utils/tests/template/applications2.tmpl
+++ /dev/null
@@ -1,10 +0,0 @@
-template Applications(var products) {
-  ${#each products}
-    <div>
-      <span>${name}</span>
-      <span>-</span>
-      <span>${users}</span>
-    </div>
-  ${/each}
-}
-
diff --git a/utils/tests/template/callview.tmpl b/utils/tests/template/callview.tmpl
deleted file mode 100644
index ad25c9b..0000000
--- a/utils/tests/template/callview.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-template NameEntry(String name, int age) {
-  <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span> - </span>
-    <span>${age}</span>
-    ${#NameEntry2(name, age)}
-  </div>
-}
-
-template NameEntry2(String name, int age) {
-  <div var=topDiv2 style="background-color: yellow;">
-    <span var=spanElem2>${name}</span>
-    <span> - </span>
-    <span>${age}</span>
-  </div>
-}
-
-
diff --git a/utils/tests/template/complex_datamodel.dart b/utils/tests/template/complex_datamodel.dart
deleted file mode 100644
index b5bab35..0000000
--- a/utils/tests/template/complex_datamodel.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Data model for complex tests.
-
-class Person {
-  String name;
-  int age;
-  List<Search> searches;
-
-  Person(this.name, this.age, this.searches);
-}
-
-class Search {
-  String query;
-  int rank;
-  int total;
-  List<Metric> metrics;
-
-  Search(this.query, this.rank, this.total, this.metrics);
-}
-
-class Metric {
-  String country;
-  int quantity;
-
-  Metric(this.country, this.quantity);
-
-  static int grandTotal(List<Metric> metrics) {
-    int total = 0;
-    for (final metric in metrics) {
-      total += metric.quantity;
-    }
-
-    return total;
-  }
-}
-
-List<Person> get dataModel {
-  List<Person> persons = [];
-
-  List<Search> searches = [];
-  List<Metric> metrics = [];
-
-  // Snooki data
-  metrics = [];
-  metrics.add(new Metric("USA", 200300312));
-  searches.add(new Search("intellect", 6, Metric.grandTotal(metrics), metrics));
-
-  metrics.add(new Metric("USA", 75000000));
-  metrics.add(new Metric("China", 5));
-  metrics.add(new Metric("EU", 110000));
-  metrics.add(new Metric("Canada", 3400000));
-  metrics.add(new Metric("Mexico", 20000));
-  searches.add(new Search("breading", 5, Metric.grandTotal(metrics), metrics));
-
-  metrics = [];
-  metrics.add(new Metric("USA", 5000000));
-  metrics.add(new Metric("China", 3));
-  metrics.add(new Metric("EU", 90000));
-  metrics.add(new Metric("Canada", 3100000));
-  metrics.add(new Metric("Mexico", 24000));
-  searches.add(new Search("booze", 8, Metric.grandTotal(metrics), metrics));
-
-  metrics = [];
-  metrics.add(new Metric("USA", 5000000));
-  metrics.add(new Metric("EU", 90000));
-  metrics.add(new Metric("Canada", 300000));
-  searches.add(new Search("turpitude", 10, Metric.grandTotal(metrics), metrics));
-
-  persons.add(new Person("Snooki", 24, searches));
-
-  // Lady Gaga
-  searches = [];
-
-  metrics = [];
-  metrics.add(new Metric("USA", 11000000));
-  metrics.add(new Metric("China", 5000000000));
-  metrics.add(new Metric("EU", 8700000));
-  metrics.add(new Metric("Canada", 3400000));
-  metrics.add(new Metric("Mexico", 24349898));
-  searches.add(new Search("bad romance", 3, Metric.grandTotal(metrics), metrics));
-
-  metrics = [];
-  metrics.add(new Metric("USA", 980000));
-  metrics.add(new Metric("China", 187000000));
-  searches.add(new Search("fashion", 7,  Metric.grandTotal(metrics), metrics));
-
-  metrics = [];
-  metrics.add(new Metric("USA", 7630000));
-  searches.add(new Search("outrageous", 9,  Metric.grandTotal(metrics), metrics));
-
-  persons.add(new Person("Lady Gaga", 25, searches));
-
-  // Uggie (The Artist dog)
-  searches = [];
-
-  metrics = [];
-  metrics.add(new Metric("USA", 1000000));
-  metrics.add(new Metric("China", 34000));
-  metrics.add(new Metric("EU", 11000000000));
-  metrics.add(new Metric("Canada", 5023));
-  metrics.add(new Metric("Mexico", 782));
-  searches.add(new Search("smart", 2, Metric.grandTotal(metrics), metrics));
-
-  metrics = [];
-  metrics.add(new Metric("USA", 18900000));
-  metrics.add(new Metric("China", 34000));
-  metrics.add(new Metric("EU", 990000000));
-  metrics.add(new Metric("Canada", 6739920));
-  searches.add(new Search("cute", 4, Metric.grandTotal(metrics), metrics));
-
-  metrics = [];
-  metrics.add(new Metric("USA", 1));
-  metrics.add(new Metric("China", 1500000000000));
-  metrics.add(new Metric("EU", 50));
-  metrics.add(new Metric("Canada", 0));
-  metrics.add(new Metric("Mexico", 7801));
-  searches.add(new Search("tasty", 1, Metric.grandTotal(metrics), metrics));
-
-  persons.add(new Person("Uggie (Artist dog)", 10, searches));
-
-  return persons;
-}
-
diff --git a/utils/tests/template/name_entry.tmpl b/utils/tests/template/name_entry.tmpl
deleted file mode 100644
index 2660cb6..0000000
--- a/utils/tests/template/name_entry.tmpl
+++ /dev/null
@@ -1,8 +0,0 @@
-template NameEntry(String name, int age) {
-  <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span>-</span>
-    <span>${age}</span>
-  </div>
-}
-
diff --git a/utils/tests/template/name_entry2.tmpl b/utils/tests/template/name_entry2.tmpl
deleted file mode 100644
index 1b6629e..0000000
--- a/utils/tests/template/name_entry2.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-template NameEntry(String name, int age) {
-  <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <h1>
-      <h2>
-        <h3>
-          <span var=spanElem>${name}</span>
-          <span>-</span>
-          <span>${age}</span>
-        </h3>
-      </h2>
-    </h1>
-  </div>
-}
-
diff --git a/utils/tests/template/name_entry_css.tmpl b/utils/tests/template/name_entry_css.tmpl
deleted file mode 100644
index 16fba47..0000000
--- a/utils/tests/template/name_entry_css.tmpl
+++ /dev/null
Binary files differ
diff --git a/utils/tests/template/name_entry_simple.tmpl b/utils/tests/template/name_entry_simple.tmpl
deleted file mode 100644
index 42dac27..0000000
--- a/utils/tests/template/name_entry_simple.tmpl
+++ /dev/null
@@ -1,16 +0,0 @@
-template NameEntry(String name, int age) {
-  <div>
-    <span>aaaa</span>
-    <span>bbbb</span>
-    cccc<span>-</span>dddd
-  </div>
-}
-
-template SimplestTemplate() {
-  <div></div>
-}
-
-template EmptyTemplateContent() {
-}
-
-
diff --git a/utils/tests/template/name_entry_text.tmpl b/utils/tests/template/name_entry_text.tmpl
deleted file mode 100644
index fe5eb39..0000000
--- a/utils/tests/template/name_entry_text.tmpl
+++ /dev/null
@@ -1,5 +0,0 @@
-template NameEntry(String name, int age) {
-  <div>  &#125; part1 part2 ${name} part3  &#125;  </div>
-  <div>  age = ${age} </div>&#125;
-}
-
diff --git a/utils/tests/template/nestedview.tmpl b/utils/tests/template/nestedview.tmpl
deleted file mode 100644
index 15378c0..0000000
--- a/utils/tests/template/nestedview.tmpl
+++ /dev/null
@@ -1,27 +0,0 @@
-template NestedView(Person person1, Person person2) {
-  <div>
-    <span var=a1>
-      <h1>
-        ${#with person1 p1}
-          <div>
-            <span>${p1.name}</span>
-            <span>-</span>
-            <span>${p1.age}</span>
-            <div style="background-color:yellow;">
-              ${#with person2 p2}
-                <div>
-                  <span style="color:green;">${p2.age}</span>
-                  <span>-</span>
-                  <span style="color:green;">${p2.name}</span>
-                  <div style="color:blue;font-weight:bold">${p1.name}=${p2.age}</div>
-                </div>
-              ${/with}
-              <div style="background-color:green; color: red;">${p1.name}</div>
-            </div>
-          </div>
-        ${/with}
-      </h1>
-    </span>
-  </div>
-}
-
diff --git a/utils/tests/template/productview.tmpl b/utils/tests/template/productview.tmpl
deleted file mode 100644
index 02117e1..0000000
--- a/utils/tests/template/productview.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-template ProductView(Person person) {
-  <div>
-    ${#with person}
-      <div>
-        <span>${name}</span>
-        <span>-</span>
-        <span>${age}</span>
-      </div>
-    ${/with}
-  </div>
-}
-  
diff --git a/utils/tests/template/productview2.tmpl b/utils/tests/template/productview2.tmpl
deleted file mode 100644
index c51d9ec..0000000
--- a/utils/tests/template/productview2.tmpl
+++ /dev/null
@@ -1,16 +0,0 @@
-template ProductView(Person person) {
-  <div>
-    <span var=a1>
-      <h1>
-        ${#with person}
-          <div>
-            <span>${name}</span>
-            <span>-</span>
-            <span>${age}</span>
-          </div>
-        ${/with}
-      </h1>
-    </span>
-  </div>
-}
-
diff --git a/utils/tests/template/productview3.tmpl b/utils/tests/template/productview3.tmpl
deleted file mode 100644
index 16bcfbf..0000000
--- a/utils/tests/template/productview3.tmpl
+++ /dev/null
@@ -1,10 +0,0 @@
-template ProductView(Person person) {
-  ${#with person}
-    <div>
-      <span>${name}</span>
-      <span>-</span>
-      <span>${age}</span>
-    </div>
-  ${/with}
-}
-  
diff --git a/utils/tests/template/productview_localname.tmpl b/utils/tests/template/productview_localname.tmpl
deleted file mode 100644
index a8093dc..0000000
--- a/utils/tests/template/productview_localname.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-template ProductView(Person person) {
-  <div>
-    ${#with person p}
-      <div>
-        <span>${p.name}</span>
-        <span>-</span>
-        <span>${p.age}</span>
-      </div>
-    ${/with}
-  </div>
-}
-  
diff --git a/utils/tests/template/real_app.dart b/utils/tests/template/real_app.dart
deleted file mode 100644
index cd4a8f5..0000000
--- a/utils/tests/template/real_app.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-import 'dart:html';
-part 'realviews.dart';
-
-class Division {
-  String name;
-  int id;
-  List<Product> products;
-
-  Division(this.name, this.id, this.products);
-}
-
-class Product {
-  int id;
-  String name;
-  int users;
-  List<YTD_Sales> sales;
-
-  Product(this.id, this.name, this.users, this.sales);
-}
-
-class YTD_Sales {
-  int yearly;
-  String country;
-
-  YTD_Sales(this.yearly, this.country);
-}
-
-// TODO(terry): Remove use for debug only.
-void debug() {
-  try {
-    throw "DEBUG";
-  } catch (e) {
-    print("DEBUGBREAK");
-  }
-}
-
-void main() {
-  List<Division> divisions = [];
-  List<Product> products;
-  List<YTD_Sales> sales;
-
-  products = [];
-  sales = [];
-  sales.add(new YTD_Sales(52000000, "USA"));
-  sales.add(new YTD_Sales(550000, "China"));
-  sales.add(new YTD_Sales(56000000, "EU"));
-  sales.add(new YTD_Sales(510000, "Canada"));
-  sales.add(new YTD_Sales(58700028, "Mexico"));
-  products.add(new Product(100, "Gmail", 75000000, sales));
-
-  sales = [];
-  sales.add(new YTD_Sales(12000000, "USA"));
-  sales.add(new YTD_Sales(50000, "China"));
-  sales.add(new YTD_Sales(6000000, "EU"));
-  sales.add(new YTD_Sales(10000, "Canada"));
-  sales.add(new YTD_Sales(8700028, "Mexico"));
-  products.add(new Product(101, "Talk", 5000000, sales));
-  divisions.add(new Division("Apps", 1, products));
-
-  products = [];
-  sales = [];
-  sales.add(new YTD_Sales(200000, "USA"));
-  sales.add(new YTD_Sales(20000, "China"));
-  sales.add(new YTD_Sales(2200000, "EU"));
-  sales.add(new YTD_Sales(10000, "Canada"));
-  sales.add(new YTD_Sales(100, "Mexico"));
-  products.add(new Product(200, "iGoogle", 2000000, sales));
-  divisions.add(new Division("Misc", 3, products));
-
-  products = [];
-  sales = [];
-  sales.add(new YTD_Sales(1200, "USA"));
-  sales.add(new YTD_Sales(50, "China"));
-  sales.add(new YTD_Sales(600, "EU"));
-  sales.add(new YTD_Sales(10, "Canada"));
-  sales.add(new YTD_Sales(8, "Mexico"));
-  products.add(new Product(300, "Dart", 2000, sales));
-  divisions.add(new Division("Chrome", 2, products));
-
-  products = [];
-  sales = [];
-  divisions.add(new Division("Search", 4, products));
-
-  var header = new Header("Google World Wide", new DateTime.now());
-  var listView = new DivisionSales(divisions);
-
-  document.body.elements.add(header.root);                 // Add top view.
-  document.body.elements.add(listView.root);               // Add list view.
-
-  // Hookup events.
-  for (var elem in listView.productZippy) {
-    elem.on.click.add((MouseEvent e) {
-      var expandCollapseElem = e.toElement;
-
-      DivElement salesDiv = expandCollapseElem.parent.elements.last;
-
-      bool showSales = (salesDiv.classes.contains(DivisionSales.showSales));
-
-      expandCollapseElem.innerHTML = showSales ? "&#9654;": "&#9660;";
-      expandCollapseElem.classes.remove(showSales ? DivisionSales.expand : DivisionSales.collapse);
-      expandCollapseElem.classes.add(showSales ? DivisionSales.collapse : DivisionSales.expand);
-
-      salesDiv.classes.clear();
-      salesDiv.classes.add(showSales ? DivisionSales.hideSales : DivisionSales.showSales);
-    });
-  }
-}
-
diff --git a/utils/tests/template/realviews.tmpl b/utils/tests/template/realviews.tmpl
deleted file mode 100644
index 8eff4ae..0000000
--- a/utils/tests/template/realviews.tmpl
+++ /dev/null
@@ -1,106 +0,0 @@
-template DivisionSales(var divisions) {
-  css {
-    .division-item {
-      background-color: #bbb;
-      border-top: 2px solid white;
-      line-height: 20pt;
-      padding-left: 5px;
-    }
-    .product-item {
-      background-color: lightgray;
-      margin-left: 10px;
-      border-top: 2px solid white;
-      line-height: 20pt;
-    }
-    .product-title {
-      position: absolute;
-      left: 45px;
-    }
-    .product-name {
-      font-weight: bold;
-      position: absolute;
-      left: 100px;
-    }
-    .product-users {
-      position: absolute;
-      left: 150px;
-      font-style: italic;
-      color: gray;
-      width: 110px;
-    }
-    .expand-collapse {
-      margin-left: 5px;
-      margin-right: 5px;
-      vertical-align: top;
-      cursor: pointer;
-    }
-    .expand {
-      font-size: 9pt;
-    }
-    .collapse {
-      font-size: 8pt;
-    }
-    .show-sales {
-      display: inherit;
-    }
-    .hide-sales {
-      display: none;
-    }
-    .sales-item {
-      font-family: arial;
-      background-color: lightgray;
-      margin-left: 10px;
-      border-top: 1px solid white;
-      line-height: 18pt;
-      padding-left: 5px;
-    }
-    .ytd-sales {
-      position: absolute;
-      left: 100px;
-    }
-  }
-  <div>
-    ${#each divisions div}
-      <div class="division-item">
-        <span>${div.name}</span>
-        <span>-</span>
-        <span>${div.id}</span>
-      </div>
-      <div>
-        ${#each div.products prod}
-          <div class="product-item">
-            <span var=productZippy class="expand-collapse expand">&#9660;</span>
-            <span class='product-title'>Product</span>
-            <span class="product-name">${prod.name}</span>
-            <span class="product-users" align=right>${prod.users}&nbsp;users</span>
-            <div class="show-sales">
-              ${#each prod.sales sale}
-                <div class="sales-item">
-                  <span>${sale.country}</span>
-                  <span class="ytd-sales">\$${sale.yearly}</span>
-                </div>
-              ${/each}
-            </div>
-          </div>
-        ${/each}
-      </div>
-    ${/each}
-  </div>
-}
-
-template Header(String company, Date date) {
-  css {
-    .header {
-      background-color: slateGray;
-      font-family: arial;
-      color: lightgray;
-      font-weight: bold;
-      padding-top: 20px;
-    }
-  }
-  <div class='header' align=center>
-    <h2>${company}</h2>
-    <div align=right>${date}</div>
-  </div>
-}
-
diff --git a/utils/tests/template/run b/utils/tests/template/run
deleted file mode 100755
index c4658b0..0000000
--- a/utils/tests/template/run
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/bin/bash
-
-# get the number of command-line arguments given
-ARGC=$#
-
-if [[ $ARGC -eq 1 ]];
-then
-  if [[ $1 = "simple" ]];
-  then
-    ./../../template/template name_entry_simple.tmpl name_entry.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_simple.dart
-  elif [[ $1 = "simple1" ]];
-  then
-    ./../../template/template name_entry.tmpl name_entry.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_simple.dart
-  elif [[ $1 == "simple2" ]];
-  then
-    ./../../template/template name_entry2.tmpl name_entry.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_simple.dart
-  elif [[ $1 == "simple3" ]];
-  then
-    ./../../template/template name_entry_css.tmpl name_entry.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_simple.dart
-  elif [[ $1 == "simple4" ]];
-  then
-    ./../../template/template name_entry_text.tmpl name_entry.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_simple.dart
-  elif [[ $1 == "simplecall" ]];
-  then
-    ./../../template/template callview.tmpl name_entry.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_simple.dart
-  elif [[ $1 == "with1" ]];
-  then
-    ./../../template/template productview.tmpl productview.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_with.dart
-  elif [[ $1 == "with2" ]];
-  then
-    ./../../template/template productview2.tmpl productview.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_with.dart
-  elif [[ $1 == "with3" ]];
-  then
-    ./../../template/template productview_localname.tmpl productview.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_with.dart
-  elif [[ $1 == "with4" ]];
-  then
-    ./../../template/template productview3.tmpl productview.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_with.dart
-  elif [[ $1 == "nested" ]];
-  then
-    ./../../template/template nestedview.tmpl nestedview.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_nested.dart
-  elif [[ $1 == "list1" ]];
-  then
-    ./../../template/template applications.tmpl applications.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_list.dart
-  elif [[ $1 == "list2" ]];
-  then
-    ./../../template/template applications2.tmpl applications.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_list.dart
-  elif [[ $1 == "complex" ]];
-  then
-    ./../../template/template top_searches.tmpl top_searches.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_complex.dart
-  elif [[ $1 == "complexcss" ]];
-  then
-    ./../../template/template top_searches_css.tmpl top_searches.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_complex.dart
-  elif [[ $1 == "complex2" ]];
-  then
-    ./../../template/template top_searches2.tmpl top_searches2.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/test_complex2.dart
-  elif [[ $1 == "real" ]];
-  then
-    ./../../template/template realviews.tmpl realviews.dart
-    cd ../../../frog
-    ./frog.py --html -- ../utils/tests/template/real_app.dart
-  elif [[ $1 == "clean" ]];
-  then
-    # remove all generated templates
-    echo "rm name_entry.dart"
-    rm -f name_entry.dart
-    echo "rm productview.dart"
-    rm -f productview.dart
-    echo "rm nestedview.dart"
-    rm -f nestedview.dart
-    echo "rm applications.dart"
-    rm -f applications.dart
-    echo "rm top_searches.dart"
-    rm -f top_searches.dart
-    echo "rm top_searches2.dart"
-    rm -f top_searches2.dart
-    echo "rm realviews.dart"
-    rm -f realviews.dart
-  fi
-else
-  echo -e "\033[31mUnknown test\033[0m"
-  echo -e ""
-  echo -e "Known tests are:"
-  echo -e "  simple"
-  echo -e "  simple1"
-  echo -e "  simple2"
-  echo -e "  simple3"
-  echo -e "  simple4"
-  echo -e "  simplecall"
-  echo -e "  with1"
-  echo -e "  with2"
-  echo -e "  with3"
-  echo -e "  with4"
-  echo -e "  nested"
-  echo -e "  list1"
-  echo -e "  list2"
-  echo -e "  complex"
-  echo -e "  complexcss"
-  echo -e "  complex2"
-  echo -e "  real"
-  echo -e ""
-  echo -e "clean - removes all template generated Dart classes"
-fi
-
diff --git a/utils/tests/template/sample.dart b/utils/tests/template/sample.dart
deleted file mode 100755
index 58884dd..0000000
--- a/utils/tests/template/sample.dart
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-
-// Utility functions:
-String safeHTML(String value) {
-  // TODO(terry): TBD
-  return value;
-}
-
-/* Data Model */
-class Friend {
-  String name;
-  String phone;
-  int age;
-  int friendsCircle, familyCircle, workCircle;
-
-  Friend(this.name, this.phone, this.age,
-         this.friendsCircle, this.familyCircle, this.workCircle);
-}
-
-/* Simple template:
-   ================
-
-  template HTML FriendList(List<Friend> friends) {
-    <div>Friends:
-      <ul>
-        ${#each friends}          // Iterates over each friend
-          <li>${name}</li>        // Scope of block is Friend type
-        ${/each}
-      </ul>
-    </div>
-  }
-*/
-class FriendList /*extends Template*/ {
-  Element _fragment;
-
-  // ${#each friends}
-  each_0(List items, Element parent) {
-    for (var item in items) {
-      var e0 = new Element.html('<li></li>');      // Node before injection
-      e0.innerHTML = inject_0(item);
-      parent.elements.add(e0);
-    }
-  }
-
-  // ${name}
-  String inject_0(item) {
-    return safeHTML('''${item.name}''');
-  }
-
-  FriendList(List<Friend> friends) {
-    _fragment = new Element.tag('div');
-    Element e0 = new Element.html('<div>Friends:</div>');
-    _fragment.elements.add(e0);
-    Element e0_0 = new Element.html('<ul></ul>');  // Node before #each
-    e0.elements.add(e0_0);
-    each_0(friends, e0_0);
-  }
-
-  Element get root => _fragment.nodes.first;
-
-  String toString(){
-    return _fragment.innerHTML;
-  }
-}
-
-
-/* More template control:
-   ======================
-
-  template HTML FriendEntry(Friend friend) {
-    <li>
-      ${#with friend}
-        <span>${name}</span>
-        ${#if (age < 18)}
-          <span class=”left-space”>child</span>
-        ${#else}
-          <span class=”left-space”>adult</span>
-        ${/if}
-        <span class=”left-space”>circles = ${friendCircle + familyCircle + workCircle}</span>
-      ${/friend}
-    </li>
-  }
-*/
-class FriendEntry /*extends Template*/ {
-  Element _fragment;
-
-  // ${#with friend}
-  with_0(Friend item, Element parent) {
-    var e0 = new Element.html('<span></span>');  // Node before injection
-    e0.innerHTML = inject_0(item);
-    parent.elements.add(e0);
-
-    // ${#if expression} 
-    if (if_0(item)) {
-      var e1 = new Element.html('<span class="left-space">child</span>');
-      parent.elements.add(e1);
-    } else {
-      var e2 = new Element.html('<span class="left-space">adult</span>');
-      parent.elements.add(e2);
-    }
-
-    // Node before injection.
-    var e3 = new Element.html('<span class="left-space"></span>');
-    e3.innerHTML = inject_1(item);
-    parent.elements.add(e3);
-  }
-
-  // expression (age < 18)}
-  bool if_0(var item) {
-    return (item.age < 18);
-  }
-
-  // ${name}
-  String inject_0(item) {
-    return safeHTML('''${item.name}''');
-  }
-
-  // ${friendCircle + family.Circle + workCircle
-  String inject_1(item) {
-    return safeHTML('circles = ${item.friendsCircle + item.familyCircle + item.workCircle}');
-  }
-
-  FriendEntry(Friend friend) {
-    _fragment = new Element.tag('div');
-    Element e0 = new Element.html('<li></li>');  // Node before #with
-    _fragment.elements.add(e0);
-    with_0(friend, e0);
-  }
-
-  Element get root => _fragment.nodes.first;
-
-  String toString(){
-    return _fragment.innerHTML;
-  }
-}
-
-
-/* Template with events:
-   =====================
-
-  template HTML FriendEntryEvents(Friend friend) {
-   <li>
-     ${#with friend}
-       <span var=friendElem style="cursor: pointer;">${name}</span>
-       ${#if (age < 18)}
-         <span class=”left-space”>child</span>
-       ${#else}
-         <span class=”left-space”>adult</span>
-       ${/if}
-       <span class=”left-space”>circles = ${friendCircle + familyCircle + workCircle}</span>
-     ${/friend}
-   </li>
-  }
-*/
-class FriendEntryEvents /*extends Template*/ {
-  Element _fragment;
-  var _friendElem;
-
-  get friendElem => _friendElem;
-
-  // ${#with friend}
-  with_0(Friend item, Element parent) {
-    _friendElem = new Element.html('<span style="cursor: pointer;"></span>');  // Node before injection
-    _friendElem.innerHTML = inject_0(item);
-   parent.elements.add(_friendElem);
-
-   // ${#if expression} 
-   if (if_0(item)) {
-     var e1 = new Element.html('<span class="left-space">child</span>');
-     parent.elements.add(e1);
-   } else {
-     var e2 = new Element.html('<span class="left-space">adult</span>');
-     parent.elements.add(e2);
-   }
-
-   // Node before injection.
-   var e3 = new Element.html('<span class="left-space"></span>');
-   e3.innerHTML = inject_1(item);
-   parent.elements.add(e3);
-  }
-
-  // expression (age < 18)}
-  bool if_0(var item) {
-   return (item.age < 18);
-  }
-
-  // ${name}
-  String inject_0(item) {
-   return safeHTML('''${item.name}''');
-  }
-
-  // ${friendCircle + family.Circle + workCircle
-  String inject_1(item) {
-   return safeHTML('circles = ${item.friendsCircle + item.familyCircle + item.workCircle}');
-  }
-
-  FriendEntryEvents(Friend friend) {
-   _fragment = new Element.tag('div');
-   Element e0 = new Element.html('<li></li>');  // Node before #with
-   _fragment.elements.add(e0);
-   with_0(friend, e0);
-  }
-
-  Element get root => _fragment.nodes.first;
-
-  String toString(){
-   return _fragment.innerHTML;
-  }
-}
-
-
-void main() {
-  // Setup style sheet for page.
-  document.head.elements.add(new Element.html('<style>.left-space { margin-left: 10px; }</style>'));
-
-  // Create data model.
-  List<Friend> friends = new List<Friend>();
-  friends.add(new Friend('Tom','425.123.4567', 35, 20, 10, 40));
-  friends.add(new Friend('Sue','802.987.6543', 23, 53, 25, 80));
-  friends.add(new Friend('Bill','617.123.4444', 50, 10, 5, 110));
-
-  // Simple template.
-  document.body.elements.add(new FriendList(friends).root);
-
-  // Use control template.
-  document.body.elements.add(new FriendEntry(friends[0]).root);
-
-  // Template with Events:
-  var clickableFriend = new FriendEntryEvents(friends[0]);
-  document.body.elements.add(clickableFriend.root);
-  clickableFriend.friendElem.on.click.add((e) {
-    var elemStyle = e.srcElement.style;
-    String toggleColor = elemStyle.getPropertyValue("background-color") == "red" ? "white" : "red";
-    elemStyle.setProperty("background-color", "${toggleColor}");
-  });
-
-  // Calling template inside of a template:
-//  document.body.elements.add(new Templates(friends).root);
-}
diff --git a/utils/tests/template/test_complex.dart b/utils/tests/template/test_complex.dart
deleted file mode 100644
index f0d1c8c..0000000
--- a/utils/tests/template/test_complex.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Sample for complex templates:
-//
-//       top_searches_css.tmpl
-
-import 'dart:html';
-part 'complex_datamodel.dart';
-part 'top_searches.dart';
-
-void main() {
-  List<Person> persons = dataModel;
-
-  Person whichPerson = persons[2];
-  var searchesView = new TopSearches(whichPerson, whichPerson.searches);
-
-  document.body.elements.add(searchesView.root);
-}
-
diff --git a/utils/tests/template/test_complex2.dart b/utils/tests/template/test_complex2.dart
deleted file mode 100644
index 50b4b43..0000000
--- a/utils/tests/template/test_complex2.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Sample for complex templates:
-//
-//       top_searches2.tmpl
-
-import 'dart:html';
-part 'complex_datamodel.dart';
-part 'top_searches2.dart';
-
-void main() {
-  List<Person> persons = dataModel;
-
-  var searchesView = new TopSearches(persons);
-
-  document.body.elements.add(searchesView.root);
-}
-
diff --git a/utils/tests/template/test_list.dart b/utils/tests/template/test_list.dart
deleted file mode 100644
index 7f2f312..0000000
--- a/utils/tests/template/test_list.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Sample for #each templates:
-//
-//       applications.tmpl
-
-import 'dart:html';
-part 'applications.dart';
-
-class Product {
-  String name;
-  int users;
-
-  Product(this.name, this.users);
-}
-
-void main() {
-  List<Product> products = [];
-  products.add(new Product("Gmail", 75000000));
-  products.add(new Product("Talk", 5000000));
-  products.add(new Product("iGoogle", 2000000));
-  products.add(new Product("Dart", 2000));
-
-  var form = new Applications(products);
-
-  document.body.elements.add(form.root);
-}
diff --git a/utils/tests/template/test_nested.dart b/utils/tests/template/test_nested.dart
deleted file mode 100644
index 84ec6c7..0000000
--- a/utils/tests/template/test_nested.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Sample for #with templates:
-//
-//       productview.tmpl
-//       productview2.tmpl
-
-
-import 'dart:html';
-part 'nestedview.dart';
-
-class Person {
-  String name;
-  int age;
-
-  Person(this.name, this.age);
-}
-
-void main() {
-  // Simple template.
-  Person person1 = new Person("Aristotle - Bugger for the bottle", 52);
-  Person person2 = new Person("René Descartes - Drunken fart", 62);
-
-  NestedView view = new NestedView(person1, person2);
-  document.body.elements.add(view.root);
-}
-
diff --git a/utils/tests/template/test_simple.dart b/utils/tests/template/test_simple.dart
deleted file mode 100755
index 8c8ee0d..0000000
--- a/utils/tests/template/test_simple.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Sample for testing templates:
-//
-//       name_entry.tmpl
-//       name_entry2.tmpl
-//       name_entry_css.tmpl
-
-import 'dart:html';
-part 'name_entry.dart';
-
-void main() {
-  // Simple template.
-  var x = new NameEntry("Terry Lucas", 52);
-  var y = x.root;
-  document.body.elements.add(y);
-}
-
diff --git a/utils/tests/template/test_with.dart b/utils/tests/template/test_with.dart
deleted file mode 100644
index 5e728ef..0000000
--- a/utils/tests/template/test_with.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Sample for #with templates:
-//
-//       productview.tmpl
-//       productview2.tmpl
-
-
-import 'dart:html';
-part 'productview.dart';
-
-class Person {
-  String name;
-  int age;
-
-  Person(this.name, this.age);
-}
-
-void main() {
-  // Simple template.
-  Person person = new Person("Terry Lucas", 52);
-  ProductView view = new ProductView(person);
-  document.body.elements.add(view.root);
-}
-
diff --git a/utils/tests/template/top_searches.tmpl b/utils/tests/template/top_searches.tmpl
deleted file mode 100644
index 2dee107..0000000
--- a/utils/tests/template/top_searches.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-template TopSearches(Person person, var searches) {
-  <div>
-    ${#with person}
-      <div>
-        <span>${name},&nbsp;</span>
-        <span>age&nbsp;=&nbsp;</span>
-        <span>${age}</span>
-      </div>
-      ${#each searches search}
-        <div>
-          <span style="margin-left: 10px;">query=${search.query}</span>
-          <span style="margin-left: 20px;">hits=${search.total}</span>
-        </div>
-      ${/each}
-    ${/with}
-  </div>
-}
-
diff --git a/utils/tests/template/top_searches2.tmpl b/utils/tests/template/top_searches2.tmpl
deleted file mode 100644
index e53df9e..0000000
--- a/utils/tests/template/top_searches2.tmpl
+++ /dev/null
@@ -1,64 +0,0 @@
-template TopSearches(var persons) {
-  css {
-    .all-list {
-      font-family: arial;
-    }
-    .person-item {
-      padding: 4px 0px 4px 5px;
-      background-color: slateGray;
-      color: white;
-      font-weight: bold;
-    }
-    .search-item {
-      font-size: 11pt;
-      padding: 3px 0px 3px 15px;
-      background-color: #aaa;
-      font-weight: bold;
-    }
-    .metrics-item {
-      font-size: 10pt;
-      padding: 2px 0px 2px 25px;
-      background-color: lightgray;
-      border-bottom: 1px solid white;
-    }
-    .total-hits {
-      position: absolute;
-      left: 100px;
-    }
-  }
-  <div class="all-list">
-    ${#each persons person}
-      <div class="person-item">
-        <span>${person.name},&nbsp;</span>
-        <span>age&nbsp;=&nbsp;</span>
-        <span>${person.age}</span>
-      </div>
-      <div>
-        ${#each person.searches search}
-          <div class="search-item">query=${search.query},&nbsp;rank=${search.rank},&nbsp;total=${search.total}</div>
-          ${#each search.metrics metric}
-            <div class="metrics-item">
-              <span>${metric.country}</span>
-              <span class="total-hits">${metric.quantity}</span>
-            </div>
-          ${/each}
-        ${/each}
-      </div>
-    ${/each}
-  </div>
-}
-
-template NameEntry(String name, int age) {
-  css {
-    .name-item {
-      font-size: 18pt;
-      font-weight: bold;
-    }
-  }
-  <div var=topDiv class="name-item" attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span> - </span>
-    <span>${age}</span>
-  </div>
-}
-
diff --git a/utils/tests/template/top_searches_css.tmpl b/utils/tests/template/top_searches_css.tmpl
deleted file mode 100644
index 036145a..0000000
--- a/utils/tests/template/top_searches_css.tmpl
+++ /dev/null
@@ -1,49 +0,0 @@
-template TopSearches(Person person, var searches) {
-  css {
-    .metrics-item {
-      font-family: arial;
-      background-color: lightgray;
-      margin-left: 10px;
-      border-bottom: 1px solid white;
-    }
-    .total-hits {
-      position: absolute;
-      left: 100px;
-    }
-  }
-  <div>
-    ${#with person}
-      <div>
-        <span>${name},&nbsp;</span>
-        <span>age&nbsp;=&nbsp;</span>
-        <span>${age}</span>
-      </div>
-      <div>
-        ${#each searches search}
-          <div>query=${search.query},&nbsp;rank=${search.rank},&nbsp;total=${search.total}</div>
-          ${#each search.metrics metric}
-            <div class="metrics-item">
-              <span>${metric.country}</span>
-              <span class="total-hits">${metric.quantity}</span>
-            </div>
-          ${/each}
-        ${/each}
-      </div>
-    ${/with}
-  </div>
-}
-
-template NameEntry(String name, int age) {
-  css {
-    .name-item {
-      font-size: 18pt;
-      font-weight: bold;
-    }
-  }
-  <div var=topDiv class="name-item" attr="test" attr1=test1 attr2='test2' attr3=test3>
-    <span var=spanElem>${name}</span>
-    <span> - </span>
-    <span>${age}</span>
-  </div>
-}
-