Version 1.21.0-dev.10.0

Merge 6e84b56256b8169fe5688a8220af8df59020b765 into dev
diff --git a/.packages b/.packages
index 721c67e..1a6226d 100644
--- a/.packages
+++ b/.packages
@@ -50,7 +50,7 @@
 js_ast:pkg/js_ast/lib
 js_runtime:sdk/lib/_internal/js_runtime/lib
 json_rpc_2:third_party/pkg/json_rpc_2/lib
-kernel:third_party/pkg/kernel/lib
+kernel:pkg/kernel/lib
 linter:third_party/pkg/linter/lib
 logging:third_party/pkg/logging/lib
 lookup_map:pkg/lookup_map/lib
diff --git a/DEPS b/DEPS
index 97e943b..685fbc7 100644
--- a/DEPS
+++ b/DEPS
@@ -28,7 +28,7 @@
   "github_dartlang": "https://github.com/dart-lang/%s.git",
 
   "gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
-  "co19_rev": "@d4767b4caea3c5828ad8e053cd051d44a59061af",
+  "co19_rev": "@f05d5aee5930bfd487aedf832fbd7b832f502b15",
 
   # Revisions of GN related dependencies.
   "buildtools_revision": "@39b1db2ab4aa4b2ccaa263c29bdf63e7c1ee28aa",
@@ -73,7 +73,6 @@
   "isolate_tag": "@0.2.3",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.2",
-  "kernel_rev": "@8e2b2c03c2a22d9fdf581a8e3ce798f189531081",
   "linter_tag": "@0.1.29",
   "logging_tag": "@0.11.3+1",
   "markdown_tag": "@0.11.0",
@@ -235,8 +234,6 @@
       (Var("github_dartlang") % "isolate") + Var("isolate_tag"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
       (Var("github_mirror") % "json_rpc_2") + Var("json_rpc_2_tag"),
-  Var("dart_root") + "/third_party/pkg/kernel":
-      (Var("github_mirror") % "kernel") + Var("kernel_rev"),
   Var("dart_root") + "/third_party/pkg/linter":
       (Var("github_mirror") % "linter") + Var("linter_tag"),
   Var("dart_root") + "/third_party/pkg/logging":
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index dad9113..a01d8eb2 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -9,7 +9,7 @@
 \newcommand{\code}[1]{{\sf #1}}
 \title{Dart Programming Language  Specification  \\
 {4th edition draft}\\
-{\large Version 1.14}}
+{\large Version 1.15.0}}
 
 % For information about Location Markers (and in particular the
 % commands \LMHash and \LMLabel), see the long comment at the
@@ -139,6 +139,10 @@
 When the specification refers to the order given in the program, it means the order of the program source code text, scanning left-to-right and top-to-bottom.
 
 \LMHash{}
+When the specification refers to a {\em fresh variable}, it means a variable with a name that doesn't occur anywhere in the current program.
+When the specification introduces a fresh variable bound to a value, the fresh variable is implicitly bound in a surrounding scope.
+
+\LMHash{}
 References to otherwise unspecified names of program entities (such as classes or functions) are interpreted as the names of members of the Dart core library.
 
 \commentary{
@@ -164,7 +168,7 @@
 }
 
 \LMHash{}
-In checked mode, assignments are dynamically checked, and certain violations of the type system raise exceptions at run time.
+In checked mode, assignments are dynamically checked, and certain violations of the type system throw exceptions at run time.
 
 \commentary{
 The coexistence between optional typing and reification is based on the following:
@@ -325,12 +329,11 @@
 {\em Dynamic type errors} are type errors reported in checked mode.
 
 \LMHash{}
-{\em Run-time errors} are exceptions raised during execution. Whenever we say that an exception $ex$ is {\em raised} or {\em thrown}, we mean that a throw expression  (\ref{throw}) of the form: \code{\THROW{} $ex$;} was implicitly evaluated or that a rethrow statement (\ref{rethrow}) of the form \code{\RETHROW} was executed. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we mean that an instance of class $C$ is thrown. When we say that a stream raises an exception, we mean that an exception occurred while computing the value(s) of the stream.
+{\em Run-time errors} are exceptions thrown during execution. Whenever we say that an exception $ex$ is {\em thrown}, it acts like an expression had {\em thrown} (\ref{completion}) with $ex$ as exception object and with a stack trace corresponding to the current system state. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we mean that an instance of class $C$ is thrown.
 
 \LMHash{}
 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately suspended.
 
-
 \section{Variables}
 \LMLabel{variables}
 
@@ -815,7 +818,7 @@
 }
 
 \LMHash{}
-An external function is connected to its body by an implementation specific mechanism. Attempting to invoke an external function that has not been connected to its body will raise a \code{NoSuchMethodError} or some subclass thereof.
+An external function is connected to its body by an implementation specific mechanism. Attempting to invoke an external function that has not been connected to its body will throw a \code{NoSuchMethodError} or some subclass thereof.
 
 \LMHash{}
 The actual syntax is given in sections \ref{classes} and \ref{librariesAndScripts} below.
@@ -1212,7 +1215,8 @@
 \LMLabel{constructors}
 
 \LMHash{}
-A {\em constructor} is a special function that is used in instance creation expressions (\ref{instanceCreation}) to produce objects. Constructors may be generative (\ref{generativeConstructors}) or they may be factories (\ref{factories}).
+A {\em constructor} is a special function that is used in instance creation expressions (\ref{instanceCreation}) to obtain objects, typically by creating or initializing them.
+Constructors may be generative (\ref{generativeConstructors}) or they may be factories (\ref{factories}).
 
 \LMHash{}
 A {\em constructor name} always begins with the name of its immediately enclosing class, and may optionally be followed by a dot and an identifier $id$. It is a compile-time error if $id$ is the name of a member  declared in the immediately enclosing class. It is a compile-time error if the name of a  constructor is not a constructor name.
@@ -1229,7 +1233,7 @@
 \LMLabel{generativeConstructors}
 
 \LMHash{}
-A {\em generative constructor} consists of a constructor name, a constructor parameter list, and either a redirect clause or an  initializer list and an optional body.
+A {\em generative constructor} consists of a constructor name, a constructor parameter list, and either a redirect clause or an initializer list and an optional body.
 
 \begin{grammar}
 {\bf constructorSignature:}
@@ -1255,7 +1259,7 @@
 }
 
 \LMHash{}
-Initializing formals are executed during the execution of generative constructors detailed below. Executing an initializing formal  \code{\THIS{}.id} causes the field \code{id} of the immediately surrounding class to be assigned the value of the corresponding actual parameter, unless $id$ is a final variable that has already been initialized, in which case a runtime error occurs.
+Initializing formals are executed during the execution of generative constructors detailed below. Executing an initializing formal  \code{\THIS{}.$id$} causes the field $id$ of the immediately surrounding class to be assigned the value of the corresponding actual parameter, unless $id$ is a final variable that has already been initialized, in which case a runtime error occurs.
 
 
 \commentary{
@@ -1301,9 +1305,6 @@
     .
 \end{grammar}
 
-% Need to specify exactly how executing a redirecting constructor works
-
-
 %\Q{We now have generative constructors with no bodies as well.}
 
 \paragraph{Initializer Lists}
@@ -1312,7 +1313,7 @@
 \LMHash{}
 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers.
 \begin{itemize}
-\item A {\em superinitializer} identifies a {\em superconstructor} - that is, a specific  constructor of the superclass.  Execution of the superinitializer causes the initializer list of the superconstructor to be executed.
+\item A {\em superinitializer} identifies a {\em superconstructor} - that is, a specific constructor of the superclass.  Execution of the superinitializer causes the initializer list of the superconstructor to be executed.
 
 \item An {\em instance variable initializer} assigns a value to an individual instance variable.
 \end{itemize}
@@ -1341,7 +1342,7 @@
 Each final instance variable $f$ declared in the immediately enclosing class must have an initializer in $k$'s initializer list unless it has already been initialized by one of the following means:
  \begin{itemize}
  \item Initialization at the declaration of $f$.
- \item Initialization by  means of an initializing formal of $k$.
+ \item Initialization by means of an initializing formal of $k$.
  \end{itemize}
 
 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declared in the immediately surrounding class.
@@ -1351,12 +1352,14 @@
 }
 
 \LMHash{}
- It is a compile-time error if a  generative constructor of class \code{Object} includes a superinitializer.
+It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer.
 
 \LMHash{}
-Execution of a generative constructor $k$ is always done with respect to a set of bindings for its formal parameters and with  \THIS{} bound to a fresh instance $i$ and the type parameters of the immediately enclosing class bound to a set of actual type arguments $V_1, \ldots , V_m$.
+Execution of a generative constructor $k$ of type $T$ to initialize a fresh instance $i$
+is always done with respect to a set of bindings for its formal parameters
+and the type parameters of the immediately enclosing class bound to a set of actual type arguments of $T$, $V_1, \ldots , V_m$.
 
-\commentary{These bindings are usually determined by the instance creation expression that invoked the constructor (directly or indirectly). However, they may also be determined by a reflective call,.
+\commentary{These bindings are usually determined by the instance creation expression that invoked the constructor (directly or indirectly). However, they may also be determined by a reflective call.
 }
 
 \LMHash{}
@@ -1364,36 +1367,63 @@
 
 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$
 
-where $g$ identifies another  generative constructor of the immediately surrounding class. Then execution of $k$ proceeds by evaluating the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with  \THIS{} bound to $i$ and the type parameters of the immediately enclosing class bound to $V_1, \ldots , V_m$.
+where $g$ identifies another  generative constructor of the immediately surrounding class. Then execution of $k$ to initialize $i$ proceeds by evaluating the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ to initialize $i$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with  \THIS{} bound to $i$ and the type parameters of the immediately enclosing class bound to $V_1, \ldots , V_m$.
 
 \LMHash{}
 Otherwise, execution  proceeds as follows:
 
 \LMHash{}
-%First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately enclosing class is allocated.  Next, the instance variable declarations of the immediately enclosing class are visited in the order they appear in the program text. For each such declaration $d$, if $d$ has the form  \code{$finalConstVarOrType$ $v$ = $e$; } then the instance variable $v$ of $i$ is bound to the value of $e$ (which is necessarily a compile-time constant).
-%Next, a
+The instance variable declarations of the immediately enclosing class are visited in the order they appear in the program text.
+For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrType$ $v$ = $e$; }
+then $e$ is evaluated to an object $o$
+and the instance variable $v$ of $i$ is bound to $o$.
+
+\LMHash{}
 Any initializing formals declared in $k$'s parameter list are executed in the order they appear in the program text.
 % In fact, this order is unobservable; this could be done any time prior to running the body, since
 % these only effect \THIS{}.
-Then, $k$'s  initializers are executed in the order they appear in the program.
+Then, the initializers of $k$'s initializer list are executed to initialize $i$
+in the order they appear in the program.
 
-\rationale {We could observe the order by side  effecting external routines called. So we need to specify the order.}
+\rationale {We could observe the order by side effecting external routines called. So we need to specify the order.}
 
 \LMHash{}
-After all the initializers  have completed, the body of $k$ is executed  in a scope where \THIS{} is bound to $i$. Execution of the body begins with execution of the body of the superconstructor  with \THIS{} bound to $i$, the type parameters of the immediately enclosing class bound to a set of actual type arguments $V_1, \ldots , V_m$ and the formal parameters bindings determined by the argument list of the superinitializer of $k$.
+Then if any instance variable of $i$ declared by the immediately enclosing class
+is not yet bound to a value,
+it is a dynamic error if such a variable is a \FINAL{} variable,
+otherwise all such variables are initialized with the \NULL{} value.
 
-\rationale{
-This process ensures that no uninitialized final field is ever seen by code. Note that \THIS{} is not in scope on the right hand side of an initializer (see \ref{this}) so no instance method can execute during initialization: an instance method cannot be directly invoked, nor can  \THIS{} be passed into any other code being invoked in the initializer.
+\LMHash{}
+Then, unless the enclosing class is \code{Object}, the explicitly specified or
+implicitly added superinitializer (\ref{initializerLists}) is executed to
+further initialize $i$.
+
+\commentary{
+The super constructor call can be written anywhere
+in the initializer list of $k$,
+but the actual call always happens after all initializers have been processed.
+It is not equivalent to moving the super call to the end of the initializer list
+because the argument expressions may have visible side effects
+which must happen in the order the expressions occur in the program text.
 }
 
 \LMHash{}
-Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as follows:
+After the superinitializer has completed, the body of $k$ is executed in a scope where \THIS{} is bound to $i$.
+
+\rationale{
+This process ensures that no uninitialized final field is ever seen by code. Note that \THIS{} is not in scope on the right hand side of an initializer (see \ref{this}) so no instance method can execute during initialization: an instance method cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer.
+}
 
 \LMHash{}
-First, the expression $e$ is evaluated to an object $o$. Then, the instance variable $v$ of the object denoted by \THIS{} is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occurs. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interface of the class of $o$ is not a subtype of the actual type of the field $v$.
+During the execution of a generative constructor to initialize an instance $i$,
+execution of an initializer of the form \code{\THIS{}.$v$ = $e$}
+proceeds as follows:
 
 \LMHash{}
-An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of the form  \code{\THIS{}.$v$ = $e$}.
+First, the expression $e$ is evaluated to an object $o$. Then, the instance variable $v$ of $i$ is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occurs. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interface of the class of $o$ is not a subtype of the actual type of the field $v$.
+
+\LMHash{}
+An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of the form \code{\THIS{}.$v$ = $e$}.
 
 \LMHash{}
 Execution of a superinitializer of the form
@@ -1408,10 +1438,17 @@
 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated.
 
 \LMHash{}
-Let $C$ be the class in which the superinitializer appears and let $S$ be the superclass of $C$.  If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ be the actual type arguments passed to $S$ in the superclass clause of $C$.
+Then, after the remainder of the initializer list of $k$ has been executed,
+the superconstructor is executed as follows:
 
 \LMHash{}
-Then, the initializer list of the constructor $S$ (respectively $S.id$) is executed with respect to the bindings that resulted from the evaluation of the argument list,  with \THIS{} bound to the current binding of \THIS{}, and  the type parameters (if any) of class $S$ bound to the current bindings of $U_1, , \ldots, U_m$.
+Let $C$ be the class in which the superinitializer appears and let $S$ be the superclass of $C$.  If $S$ is generic (\ref{generics}), let $U_1, \ldots, U_m$ be the actual type arguments passed to $S$ in the superclass clause of $C$.
+
+\LMHash{}
+The generative constructor $S$ (respectively $S.id$) of $S$ is executed
+to initialize $i$ with respect to the bindings that resulted from the evaluation of
+$(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$,
+and the type parameters (if any) of class $S$ bound to $U_1, \ldots, U_m$.
 
 \LMHash{}
 It is a compile-time error if class $S$ does not declare a generative constructor named $S$ (respectively $S.id$).
@@ -1444,7 +1481,6 @@
 
 \rationale{Factories address classic weaknesses associated with constructors in other languages.
 Factories can produce instances that are not freshly allocated: they can come from a cache. Likewise, factories can return instances of different classes.
-
 }
 
 \paragraph{Redirecting Factory Constructors}
@@ -2352,8 +2388,20 @@
 \LMLabel{expressions}
 
 \LMHash{}
-An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an associated static type (\ref{staticTypes}). Every value has an associated dynamic type (\ref{dynamicTypeSystem}).
+\label{evaluation}
+An {\em expression} is a fragment of Dart code that can be evaluated at run time.
+Evaluating an expression either {\em produces a value} (an object),
+or it {\em throws} an exception object and an associated stack trace.
+In the former case, we also say that the expression {\em evaluates to a value}.
 
+\LMHash{}
+Every expression has an associated static type (\ref{staticTypes}).
+Every value has an associated dynamic type (\ref{dynamicTypeSystem}).
+
+\LMHash{}
+If evaluation of one expression, $e$, is defined in terms of evaluation of another expression, typically a subexpression of $e$,
+and the evaluation of the other expression throws an exception and a stack trace,
+the evaluation of $e$ stops at that point and throws the same exception object and stack trace.
 
 \begin{grammar}
 
@@ -2472,13 +2520,13 @@
 % designed so constants do not depend on check diode being on or not.
 
 \LMHash{}
-It is a compile-time error if an expression is required to be a constant expression but its evaluation  would raise an exception.
+It is a compile-time error if an expression is required to be a constant expression but its evaluation would throw an exception.
 
 % so, checked mode? analyzers? editor/development compilers?
 \commentary{
 Note that there is no requirement that every constant expression evaluate correctly. Only when a constant expression is required (e.g., to initialize a constant variable, or as a default value of a formal parameter, or as metadata) do we insist that a constant expression actually be evaluated successfully at compile time.
 
-The above is not dependent on program control-flow. The mere presence of a required compile time constant whose evaluation would fail within a program is an error.  This also holds recursively: since compound constants are composed out of constants, if any subpart of a constant  would raise an exception when evaluated, that is an error.
+The above is not dependent on program control-flow. The mere presence of a required compile time constant whose evaluation would fail within a program is an error.  This also holds recursively: since compound constants are composed out of constants, if any subpart of a constant would throw an exception when evaluated, that is an error.
 
 On the other hand, since implementations are free to compile code late, some compile-time errors may manifest quite late.
 }
@@ -2555,7 +2603,7 @@
 \LMLabel{null}
 
 \LMHash{}
-The reserved word \NULL{} denotes the {\em null object}.
+The reserved word \NULL{} evaluates to the {\em null object}.
 %\Q{Any methods, such as \code{isNull}?}
 
 \begin{grammar}
@@ -2565,8 +2613,8 @@
 \end{grammar}
 
 \LMHash{}
-The null object is the sole instance of the built-in class \code{Null}. Attempting to instantiate \code{Null} causes a run-time error. It is a compile-time error for a class to attempt to extend, mix in or implement \code{Null}.
-Invoking a method on \NULL{}  yields a \code{NoSuchMethodError} unless the method is explicitly implemented by class \code{Null}.
+The null object is the sole instance of the built-in class \code{Null}. Attempting to instantiate \code{Null} causes a run-time error. It is a compile-time error for a class to extend, mix in or implement \code{Null}.
+The \code{Null} class declares no methods except those also declared by \code{Object}.
 
 \LMHash{}
 The static type of \NULL{} is $\bot$.
@@ -2605,7 +2653,17 @@
  \end{grammar}
 
 \LMHash{}
-If a numeric literal begins with the prefix `0x' or `0X', it denotes the hexadecimal integer represented by the part of the literal following `0x' (respectively `0X'). Otherwise, if the numeric literal contains only decimal digits, it denotes a decimal integer.  Otherwise, the numeric literal contains either a decimal point or an exponent part and it denotes a 64 bit double precision floating point number as specified by the IEEE 754 standard.
+If a numeric literal begins with the prefix `0x' or `0X',
+it denotes the integer represented by the hexadecimal numeral
+following `0x' (respectively `0X').
+Otherwise, if the numeric literal contains only decimal digits,
+it denotes an integer represented as a decimal numeral.
+In either case the literal evaluates to an instance of the class \code{int}
+with the integer value represented by that numeral.
+Otherwise, the numeric literal contains either a decimal point or an exponent part
+and it evaluates to a an instance of the `double` class
+representing a 64 bit double precision floating point number
+as specified by the IEEE 754 standard.
 
 \LMHash{}
 In principle, the range of integers supported by a Dart implementations is unlimited. In practice, it is limited by available memory. Implementations may also be limited by other considerations.
@@ -2615,20 +2673,23 @@
 }
 
 \LMHash{}
-It is a compile-time error for a class to attempt to extend, mix in or implement \code{int}. It is a compile-time error for a class to attempt to extend, mix in or implement \code{double}. It is a compile-time error for any type other than the types \code{int} and \code{double} to attempt to extend, mix in or implement \code{num}.
+It is a compile-time error for a class to extend, mix in or implement \code{int}.
+It is a compile-time error for a class to extend, mix in or implement \code{double}.
+It is a compile-time error for any class other than \code{int} and \code{double} to extend, mix in or implement \code{num}.
 
 \LMHash{}
-An {\em integer literal} is either a hexadecimal integer literal or a  decimal integer literal. Invoking the getter \code{runtimeType} on an integer literal returns the \code{Type} object that is the value of the expression \code{int}. The static type of an integer literal is \code{int}.
+An {\em integer literal} is either a hexadecimal integer literal or a  decimal integer literal.
+The static type of an integer literal is \code{int}.
 
 \LMHash{}
-A {\em literal double} is a numeric literal that is not an integer literal. Invoking the getter \code{runtimeType} on a literal double returns the \code{Type} object that is the value of the expression \code{double}.
-The static type of a literal double is \code{double}.
+A {\em literal double} is a numeric literal that is not an integer literal. The static type of a literal double is \code{double}.
 
 \subsection{Booleans}
 \LMLabel{booleans}
 
 \LMHash{}
-The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolean values true and false respectively. They are the {\em boolean literals}.
+The reserved words \TRUE{} and \FALSE{} evaluate to objects {\em true} and {\em false} that represent the boolean values true and false respectively.
+They are the {\em boolean literals}.
 
 \begin{grammar}
 {\bf booleanLiteral:}\TRUE{};
@@ -2637,14 +2698,12 @@
 \end{grammar}
 
 \LMHash{}
-Both  \TRUE{} and \FALSE{} implement the built-in class \code{bool}.  It is a compile-time error for a class to attempt to extend, mix in or implement\code{ bool}.
-
-\commentary{
-It follows that the two boolean literals are the only two instances of \code{bool}.
-}
+Both {\em true} and {\em false} are instances of the built-in class \code{bool},
+and there are no other objects that implement \code{bool}.
+It is a compile-time error for a class to extend, mix in or implement \code{bool}.
 
 \LMHash{}
-Invoking the getter \code{runtimeType} on a boolean literal returns the \code{Type} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}.
+Invoking the getter \code{runtimeType} on a boolean value returns the \code{Type} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}.
 
 \subsubsection{Boolean Conversion}
 \LMLabel{booleanConversion}
@@ -2845,7 +2904,9 @@
  \end{grammar}
 
 \LMHash{}
-All string literals implement the built-in class \code{String}. It is a compile-time error for a class to attempt to extend, mix in or implement \code{String}. Invoking the getter \code{runtimeType} on a string literal returns the \code{Type} object that is the value of the expression \code{String}. The static type of a string literal is \code{String}.
+All string literals evaluate to instances of the built-in class \code{String}.
+It is a compile-time error for a class to extend, mix in or implement \code{String}.
+The static type of a string literal is \code{String}.
 
 \subsubsection{String Interpolation}
 \LMLabel{stringInterpolation}
@@ -2870,7 +2931,16 @@
 \end{itemize}
 
 \LMHash{}
-The form \code{\$id} is equivalent to the form \code{\$\{id\}}.  An interpolated string \code{`$s_1$\$\{$e$\}$s_2$'}  is equivalent to the concatenation of the  strings \code{`$s_1$'},  \code{$e$.toString()} and  \code{$`s_2$'}. Likewise an interpolated string \code{``$s_1$\$\{e\}$s_2$''} is equivalent to the concatenation of the strings \code{``$s_1$''}, \code{$e$.toString()} and  \code{``$s_2$''}.
+The form \code{\$id} is equivalent to the form \code{\$\{id\}}.
+An interpolated string, $s$, with content `\code{$s_0$\$\{$e_1$\}$s_1\ldots{}s_{n-1}\$\{e_n\}s_{n}$}' (where any of $s_0 \ldots{} s_n$ can be empty)
+is evaluated by evaluating each expression $e_i$ ($1 \le i \le n$) in to a string $r_i$ in the order they occur in the source text, as follows:
+\begin{itemize}
+\item{} Evaluate $e_i$ to an object $o_i$.
+\item{} Invoke the \code{toString} method on $o_i$ with no arguments, and let
+  $r_i$ be the returned value.
+\item{} If $r_i$ is not an instance of the built-in type \code{String}, throw an \code{Error}.
+\end{itemize}
+Finally, the result of the evaluation of $s$ is the concatenation of the strings $s_0$, $r_1$, \ldots{}, $r_n$, and $s_n$.
 
 \subsection{Symbols}
 \LMLabel{symbols}
@@ -2934,8 +3004,8 @@
 A run-time list literal $<E>[e_1 \ldots e_n]$  is evaluated as follows:
 \begin{itemize}
 \item
-First, the expressions $e_1 \ldots e_n$ are evaluated in order they appear in the program, yielding objects $o_1 \ldots o_n$.
-\item A fresh instance  (\ref{generativeConstructors}) $a$, of size $n$,  whose class implements the built-in class $List<E>$ is allocated.
+First, the expressions $e_1 \ldots e_n$ are evaluated in order they appear in the program, producing objects $o_1 \ldots o_n$.
+\item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$,  whose class implements the built-in class $List<E>$ is allocated.
 \item
 The operator \code{[]=} is invoked on $a$ with  first  argument $i$ and second argument
 %The $i$th element of $a$ is set to
@@ -3010,12 +3080,13 @@
 A runtime map literal $<K, V>\{k_1:e_1\ldots k_n :e_n\}$  is evaluated as follows:
 \begin{itemize}
 \item
-First, the expression $k_i$ is evaluated yielding object $u_i$, the $e_i$ is vaulted yielding object $o_i$, for $i \in 1..n$ in left to right order, yielding objects $u_1, o_1\ldots u_n, o_n$.
-\item  A fresh instance (\ref{generativeConstructors}) $m$ whose class implements the built-in class
-
- $Map<K, V>$ is allocated.
+For each $i \in 1..n$ in numeric order,
+first the expression $k_i$ is evaluated producing object $u_i$,
+and then $e_i$ is evaluated producing object $o_i$.
+This produces all the objects $u_1, o_1\ldots u_n, o_n$.
+\item  A fresh instance (\ref{generativeConstructors}) $m$ whose class implements the built-in class $Map<K, V>$ is allocated.
 \item
-The operator \code{[]=} is invoked on $m$ with  first  argument $u_i$ and second argument $o_i,  i \in 1.. n$.
+The operator \code{[]=} is invoked on $m$ with  first  argument $u_i$ and second argument $o_i$ for each $i \in 1.. n$.
 \item
 The result of the evaluation is $m$.
 \end{itemize}
@@ -3045,7 +3116,7 @@
 \LMLabel{throw}
 
 \LMHash{}
-The {\em throw expression}  is used to raise an exception.
+The {\em throw expression}  is used to throw an exception.
 
  \begin{grammar}
 {\bf throwExpression:}
@@ -3059,45 +3130,32 @@
  \end{grammar}
 
 \LMHash{}
- The {\em current exception} is the last exception raised and not subsequently caught at a given moment during runtime.
+Evaluation of a throw expression of the form  \code{\THROW{} $e$;} proceeds as follows:
 
 \LMHash{}
- Evaluation of a throw expression of the form  \code{\THROW{} $e$;} proceeds as follows:
-
-\LMHash{}
-The expression $e$ is evaluated yielding a value $v$.
+The expression $e$ is evaluated to a value $v$ (\ref{evaluation}).
 
 \commentary{
-There is no requirement that the expression $e$ evaluate to a special kind of exception or error object.
+There is no requirement that the expression $e$ evaluate to any special kind of object.
 }
 
 \LMHash{}
-If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is thrown. Otherwise the current exception is set to $v$ and the current return value (\ref{return}) becomes undefined.
-
-\rationale{The current exception and the current return value must never be simultaneously defined, as they represent mutually exclusive options for exiting the current function.
-}
+If $v$ is the null value (\ref{null}), then a \code{NullThrownError} is thrown.
+Otherwise let $t$ be a stack trace corresponding to the current execution state,
+and the \THROW{} statement throws with $v$ as exception object
+and $t$ as stack trace (\ref{evaluation}).
 
 \LMHash{}
-Let $f$ be the immediately enclosing function.
-
-\LMHash{}
-If $f$ is synchronous (\ref{functions}), control is transferred to the nearest dynamically enclosing exception handler.
+If $v$ is an instance of class \code{Error} or a subclass thereof,
+and it is the first time that \code{Error} object is thrown,
+the stack trace $t$ is stored on $v$ so that it will be returned
+by the $v$'s \code{stackTrace} getter
 
 \commentary{
-If $f$ is marked \SYNC* then a dynamically enclosing exception handler encloses the call to \code{moveNext()} that initiated the evaluation of the throw expression.
+If the same \code{Error} object is thrown more than once, its \code{stackTrace} getter will return the stack trace from the {\em first} time it was thrown.
 }
 
 \LMHash{}
-If $f$ is asynchronous  then if there is a dynamically enclosing exception handler $h$  (\ref{try}) introduced by the current activation, control is transferred to $h$, otherwise $f$  terminates.
-
-\rationale{
-The rules for where a thrown exception will be handled must necessarily differ between the synchronous and asynchronous cases. Asynchronous functions cannot transfer control to an exception handler defined outside themselves.  Asynchronous generators post exceptions to their stream. Other asynchronous functions report exceptions via their future.
-}
-
-\LMHash{}
-If the object being thrown is an instance of class \code{Error} or a subclass thereof, its \code{stackTrace} getter will return the stack trace current at the point where the object was first thrown.
-
-\LMHash{}
 The static type of a throw expression is $\bot$.
 
 
@@ -3359,22 +3417,21 @@
 
 \LMHash{}
 If $T$  is malformed or if $T$ is a type variable a dynamic error occurs. In checked mode, if $T$ or any of its superclasses is malbounded a dynamic error occurs.
- Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} is thrown.  If $q$ has  less than $n$ positional parameters or more than $n$ required parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ldots, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown.
+Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} is thrown.  If $q$ has fewer than $n$ positional parameters or more than $n$ required parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ldots, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown.
 
 \LMHash{}
 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), then:
 
-\commentary{Note that it this point we are assured that the number of actual type arguments match the number of formal type parameters.}
+\commentary{Note that at this point we are assured that the number of actual type arguments match the number of formal type parameters.}
 
 \LMHash{}
-A fresh instance (\ref{generativeConstructors}), $i$,  of class $R$ is allocated. For each instance variable $f$ of $i$,  if the variable declaration of $f$ has an initializer expression $e_f$, then $e_f$ is evaluated, with the type parameters (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$, to an object $o_f$ and $f$ is bound to $o_f$. Otherwise $f$ is bound to \NULL{}.
+A fresh instance (\ref{generativeConstructors}), $i$, of class $R$ is allocated.
+Then $q$ is executed to initialize $i$ with respect to the bindings that resulted from the evaluation of the argument list, and, if $R$ is a generic class, with its type parameters bound to $V_1 \ldots V_m$.
 
-\commentary{
-Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot depend on other properties of the object being instantiated.
-}
-
-\LMHash{}
-Next,  $q$ is executed  with \THIS{} bound to $i$,  the type parameters (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$ and the formal parameter bindings that resulted from the evaluation of the argument list. The result of the evaluation of $e$ is $i$.
+If execution of $q$ completes normally (\ref{completion}), $e$ evaluates to $i$.
+Otherwise execution of $q$ throws an exception object $x$ and stack trace $t$,
+and then evaluation of $e$ also throws exception object $x$ and stack trace $t$
+(\ref{evaluation}).
 
 \LMHash{}
 Otherwise, $q$ is a factory constructor (\ref{factories}). Then:
@@ -3382,11 +3439,18 @@
 \LMHash{}
 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form  $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression
 
-$[V_1,  \ldots, V_m/T_1,  \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}.  If evaluation of $q$ causes $q$ to be re-evaluated cyclically, a runtime error occurs.
+$[V_1,  \ldots, V_m/T_1,  \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}.  If evaluation of $q$ causes $q$ to be re-evaluated cyclically, with only factory constructor redirections in-between, a runtime error occurs.
+% Used to not have the "in-between" clause, which would disallow a factory constructor redirecting to another constructor which conditionally calls the original factory constructor again with different arguments.
 
 
 \LMHash{}
-Otherwise, the body of $q$ is executed with respect to the bindings that resulted from the evaluation of the argument list and the type parameters (if any) of $q$ bound to the actual type arguments $V_1, \ldots, V_l$ resulting in an object $i$. The result of the evaluation of $e$ is $i$.
+Otherwise, the body of $q$ is executed with respect to the bindings that resulted from the evaluation of the argument list, and with the type parameters (if any) of $q$ bound to the actual type arguments $V_1, \ldots, V_l$.
+If this execution returns a value (\ref{completion}),
+then $e$ evaluates to the returned value.
+Otherwise, if the execution completes normally or returns with no value,
+then $e$ evaluates to \NULL.
+Otherwise the execution throws an exception $x$ and stack trace $t$,
+and then evaluation of $e$ also throws $x$ and $t$ (\ref{evaluation}).
 
 \LMHash{}
 It is a static warning if $q$ is a constructor of an abstract class and $q$ is not a factory constructor.
@@ -3550,37 +3614,21 @@
 Function invocation occurs in the following cases: when a function expression  (\ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref{propertyExtraction}) or setter (\ref{assignment}) is invoked or when a constructor is invoked (either via instance creation (\ref{instanceCreation}), constructor redirection (\ref{redirectingConstructors}) or super initialization). The various kinds of function invocation differ as to how the function to be invoked, $f$,  is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ has been determined, the formal parameters of $f$ are bound to corresponding actual arguments. When the body of $f$ is executed it will be executed with the aforementioned bindings.
 
 \LMHash{}
-If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generativeConstructors}) $o$ implementing the built-in class \code{Future} is associated with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when $f$ terminates. The value used to complete $o$ is the current return value (\ref{return}), if it is defined, and the current exception (\ref{throw}) otherwise.
+If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately.
+If the execution of the body of $f$ returns a value, $v$, (\ref{completion}), the invocation evaluates to $v$.
+If the execution completes normally or it returns without a value, the invocation evaluates to \NULL (\ref{null}).
+If the execution throws an exception object and stack trace, the invocation throws the same exception object and stack trace (\ref{evaluation}).
 
-\LMHash{}
-If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementing the built-in class \code{Stream} is associated with the invocation and immediately returned. When $s$ is listened to, execution of the body of $f$ will begin.  When $f$ terminates:
-\begin{itemize}
-\item If the current return value is defined then, if $s$ has been canceled then its cancellation future is completed with \NULL{} (\ref{null}).
-\item If the current exception $x$ is defined:
-  \begin{itemize}
-  \item $x$ is added to $s$.
-  \item If $s$ has been canceled then its cancellation future is completed with $x$ as an error.
-  \end{itemize}
-\item $s$ is closed.
-\end{itemize}
-
-\rationale{
-When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct any exceptions that occur at this time to the cancellation future rather than have them be lost.
+\commentary{
+A complete function body can never break or contine (\ref{completion})
+because a \BREAK{} or \CONTINUE{} statement must always occur inside the statement that is the target of the \BREAK{} or \CONTINUE{}.
+This means that a function body can only either complete normally, throw, or return. Completing normally or returning without a value is treated the same as returning \NULL, so the result of executing a function body can always be used as the result of evaluating an expression, either by evaluating to a value or by the evaluation throwing.
 }
 
-\LMHash{}
-If $f$ is asynchronous then, when $f$ terminates, any open stream subscriptions associated with any asynchronous for loops  (\ref{asynchronousFor-in}) or yield-each statements  (\ref{yieldEach}) executing within $f$ are canceled, in the order of their nesting, innermost first.
-
-\rationale{Such streams may be left open by for loops that were escaped when an exception was thrown within them for example.
-}
-
-%\LMHash{}
-%When a stream is canceled, the implementation must wait for the cancelation future returned by \cd{cancell()} to complete before proceeding.
 
 \LMHash{}
 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementing the built-in class \code{Iterable} is associated with the invocation and immediately returned.
 
-
 \commentary{
 A Dart implementation will need to provide a specific implementation of \code{Iterable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}.
 }
@@ -3593,7 +3641,11 @@
 }
 
 \LMHash{}
-When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin. When $f$ terminates, $j$ is positioned after its last element, so that its current value is \NULL{} and the current call to \code{moveNext()} on $j$ returns false, as will all further calls.
+When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin. When execution of the body of $f$ completes (\ref{completion},
+\begin{itemize}
+\item If it returns without a value or it completes normally (\ref{completion}), $j$ is positioned after its last element, so that its current value is \code{null} and the current call to \code{moveNext()} on $j$ returns false, as must all further calls.
+\item If it throws an exception object $e$ and stack trace $t$ then the current value of $j$ is \NULL and the current call to \code{moveNext()} throws $e$ and $t$ as well. Further calls to \code{moveNext()} must return false.
+\end{itemize}
 
 Each iterator starts a separate computation. If the \SYNC* function is impure, the sequence of values yielded by each iterator may differ.
 
@@ -3612,21 +3664,31 @@
 }
 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}.  This would have strange issues as well. The yielded value might differ from the expression in the yield. And it is a potential memory leak as the cache is kept alive by any iterator.
 
+\LMHash{}
+If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generativeConstructors}) $o$ implementing the built-in class \code{Future} is associated with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will be completed when execution of the body of $f$ completes (\ref{completion}). If execution of the body returns a value, $o$ is completed with that value, if it completes normally or returns without a value, $o$ is completed with the \NULL{} value, and if it throws an exception $e$ and stack trace $t$, $o$ is completed with the error $e$ and stack trace $t$.
 
 \LMHash{}
-If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately.  When $f$ terminates the current return value is returned to the caller.
-
-
-\LMHash{}
-Execution of $f$ terminates when the first of the following occurs:
+If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementing the built-in class \code{Stream} is associated with the invocation and immediately returned. When $s$ is listened to, execution of the body of $f$ will begin.
+When execution of the body of $f$ completes:
 \begin{itemize}
-\item An exception is thrown and not caught within the current function activation.
-\item A return statement (\ref{return}) immediately nested in the body of $f$ is executed and not intercepted in a \FINALLY{} (\ref{try}) clause.
-\item The last statement of the body completes execution.
+\item If it completes normally or returns with no value (\ref{completion}), then if $s$ has been canceled then its cancellation future is completed with \NULL{} (\ref{null}).
+\item If it throws an exception object $e$ and stack trace $t$:
+  \begin{itemize}
+  \item If $s$ has been canceled then its cancellation future is completed with error $e$ and stack trace $t$.
+  \item otherwise the error $e$ and stack trace $t$ are emitted by $s$.
+  \end{itemize}
+\item $s$ is closed.
 \end{itemize}
+\commentary{
+The body of an asynchronous generator function cannot break, continue or return a value (\ref{completion}). The first two are only allowed in contexts that will handle the break or continue, and return statements with an expression are not allowed in generator functions.
+}
 
+\rationale{
+When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct any exceptions that occur at this time to the cancellation future rather than have them be lost.
+}
 
-
+%\LMHash{}
+%When a stream is canceled, the implementation must wait for the cancelation future returned by \cd{cancell()} to complete before proceeding.
 
 \subsubsection{ Actual Argument List Evaluation}
 \LMLabel{actualArguments}
@@ -3661,7 +3723,7 @@
 proceeds as follows:
 
 \LMHash{}
-The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in the program, yielding objects $o_1, \ldots, o_{m+l}$.
+The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in the program, producing objects $o_1, \ldots, o_{m+l}$.
 
 \commentary{Simply stated, an argument list consisting of $m$ positional arguments and $l$ named arguments is evaluated from left to right.
 }
@@ -3985,7 +4047,7 @@
 Evaluation of $i$ proceeds as follows:
 
 \LMHash{}
-First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated  yielding actual argument objects $o_1, \ldots , o_{n+k}$. Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of $C$, and let $f$ be the result of looking up method (\ref{methodLookup})  $m$ in $S_{dynamic}$  with respect to the current library $L$.
+First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated producing actual argument objects $o_1, \ldots , o_{n+k}$. Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of $C$, and let $f$ be the result of looking up method (\ref{methodLookup})  $m$ in $S_{dynamic}$  with respect to the current library $L$.
 Let $p_1 \ldots p_h$ be the required parameters of $f$,  let $p_1 \ldots p_m$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the optional parameters declared by $f$.
 
 \LMHash{}
@@ -4431,6 +4493,7 @@
 Evaluation of a compound assignment $a$ of the form \code{$v$ ??= $e$}
 proceeds as follows:
 
+\LMHash{}
 Evaluate $v$ to an object $o$.
 If $o$ is not the null value, $a$ evaluates to $o$.
 Otherwise evaluate \code{$v$ = $e$} to a value $r$,
@@ -4439,6 +4502,7 @@
 \LMHash{}
 Evaluation of a compound assignment, $a$ of the form \code{$C$.$v$ ??= $e$}, where $C$ is a type literal, proceeds as follow:
 
+\LMHash{}
 Evaluate \code{$C$.$v$} to an object $o$.
 If $o$ is not the null value, $a$ evaluates to $o$.
 Otherwise evaluate \code{$C$.$v$ = $e$} to a value $r$,
@@ -4455,7 +4519,7 @@
 \LMHash{}
 Evaluate $e_1$ to an object $u$.
 Let $x$ be a fresh variable bound to $u$.
-Evalute \code{$x$.$v$} to an object $o$.
+Evaluate \code{$x$.$v$} to an object $o$.
 If $o$ is not the null value, $a$ evaluates to $o$.
 Otherwise evaluate \code{$x$.$v$ = $e_2$} to an object $r$,
 and then $a$ evaluates to $r$.
@@ -4478,7 +4542,7 @@
 
 \LMHash{}
 Evaluate \code{\SUPER.$v$} to an object $o$.
-If $o$ is not the null value then $a$ evaluats to $o$.
+If $o$ is not the null value then $a$ evaluates to $o$.
 Otherwise evaluate \code{\SUPER.$v$ = $e$} to an object $r$,
 and then $a$ evaluates to $r$.
 
@@ -4643,10 +4707,10 @@
 A {\em logical boolean expression} is either an equality expression (\ref{equality}), or an invocation of a logical boolean operator on an expression $e_1$ with argument $e_2$.
 
 \LMHash{}
-Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes the evaluation of $e_1$ which is then  subjected to boolean conversion, yielding an object $o_1$; if $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean conversion (\ref{booleanConversion}) producing an object $r$, which is the value of $b$.
+Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes the evaluation of $e_1$ which is then  subjected to boolean conversion, producing an object $o_1$; if $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean conversion (\ref{booleanConversion}) producing an object $r$, which is the value of $b$.
 
 \LMHash{}
-Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes the evaluation of $e_1$ which is then subjected to boolean conversion, yielding an object $o_1$; if $o_1$ is not  \TRUE, the result of evaluating $b$ is \FALSE, otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean conversion producing an object $r$, which is the value of $b$.
+Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes the evaluation of $e_1$ which is then subjected to boolean conversion, producing an object $o_1$; if $o_1$ is not  \TRUE, the result of evaluating $b$ is \FALSE, otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean conversion evaluating to an object $r$, which is the value of $b$.
 
 \LMHash{}
 A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variable $v$ has type
@@ -4933,18 +4997,24 @@
 
 \LMHash{}
 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follows:
-First, the expression $e$ is evaluated. Next:
+First, the expression $e$ is evaluated to an object $o$.
 
 \LMHash{}
-If $e$ raises an exception $x$, then an instance $f$ of class \code{Future} is allocated and later completed with $x$. Otherwise, if $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of calling \code{Future.value()} with $o$ as its argument; otherwise let $f$ be the result of evaluating $e$.
+% NOTICE: Removed the requirement that an error thrown by $e$ is caught in a
+% future. There is no reason $var x = e; await x;$ and $await e$ should behave
+% differently, and no implementation actually implemented it.
+Then, if $o$ is not an instance of \code{Future}, then let $f$ be the result of creating a new object using the constructor \code{Future.value()} with $o$ as its argument; otherwise let $f$ be $o$.
 
 \LMHash{}
-Next,  execution of the function $m$ immediately enclosing $a$ is suspended until after $f$ completes. The stream associated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused. At some time after $f$ is completed, control returns to the current invocation. The stream associated with the innermost enclosing asynchronous for loop  (\ref{asynchronousFor-in}), if any, is resumed. If $f$ has completed with an exception $x$, $a$ raises $x$. If $f$ completes with a value $v$, $a$ evaluates to $v$.
+Next, the stream associated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused. The current invocation of the function body immediately enclosing $a$ is suspended until after $f$ completes. At some time after $f$ is completed, control returns to the current invocation. If $f$ has completed with an error $x$ and stack trace $t$, $a$ throws $x$ and $t$ (\ref{evaluation}). If $f$ completes with a value $v$, $a$ evaluates to $v$.
 
 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$.
 
 \commentary{
 It is a compile-time error if  the function  immediately enclosing  $a$  is not declared asynchronous.  However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning.
+% TODO(lrn): Update this, it's not actually correct,
+% the expression "await(expr)" is valid non-async syntax *and* a valid
+% async await expression.
 }
 
 \rationale{
@@ -5130,7 +5200,7 @@
 If $e_1$ is a type literal, $e$ is equivalent to \code{$e_1$.$v$-{}-}.
 
 Otherwise evaluate $e_1$ to an object $u$.
-If $u$ is the null value, $e$ evalkuates to the null value.
+If $u$ is the null value, $e$ evaluates to the null value.
 Otherwise let $x$ be a fresh variable bound to $u$.
 Evaluate \code{$x$.$v$-{}-} to an object $o$.
 Then $e$ evaluates to $o$.
@@ -5408,6 +5478,35 @@
 \section{Statements}
 \LMLabel{statements}
 
+\LMHash{}
+A {\em statement} is a fragment of Dart code that can be executed at runtime. Statements, unlike expressions, do not evaluate to a value, but are instead executed for their effect on the program state and control flow.
+
+\label{completion}
+Execution of a statement {\em completes} in one of five ways: either it {\em completes normally}, it {\em breaks} or it {\em continues} (either to a label or without a label), it {\em returns} (with or without a value), or it {\em throws} an exception object and an associated stack trace.
+
+In the description of statement execution, the default is that the execution
+completes normally unless otherwise stated.
+
+If the execution of a statement, $s$, is defined in terms of executing
+another statement,
+and the execution of that other statement does not complete normally,
+then, unless otherwise stated, the execution of $s$ stops
+at that point and completes in the same way.
+\commentary{
+For example, if execution of the body of a \DO{} loop returns a value, so does execution of the \DO{} loop statement itself.
+}
+
+If the execution of a statement is defined in terms of evaluating an expression
+and the evaluation of that expression throws,
+then, unless otherwise stated, the execution of the statement stops
+at that point and throws the same exception object and stack trace.
+\commentary{
+For example, if evaluation of the condition expression of an \IF{} statement throws,
+then so does execution of the \IF{} statement. Likewise, if evaluation of the expression of a \RETURN{} statement throws, so does execution of the \RETURN{} statement.
+}
+
+\LMHash{}
+
  \begin{grammar}
 {\bf statements:}
       statement*
@@ -5442,7 +5541,7 @@
  \LMLabel{blocks}
 
 \LMHash{}
- A {\em block statement} supports sequencing of code.
+A {\em block statement} supports sequencing of code.
 
 \LMHash{}
 Execution of a block statement $\{s_1, \ldots,  s_n\}$ proceeds as follows:
@@ -5454,9 +5553,8 @@
 A block statement introduces a new scope, which is nested in the lexically enclosing scope in which the block statement appears.
 
 
-
- \subsection{Expression Statements}
- \LMLabel{expressionStatements}
+\subsection{Expression Statements}
+\LMLabel{expressionStatements}
 
 \LMHash{}
 An {\em expression statement} consists of an expression other than a non-constant map literal (\ref{maps}) that has no explicit type arguments.
@@ -5583,15 +5681,14 @@
 
 \begin{grammar}
 {\bf ifStatement:}
-      \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow top level expression
+      \IF{} `(' expression `)' statement ( \ELSE{} statement)?
     .
- \end{grammar}
+\end{grammar}
 
 Execution of an if statement of the form  \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ proceeds as follows:
 
 \LMHash{}
- First, the expression $b$ is evaluated to an object $o$. Then, $o$ is  subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{s_2\}$ is executed.
-
+ First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{s_2\}$ is executed.
 
  \commentary {
  Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equivalent to
@@ -5661,7 +5758,7 @@
 
 
 \LMHash{}
-Execution of a for statement of the form   \code{ \FOR{} (\VAR{} $v = e_0$ ; $c$; $e$) $s$} proceeds as follows:
+Execution of a for statement of the form   \code{ \FOR{} (\VAR{} $v$ = $e_0$ ; $c$; $e$) $s$} proceeds as follows:
 
 \LMHash{}
 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let  $c^\prime$ be $c$.
@@ -5673,12 +5770,16 @@
 \label{beginFor}
 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise,  let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous execution of step \ref{allocateFreshVar}.
 \item
-The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step
+The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes normally. Otherwise, execution continues at step
 \ref{beginIteration}.
 \item
 \label{beginIteration}
 The statement $[v^\prime/v]\{s\}$ is executed.
-\item
+
+If this execution completes normally, continues without a label,
+or continues to a label (\ref{labels}) that prefixes this \FOR{} statement (\ref{completion}),
+then execution of the statement is treated as if it had completed normally.
+
 \label{allocateFreshVar}
 Let $v^{\prime\prime}$ be a fresh variable.  $v^{\prime\prime}$ is bound to the value of $v^\prime$.
 \item
@@ -5722,8 +5823,6 @@
 \end{dartCode}
 where \code{n0} is an identifier that does not occur anywhere in the program, except that for purposes of static typechecking, it is checked under the assumption that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.iterator$.
 
-
-
 \subsubsection{Asynchronous For-in}
 \LMLabel{asynchronousFor-in}
 
@@ -5731,21 +5830,70 @@
 A for-in statement may be asynchronous. The asynchronous form is designed to iterate over streams. An asynchronous for loop is distinguished by the keyword \AWAIT{} immediately preceding the keyword \FOR.
 
 \LMHash{}
-Execution of a for-in statement of the form  \code{\AWAIT{} \FOR{} (finalConstVarOrType? id \IN{} $e$) $s$} proceeds as follows:
+Execution of a for-in statement, $f$, of the form \code{\AWAIT{} \FOR{} (finalConstVarOrType? $id$ \IN{} $e$) $s$} proceeds as follows:
 
 \LMHash{}
-The expression $e$ is evaluated to an object $o$. It is a dynamic error if $o$ is not an instance of a class that implements \code{Stream}. Otherwise, the expression \code{\AWAIT{} $v_f$}  (\ref{awaitExpressions}) is evaluated, where $v_f$ is a fresh variable whose value is a fresh instance (\ref{generativeConstructors}) $f$ implementing the built-in class \code{Future}.
+The expression $e$ is evaluated to an object $o$.
+It is a dynamic error if $o$ is not an instance of a class that implements \code{Stream}.
 
 \LMHash{}
-The stream $o$ is listened to,  and on each data event in $o$ the statement $s$ is executed with \code{id} bound to the value of the current element of the stream. If $s$ raises an exception, or if $o$ raises an exception, then $f$ is completed with that exception. Otherwise, when all events in the stream $o$ have been processed, $f$ is completed with \NULL{}  (\ref{null}).
-
-\LMHash{}
-Let $u$ be the stream associated with the immediately enclosing asynchronous for loop or generator function (\ref{functions}), if any. If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handling of $e_u$ must wait until $s$ is complete.
-
-\rationale{
-The future $f$ and the corresponding \AWAIT{} expression ensure that execution suspends as an asynchronous for loop begins and resumes after the \FOR{} statement when it ends. They also ensure that the stream of any enclosing asynchronous \FOR{} loop is paused for the duration of this loop.
+The stream associated with the innermost enclosing asynchronous for loop, if any, is paused.
+The stream $o$ is listened to, producing a stream subscription $u$,
+and execution of the asynchronous for-in loop is suspended
+until a stream event is available.
+\commentary{
+This allows other asynchronous events to execute while this loop is waiting for stream events.
 }
 
+Pausing an asynchronous for loop means pausing the associated stream subscription.
+A stream subscription is paused by calling its \code{pause} method.
+If the subscription is already paused, an implementation may omit further calls to \code{pause}.
+
+\commentary{
+The \code{pause} call can throw, although that should never happen for a correctly implemented stream.
+}
+
+\LMHash{}
+For each {\em data event} from $u$,
+the statement $s$ is executed with $id$ bound to the value of the current data event.
+
+\LMHash{}
+\commentary{
+Either execution of $s$ is completely synchronous, or it contains an
+asynchronous construct (\AWAIT{}, \AWAIT{} \FOR{}, \YIELD{} or \YIELD*)
+which will pause the stream subscription of its surrounding asynchronous loop.
+This ensures that no other event of $u$ occurs before execution of $s$ is complete, if $o$ is a correctly implemented stream.
+If $o$ doesn't act as a valid stream, for example by not respecting pause requests, the behavior of the asynchronous loop may become unpredictable.
+}
+
+\LMHash{}
+If execution of $s$ continues without a label, or to a label (\ref{labels}) that prefixes the asynchronous for statement (\ref{completion}), then the execution of $s$ is treated as if it had completed normally.
+
+If execution of $s$ otherwise does not complete normally, the subscription $u$ is canceled by evaluating \code{\AWAIT{} $v$.cancel()} where $v$ is a fresh variable referencing the stream subscription $u$.
+If that evaluation throws,
+execution of $f$ throws the same exception and stack trace.
+Otherwise execution of $f$ completes in the same way as the execution of $s$.
+% Notice: The previous specification was unclear about what happened when
+% a subscripton is canceled. This text is explicit, and existing
+% implementations may not properly await the cancel call.
+Otherwise the execution of $f$ is suspended again, waiting for the next stream subscription event, and $u$ is resumed if it has been paused.
+\commentary{
+The \code{resume} call can throw, in which case the asynchronous for
+loop also throws. That should never happen for a correctly implemented stream.
+}
+
+\LMHash{}
+On an {\em error event} from $u$,
+with error object $e$ and stack trace $st$,
+the subscription $u$ is canceled by evaluating \code{\AWAIT{} v.cancel()}
+where $v$ is a fresh variable referencing the stream subscription $u$.
+If that evaluation throws,
+execution of $f$ throws the same exception object and stack trace.
+Otherwise execution of $f$ throws with $e$ as exception object and $st$ as stack trace.
+
+\LMHash{}
+When $u$ is done, execution of $f$ completes normally.
+
 \LMHash{}
 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditional for loop  (\ref{forLoop}) is prefixed by the \AWAIT{}  keyword.
 
@@ -5765,10 +5913,23 @@
  \end{grammar}
 
 \LMHash{}
- Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows:
+Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows:
 
 \LMHash{}
-The expression $e$ is evaluated to an object $o$. Then, $o$ is  subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$.  If $r$ is \TRUE{}, then the statement $\{s\}$ is executed and then the while statement is re-executed recursively. If $r$ is \FALSE{}, execution of the while statement is complete.
+The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$.
+
+\LMHash{}
+If $r$ is \FALSE{}, then execution of the while statement completes normally
+(\ref{completion}).
+
+\LMHash{}
+Otherwise $r$ is \TRUE{} and then the statement $\{s\}$ is executed.
+If that execution completes normally or it continues with no label or to a label (\ref{labels}) that prefixes the \WHILE{} statement (\ref{completion}), then the while statement is re-executed.
+If the execution breaks without a label, execution of the while statement completes normally.
+\commentary{
+If the execution breaks with a label that prefixes the \WHILE{} statement,
+it does end execution of the loop, but the break itself is handled by the surrounding labeled statement (\ref{labels}).
+}
 
 \LMHash{}
 It is a static type warning if the static type of $e$ may not be assigned to \code{bool}.
@@ -5791,7 +5952,13 @@
 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceeds as follows:
 
 \LMHash{}
-The statement $\{s\}$ is executed. Then, the expression $e$ is evaluated to an object $o$. Then, $o$ is  subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement is complete. If $r$ is \TRUE{}, then the do statement is re-executed recursively.
+The statement $\{s\}$ is executed.
+If that execution continues with no label, or to a label (\ref{labels}) that prefixes the do statement (\ref{completion}), then the execution of $s$ is treated as if it had completed normally.
+
+\LMHash{}
+Then, the expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$.
+If $r$ is \FALSE{}, execution of the do statement completes normally (\ref{completion}).
+If $r$ is \TRUE{}, then the do statement is re-executed.
 
 \LMHash{}
 It is a static type warning if the static type of $e$ may not be assigned to \code{bool}.
@@ -5802,7 +5969,7 @@
 \LMHash{}
 The {\em switch statement} supports dispatching control among a large number of cases.
 
- \begin{grammar}
+\begin{grammar}
 {\bf switchStatement:}
       \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases
     .
@@ -5886,18 +6053,15 @@
 proceeds as follows:
 
 \LMHash{}
-The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variable whose name is distinct from any other variable in the program. In checked mode, it is a run time error if the value of $e$ is not an instance of the same class as the constants $e_1 \ldots e_n$.
+The statement \code{\VAR{} $id$ = $e$;} is evaluated, where $id$ is a fresh variable. In checked mode, it is a run time error if the value of $e$ is not an instance of the same class as the constants $e_1 \ldots e_n$.
 
 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ does not matter.}
 
 \LMHash{}
-Next, the case clause \CASE{} $e_{1}: s_{1}$ is executed if it exists. If \CASE{} $e_{1}: s_{1}$ does not exist, then if there is a  \DEFAULT{} clause it is executed by executing $s_{n+1}$.
+Next, the case clause \CASE{} $e_{1}$: $s_{1}$ is matched against $id$, if $n > 0$. Otherwise if there is a \DEFAULT{} clause, the case statements $s_{n+1}$ are executed (\ref{case-execute}).
 
 \LMHash{}
-A case clause introduces a new scope, nested in the lexically surrounding scope. The scope of a case clause ends immediately after the case clause's statement list.
-
-\LMHash{}
-Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a  switch statement
+Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement
 
 \begin{dartCode}
 \SWITCH{} ($e$) \{
@@ -5908,16 +6072,15 @@
 \}
 \end{dartCode}
 
-proceeds as follows:
+against the value of a variable $id$ proceeds as follows:
 
 \LMHash{}
-The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then subjected to boolean conversion yielding a value $v$.
-If $v$ is not  \TRUE{} the following case,  \CASE{} $e_{k+1}: s_{k+1}$ is executed if it exists. If  \CASE{} $e_{k+1}: s_{k+1}$ does not exist, then the \DEFAULT{} clause is executed by executing $s_{n+1}$.
-If $v$ is \TRUE{},   let $h$ be the smallest number such that $h \ge k$ and $s_h$ is non-empty. If no such $h$ exists, let $h = n + 1$. The  sequence of statements $s_h$ is then executed.
-If execution reaches the point after $s_h$  then  a runtime error occurs, unless $h = n+1$.
+The expression \code{$e_k$ == $id$} is evaluated to an object $o$ which is then subjected to boolean conversion evaluating to a value $v$.
+If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against $id$ if $k < n$. If $k = n$, then the \DEFAULT{} clause's statements are executed (\ref{case-execute}).
+If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h$ is non-empty. If no such $h$ exists, let $h = n + 1$. The case statements $s_h$ are then executed (\ref{case-execute}).
 
 \LMHash{}
-Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a  switch statement
+Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement
 
 \begin{dartCode}
 \SWITCH{} ($e$) \{
@@ -5927,24 +6090,20 @@
 \}
 \end{dartCode}
 
-proceeds as follows:
+against the value of a variable $id$ proceeds as follows:
 
 \LMHash{}
-The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then subjected to boolean conversion yielding a value $v$.
-If $v$ is not  \TRUE{} the following case,  \CASE{} $e_{k+1}: s_{k+1}$ is executed if it exists.
-If $v$ is \TRUE{},   let $h$ be the smallest integer such that $h \ge k$ and $s_h$ is non-empty. The  sequence of statements $s_h$ is  executed if it exists.
-If execution reaches the point after $s_h$  then  a runtime error occurs, unless $h = n$.
+The expression \code{$e_k$ == $id$} is evaluated to an object $o$ which is then subjected to boolean conversion evaluating to a value $v$.
+If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against $id$ if $k < n$.
+If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_h$ is non-empty. If such a $h$ exists, the case statements $s_h$ are executed (\ref{case-execute}). Otherwise the switch statement completes normally (
+ref{completion}).
 
 
-\commentary{
-In other words, there is no implicit fall-through between non-empty cases. The last case in a switch (default or otherwise) can `fall-through' to the end of the statement.
-}
-
 \LMHash{}
 It is a static warning if the type of $e$ may not be assigned to the type of $e_k$.
 Let $s$ be the last statement of the statement sequence $s_k$.
-If $s$ is a non-empty block statement, let $s$ instead be the last statment of the block statement.
-It is a static warning $s$ is not a \BREAK{}, \CONTINUE{}, \RETHROW{} or \RETURN{} statement or an expression statment where the expression is a \THROW{} expression.
+If $s$ is a non-empty block statement, let $s$ instead be the last statement of the block statement.
+It is a static warning $s$ is not a \BREAK{}, \CONTINUE{}, \RETHROW{} or \RETURN{} statement or an expression statement where the expression is a \THROW{} expression.
 
 \rationale{
 The behavior of switch cases intentionally differs from the C tradition.  Implicit fall through is a known cause of programming errors and therefore disallowed.  Why not simply break the flow implicitly at the end of every case, rather than requiring explicit code to do so?  This would indeed be cleaner.  It would also be cleaner to insist that each case have a single (possibly compound) statement.  We have chosen not to do so in order to facilitate porting of switch statements from other languages.  Implicitly breaking the control flow at the end of a case would silently alter the meaning of ported code that relied on fall-through, potentially forcing the programmer to deal with subtle bugs. Our design ensures that the difference is immediately brought to the coder's attention.  The programmer will be notified at compile-time if they forget to end a case with a statement that terminates the straight-line control flow. We could make this warning a compile-time error, but refrain from doing so because do not wish to force the programmer to deal with this issue immediately while porting code.  If developers ignore the warning and run their code, a run time error will prevent the program from misbehaving in hard-to-debug ways (at least with respect to this issue).
@@ -5974,13 +6133,63 @@
 In other words, a warning will be issued if a switch statement over an enum is not exhaustive.
 }
 
+\LMHash{}
+\subsubsection{Switch case statements}
+\LMLabel{case-execute}
+
+\LMHash{}
+Execution of the case statements $s_h$ of a switch statement
+
+\begin{dartCode}
+\SWITCH{} ($e$) \{
+   $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
+   $\ldots$
+   $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
+\}
+\end{dartCode}
+
+or a switch statement
+
+\begin{dartCode}
+\SWITCH{} ($e$) \{
+   $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
+   $\ldots$
+   $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
+   $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$
+\}
+\end{dartCode}
+
+proceeds as follows:
+
+\LMHash{}
+Execute $\{s_h\}$.
+If this execution completes normally,
+and if $s_h$ is not the statements of the last case of the switch
+($h = n$ if there is no \DEFAULT{} clause,
+$h = n+1$ if there is a \DEFAULT{} clause),
+then the execution of the switch case throws an error.
+Otherwise $s_h$ are the last statements of the switch case,
+and execution of the switch case completes normally.
+
+\commentary{
+In other words, there is no implicit fall-through between non-empty cases. The last case in a switch (default or otherwise) can `fall-through' to the end of the statement.
+}
+
+If execution of $\{s_h\}$ breaks with no label (\ref{completion}), then the execution of the switch statement completes normally.
+
+If execution of $\{s_h\}$ continues to a label (\ref{completion}), and the label is $label_{ij}$, where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFAULT{}, or $1 \le i \le n$ if there is no \DEFAULT{}, and where $1 \le j \le j_{i}$, then
+let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty. If no such $h$ exists, let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT{}, otherwise let $h = n$.
+The case statements $s_h$ are then executed (\ref{case-execute}).
+
+If execution of $\{s_h\}$ completes in any other way, execution of the \SWITCH{} statement completes in the same way.
+
 
 \subsection{ Rethrow}
 \LMLabel{rethrow}
 
 
 \LMHash{}
-The {\em rethrow statement}  is used to re-raise an exception.
+The {\em rethrow statement}  is used to re-throw an exception and its associated stack trace.
 
  \begin{grammar}
 {\bf rethrowStatement:}
@@ -5999,25 +6208,12 @@
 }
 
 \LMHash{}
-The current exception (\ref{throw}) is set to $p_1$, the current return value (\ref{return}) becomes undefined, and the active stack trace (\ref{try}) is set to $p_2$.
-
-\LMHash{}
-If $f$ is marked \ASYNC{} or \ASYNC* (\ref{functions}) and there is a dynamically enclosing exception handler (\ref{try}) $h$ introduced by the current activation, control is transferred to $h$, otherwise $f$  terminates.
-
-\rationale{
-In the case of an asynchronous function, the dynamically enclosing exception handler is only relevant within the function. If an exception is not caught within the function, the exception value is channelled through a future or stream rather than propagating via exception handlers.
-}
-
-\LMHash{}
-Otherwise, control is transferred to the  innermost enclosing exception handler.
-
-\commentary{The change in control may result in multiple functions terminating if these functions do not catch the exception via a \CATCH{} or \FINALLY{} clause, both of which introduce a dynamically enclosing exception handler.}
+The \RETHROW{} statement {\em throws} (\ref{completion}) with $p_1$ as the exception object and $p_2$ as the stack trace.
 
 \LMHash{}
 It is a compile-time error if a  \code{\RETHROW{}} statement is not enclosed within an \ON-\CATCH{} clause.
 
 
-
 \subsection{ Try}
 \LMLabel{try}
 
@@ -6043,10 +6239,10 @@
  \end{grammar}
 
 \LMHash{}
- A try statement consists of a block statement, followed by at least one of:
- \begin{enumerate}
- \item
-A set of \ON{}-\CATCH{} clauses, each of which specifies  (either explicitly or implicitly) the type of exception object to be handled, one or two exception parameters and a block statement.
+A try statement consists of a block statement, followed by at least one of:
+\begin{enumerate}
+\item
+A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or implicitly) the type of exception object to be handled, one or two exception parameters, and a block statement.
 \item
 A \FINALLY{} clause, which consists of a block statement.
 \end{enumerate}
@@ -6056,123 +6252,84 @@
 }
 
 \LMHash{}
-An \ON{}-\CATCH{} clause of the form   \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$}  {\em matches} an object $o$  if the type of $o$ is a subtype of $T$.  If $T$ is a malformed or deferred type  (\ref{staticTypes}), then performing a match causes a run time error.
-
-\commentary {
-It is of course a static warning if $T$ is a deferred or malformed type.
-}
-
-\LMHash{}
-An \ON{}-\CATCH{} clause of the form   \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$} introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static type of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}.
-
-
-\LMHash{}
-An \ON{}-\CATCH{} clause of the form  \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is equivalent to an \ON{}-\CATCH{} clause  \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$} where $p_2$ is an identifier that does not occur anywhere else in the program.
-
-
-\LMHash{}
-An \ON{}-\CATCH{} clause of the form  \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause  \code{\ON{} \DYNAMIC{} \CATCH{} ($p$) $s$}. An \ON{}-\CATCH{} clause of the form  \code{\CATCH{} ($p_1, p_2$) $s$} is equivalent to an \ON{}-\CATCH{} clause  \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$}.
-
-
-%If an explicit type is associated with of $p_2$, it is a static warning if that type is not \code{Object} or \DYNAMIC{}.
-
-\LMHash{}
-The {\em active stack trace} is an object whose \code{toString()} method produces a string that is a record of exactly those function activations within the current isolate that had not completed execution at the point where the current exception (\ref{throw}) was thrown.
-%\begin{enumerate}
-%\item Started execution after the currently executing function.
-%\item Had not completed execution at the point where the exception caught by the currently executing  \ON{}-\CATCH{} clause was initially thrown.
-%\commentary{The active stack trace contains the frames between the exception handling code and the original point when an exception is thrown, not where it was rethrown.}
-%\end{enumerate}
-
- \commentary{
-This implies that no synthetic function activations may be added to the trace, nor may any source level activations be omitted.
-This means, for example, that any inlining of functions done as an optimization must not be visible in the trace. Similarly, any synthetic routines used by the implementation must not appear in the trace.
-
-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.
-}
-
-% 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.
-
- \commentary{The term position should not be interpreted as a line number, but rather as a precise position - the exact character index of the  expression that raised  the exception. }
-
- % A position can be represented via a Token. If we make that part of the core reflection facility, we can state this here.
-
-\LMHash{}
-A try statement \TRY{} $s_1$ $on-catch_1 \ldots  on-catch_n$ \FINALLY{} $s_f$  defines an exception handler $h$ that executes as follows:
-
-\LMHash{}
-The \ON{}-\CATCH{} clauses are examined in order, starting with $catch_1$, until either an \ON{}-\CATCH{} clause that matches the current exception (\ref{throw}) is found, or the list of \ON{}-\CATCH{} clauses has been exhausted. If an \ON{}-\CATCH{} clause $on-catch_k$ is found, then $p_{k1}$ is bound to the current exception,  $p_{k2}$, if declared,  is bound to the active stack trace, and then $catch_k$ is executed. If no \ON{}-\CATCH{} clause is found, the \FINALLY{} clause is executed. Then, execution resumes at the end of the try statement.
-
-
-\LMHash{}
-A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes as follows:
-
-\LMHash{}
-Let $r$ be the current return value (\ref{return}). Then the current return value becomes undefined. Any open streams associated with any asynchronous for loops (\ref{asynchronousFor-in}) and yield-each (\ref{yieldEach}) statements executing within the dynamic scope of $h$ are canceled, in the order of their nesting, innermost first.
-
-\rationale{
-Streams left open by for loops that were escaped for whatever reason would be canceled at function termination, but it is best to cancel them as soon as possible.
-}
-
-\LMHash{}
-Then the \FINALLY{} clause is executed. Let $m$ be the immediately enclosing function. If $r$ is defined then the current return value is set to $r$ and then:
-\begin{itemize}
-\item
- if there is a dynamically enclosing error handler $g$ defined by a \FINALLY{} clause in $m$, control is transferred to $g$.
- \item
-Otherwise $m$ terminates.
-\end{itemize}
-
-Otherwise, execution resumes at the end of the try statement.
-
-\LMHash{}
-Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $s$ of a try statement $t$ proceeds as follows:
-The statement $s$ is executed in the dynamic scope of the exception handler defined by the finally clause of $t$. Then, the current exception and active stack trace both become undefined.
-
-\LMHash{}
-Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as follows:
-
-\LMHash{}
-Let $x$ be the current exception and let $t$ be the active stack trace. Then the current exception and the active stack trace both become undefined. The statement $s$ is executed. Then, if $x$ is defined,  it is rethrown as if by a rethrow statement (\ref{rethrow}) enclosed in a \CATCH{} clause of the form \code{\CATCH{} ($v_x$, $v_t$)} where $v_x$ and $v_t$ are fresh variables bound to $x$ and $t$ respectively.
-
-
-\LMHash{}
-Execution of a try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $s_f$;}  proceeds as follows:
-
-\LMHash{}
-The statement $s_1$ is executed in the dynamic scope of the exception handler defined by the try statement. Then, the \FINALLY{} clause is executed.
-
-\commentary{
-Whether any of the \ON{}-\CATCH{} clauses is executed depends on whether a matching exception has been raised by $s_1$ (see the specification of the throw statement).
-
-If $s_1$ has raised an exception, it will transfer control to the try statement's handler, which will examine the catch clauses in order for a match as specified above. If no matches are found, the handler will execute the \FINALLY{} clause.
-
-If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FINALLY{} clause will be executed.
-
-If an exception is thrown during execution of an \ON{}-\CATCH{} clause, this will transfer control to the handler for the \FINALLY{} clause, causing the \FINALLY{} clause to execute in this case as well.
-
-If no exception was raised, the \FINALLY{} clause is also executed. Execution of the \FINALLY{} clause could also raise an exception, which will cause transfer of control to the next enclosing handler.
-}
-
-\LMHash{}
 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}.
 
+\LMHash{}
+An \ON{}-\CATCH{} clause of the form  \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is equivalent to an \ON{}-\CATCH{} clause  \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} where $p_2$ is a fresh identifier.
+
+\LMHash{}
+An \ON{}-\CATCH{} clause of the form  \code{\ON{} $T$ $s$} is equivalent to an \ON{}-\CATCH{} clause  \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} where $p_1$ and $p_2$ are fresh identifiers.
+
+\LMHash{}
+An \ON{}-\CATCH{} clause of the form  \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$, $p_2$) $s$} where $p_2$ is a fresh identifier.
+
+An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p_1$, $p_2$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1$, $p_2$) $s$}.
+
+\LMHash{}
+An \ON{}-\CATCH{} clause of the form   \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static type of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}.
+
+\LMHash{}
+Execution of a \TRY{} statement $s$ on the form:
+\begin{dartCode}
+\TRY{} $b$
+\ON{} $T_1$ \CATCH{} ($e_1$, $t_1$) $c_1$
+\ldots{}
+\ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) $c_n$
+\FINALLY{} $f$
+\end{dartCode}
+proceeds as follows:
+
+\LMHash{}
+First $b$ is executed.
+If execution of $b$ throws (\ref{completion}) with exception object $e$ and stack trace $t$, then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses to yield a new completion (\ref{on-catch}).
+
+Then, even if execution of $b$ did not complete normally or matching against the \ON{}-\CATCH{} clauses did not complete normally, the $f$ block is executed.
+
+If execution of $f$ does not complete normally,
+execution of the \TRY{} statement completes in the same way.
+Otherwise if execution of $b$ threw (\ref{completion}), the \TRY{} statement completes in the same way as the matching against the \ON{}-\CATCH{} clauses.
+Otherwise the \TRY{} statement completes in the same way as the execution of $b$.
+
+\LMHash{}
+If $T_1$ is a malformed or deferred type (\ref{staticTypes}), then performing a match causes a run time error.
+It is a static warning if $T_i$, $1 \le i \le n$ is a deferred or malformed type.
+
+\subsubsection{\ON{}-\CATCH{} clauses}
+\LMLabel{on-catch}
+
+\LMHash{}
+Matching an exception object $e$ and stack trace $t$ against a (potentially empty) sequence of \ON{}-\CATCH{} clauses on the form
+\begin{dartCode}
+\ON{} $T_1$ \CATCH{} ($e_1$, $st_1$) \{ $s_1$ \}
+\ldots
+\ON{} $T_n$ \CATCH{} ($e_n$, $st_n$) \{ $s_n$ \}
+\end{dartCode}
+proceeds as follows:
+
+\LMHash{}
+If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching throws the exception object $e$ and stack trace $t$ (\ref{completion}).
+
+\LMHash{}
+Otherwise the exception is matched against the first clause.
+
+\LMHash{}
+Otherwise, if the type of $e$ is a subtype of $T_1$, then the first clause matches, and then $e_1$ is bound to the exception object $e$ and $t_1$ is bound to the stack trace $t$, and $s_1$ is executed in this scope.
+The matching completes in the same way as this execution.
+
+\LMHash{}
+Otherwise, if the first clause did not match $e$, $e$ and $t$ are recursively matched against the remaining \ON{}-\CATCH{} clauses:
+\begin{dartCode}
+\ON{} $T_2$ \CATCH{} ($e_2$, $t_2$) \{ $s_2$ \}
+\ldots
+\ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) \{ $s_n$ \}
+\end{dartCode}
+
 
 \subsection{ Return}
 \LMLabel{return}
 
 \LMHash{}
-The {\em return statement} returns a result to the caller of a synchronous function,  completes the future associated with an asynchronous function or terminates the stream or iterable associated with a generator (\ref{functions}).
+The {\em return statement} returns a result to the caller of a synchronous function, completes the future associated with an asynchronous function or terminates the stream or iterable associated with a generator (\ref{functions}).
 
 
  \begin{grammar}
@@ -6181,31 +6338,12 @@
     .
  \end{grammar}
 
- \commentary{
- Due to \FINALLY{} clauses, the precise behavior of \RETURN{} is a little more involved. Whether the value a return statement is supposed to return is actually returned depends on the behavior of any \FINALLY{} clauses in effect when executing the return. A \FINALLY{} clause may choose to return another value, or throw an exception, or even redirect control flow leading to other returns or throws. All a return statement really does is set a value that is intended to be returned when the function terminates.
- }
-
-\LMHash{}
-The {\em current return value} is a unique value specific to a given function activation. It is undefined unless explicitly set in this specification.
-
 \LMHash{}
 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows:
 
 \LMHash{}
-First the expression $e$ is evaluated, producing an object $o$. Next:
-\begin{itemize}
-\item
-The current return value is set to $o$ and the current exception (\ref{throw}) and active stack trace (\ref{try}) become undefined.
-\item
-Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statement (\ref{try}), if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$.
-\item
-Otherwise execution of the current method terminates.
-\end{itemize}
-
-\commentary{
-In the simplest case, the immediately enclosing function is an ordinary, synchronous non-generator, and upon function termination, the current return value is given to the caller.  The other possibility is that the function is marked \ASYNC{}, in which case the current return value is used to complete the future associated with the function invocation. Both these scenarios are specified in section \ref{functionInvocation}.
-The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), since generators are not allowed to contain a statement of the form \code{\RETURN{} $e$;} as discussed below.
-}
+First the expression $e$ is evaluated, producing an object $o$.
+Then the return statement returns the value $o$ (\ref{completion}).
 
 \LMHash{}
 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing function.
@@ -6249,40 +6387,13 @@
 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this motivates the requirement above.} \commentary{Leaving the return type of a function marked \ASYNC{}  blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future<Object>} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.}
 
 \LMHash{}
-A return statement with no expression, \code{\RETURN;} is executed as follows:
+Executing a return statement with no expression, \code{\RETURN;} returns with no value (\ref{completion}).
 
-\LMHash{}
-If the immediately enclosing function $f$ is a generator, then:
-\begin{itemize}
-\item
-The current return value is set to \NULL{}.
-\item
-Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statement, if any. If $c$ is defined,  let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$.
-\item
-Otherwise, execution of the current method terminates.
-\end{itemize}
-
-\LMHash{}
-Otherwise the return statement is executed by executing the statement  \code{\RETURN{} \NULL{};} if it occurs inside a method, getter, setter or factory; otherwise, the return statement necessarily occurs inside a generative constructor, in which case it is executed by executing  \code{\RETURN{} \THIS{};}.
-
-\commentary{Despite the fact that \code{\RETURN{};} is executed as if by a \code{\RETURN{} $e$;}, it is important to understand that it is not a static warning to include a statement of the form \code{\RETURN{};}
-%in a \VOID{} function; neither is it illegal
-in a generative constructor. The rules relate only to the specific syntactic form \code{\RETURN{} $e$;}.
-}
-
-
-\rationale{
-The motivation for formulating \code{\RETURN{};} in this way stems from the basic requirement that all function invocations indeed return a value. Function invocations are expressions, and we cannot rely on a mandatory typechecker to always prohibit use of \VOID{} functions in expressions. Hence, a return statement must always return a value, even if no expression is specified.
-
-The question then becomes, what value should a return statement return when no return expression is given. In a generative constructor, it is obviously the object being constructed (\THIS{}). A void function is not expected to participate in an expression, which is why it is marked \VOID{} in the first place. Hence, this situation is a mistake which should be detected as soon as possible. The static rules help here, but if the code is executed, using \NULL{} leads to fast failure, which is desirable in this case. The same rationale applies for function bodies that do not contain a return statement at all.
-}
 
 \LMHash{}
 It is a static warning if a  function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}.
 
 
-
-
 \subsection{ Labels}
 \LMLabel{labels}
 
@@ -6300,7 +6411,13 @@
  \end{grammar}
 
 \LMHash{}
- The semantics of a labeled statement $L: s$ are identical to those of the statement $s$. The namespace of labels is distinct from the one used for types, functions and variables.
+Execution a labeled statement $s$, $label: s_l$, consists of executing $s_l$.
+If execution of $s_l$ breaks to the label $label$ (\ref{completion}),
+then execution of $s$ completes normally,
+otherwise execution of $s$ completes in the same ways as the execution of $s_l$.
+
+\LMHash{}
+The namespace of labels is distinct from the one used for types, functions and variables.
 
 \LMHash{}
 The scope of a label that labels a statement $s$ is $s$. The scope of a label that labels a case clause of a switch statement $s$ is $s$.
@@ -6322,11 +6439,12 @@
  \end{grammar}
 
 \LMHash{}
-Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form  \code{\BREAK{} $L$;}, then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_b$. If $s_b$ is of the form \code{\BREAK{};},  then let $s_E$ be the innermost  \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref{while}) statement enclosing  $s_b$. It is a compile-time error if no such statement $s_E$ exists within the innermost function in which  $s_b$ occurs.  Furthermore, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed in $s_E$ and that enclose  $s_b$, and that have a \FINALLY{} clause. Lastly, let $f_j$ be the \FINALLY{} clause of $s_j, 1 \le j \le n$.   Executing  $s_b$ first executes $f_1, \ldots,  f_n$ in innermost-clause-first  order and then terminates $s_E$.
+Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form  \code{\BREAK{} $L$;}, then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_b$. If $s_b$ is of the form \code{\BREAK{};},  then let $s_E$ be the innermost  \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref{while}) statement enclosing  $s_b$. It is a compile-time error if no such statement $s_E$ exists within the innermost function in which  $s_b$ occurs.
 
 \LMHash{}
-If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), its associated stream subscription is canceled. Furthermore, let $a_k$ be the set of asynchronous for loops  and yield-each statements (\ref{yieldEach}) enclosing $s_b$ that are enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$.   The stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, innermost first, so that $a_j$ is canceled before $a_{j+1}$.
+Execution of a \BREAK{} statement \code{\BREAK{} $L$;} breaks to the label $L$ (\ref{completion}).
 
+Execution of a \BREAK{} statement \code{\BREAK{};} breaks without a label (\ref{completion}).
 
 
 \subsection{ Continue}
@@ -6342,25 +6460,23 @@
  \end{grammar}
 
 \LMHash{}
- Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form  \code{\CONTINUE{} $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosing $s_c$. If $s_c$ is of the form \code{\CONTINUE{};}  then let $s_E$ be the innermost  \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement enclosing  $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which  $s_c$ occurs.  Furthermore, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed in $s_E$ and that enclose  $s_c$, and that have a \FINALLY{} clause. Lastly, let $f_j$ be the \FINALLY{} clause of $s_j, 1 \le j \le n$.   Executing  $s_c$ first executes $f_1, \ldots,  f_n$ in innermost-clause-first  order. Then, if $s_E$ is a case clause, control is transferred to the case clause. Otherwise, $s_E$ is necessarily a loop and execution resumes after the last statement in the loop body.
+Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form  \code{\CONTINUE{} $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosing $s_c$. If $s_c$ is of the form \code{\CONTINUE{};}  then let $s_E$ be the innermost  \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement enclosing  $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which  $s_c$ occurs.
 
- \commentary{
- In a while loop, that would be the boolean expression before the body. In a do loop, it would be the boolean expression after the body. In a for loop, it would be the increment clause.  In other words, execution continues to the next iteration of the loop.
- }
+Execution of a \CONTINUE{} statement \code{\CONTINUE{} $L$;} continues to the label $L$ (\ref{completion}).
+
+Execution of a \CONTINUE{} statement \code{\CONTINUE{};} continues without a label (\ref{completion}).
+
+
+\subsection{ Yield and Yield-Each}
+\LMLabel{yieldAndYieldEach}
+
+\subsubsection{ Yield}
+\LMLabel{yield}
 
 \LMHash{}
- If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), let $a_k$ be the set of asynchronous for loops and yield-each statements (\ref{yieldEach}) enclosing $s_c$ that are enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$.   The stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, innermost first, so that $a_j$ is canceled before $a_{j+1}$.
+The {\em yield statement} adds an element to the result of a generator function (\ref{functions}).
 
- \subsection{ Yield and Yield-Each}
- \LMLabel{yieldAndYieldEach}
-
- \subsubsection{ Yield}
- \LMLabel{yield}
-
-\LMHash{}
- The {\em yield statement} adds an element to the result of a generator function (\ref{functions}).
-
- \begin{grammar}
+\begin{grammar}
 {\bf yieldStatement:}
    \YIELD{} expression `{\escapegrammar ;}'
       .
@@ -6370,20 +6486,20 @@
 Execution of a statement $s$ of the form \code{\YIELD{} $e$;}  proceeds as follows:
 
 \LMHash{}
-First, the expression $e$ is evaluated to an object $o$. If the enclosing function $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m$ has been paused,  then execution of $m$ is suspended until $u$ is resumed or canceled.
+First, the expression $e$ is evaluated to an object $o$. If the enclosing function $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m$ has been paused, then the nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused and execution of $m$ is suspended until $u$ is resumed or canceled.
 
 \LMHash{}
 Next, $o$ is added to the iterable or stream associated with the immediately enclosing function.
 
 \LMHash{}
-If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates.
+If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated with $m$ has been canceled, then the \YIELD{} statement returns without a value (\ref{completion}), otherwise it completes normally.
 
 \rationale{
 The stream associated with an asynchronous generator could be canceled by any code with a reference to that stream at any point where the generator was passivated.  Such a cancellation constitutes an irretrievable error for the generator. At this point, the only plausible action for the generator is to clean up after itself via its \FINALLY{} clauses.
 }
 
 \LMHash{}
-Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) then the enclosing function may suspend.
+Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) then the enclosing function may suspend, in which case the nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused first.
 
 \rationale {
 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the  enclosing stream to run and access the data in the stream.  The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we allow the enclosing function to be suspended when a new value is added to its associated stream. However, it is not essential (and in fact, can be quite costly) to suspend the function on every \YIELD{}. The implementation is free to decide how often to suspend the enclosing function. The only requirement is that consumers are not blocked indefinitely.
@@ -6436,7 +6552,7 @@
 \item It is a dynamic error if the class of $o$ does not implement \code{Iterable}.  Otherwise
 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$.
 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Otherwise
-\item The getter \cd{current} is invoked on $i$. If the invocation raises an exception $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the getter invocation is added to the iterable associated with $m$.
+\item The getter \cd{current} is invoked on $i$. If the invocation throws (\ref{evaluation}), execution of $s$ throws the same exception object and stack trace (\ref{completion}). Otherwise, the result $x$ of the getter invocation is added to the iterable associated with $m$.
 Execution of the function $m$ immediately enclosing $s$ is suspended until the nullary method \code{moveNext()} is invoked upon the iterator used to initiate the current invocation of $m$, at which point execution of $s$ continues at \ref{moveNext}.
 \item
 The current call to \code{moveNext()} returns \TRUE.
@@ -6446,16 +6562,19 @@
 If $m$ is marked \ASYNC* (\ref{functions}), then:
 \begin{itemize}
 \item  It is a dynamic error if the class of $o$ does not implement \code{Stream}. Otherwise
-\item For each element $x$ of $o$:
+\item The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused.
+\item The $o$ stream is listened to, creating a subscription $s$, and for each event $x$, or error $e$ with stack trace $t$, of $s$:
 \begin{itemize}
 \item
-If the stream $u$ associated with $m$ has been paused,  then execution of $m$ is suspended until $u$ is resumed or canceled.
- \item
-If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined,  let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates.
+If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled.
 \item
-Otherwise,  $x$ is added to the stream associated with $m$ in the order it appears in $o$.  The function $m$ may suspend.
+If the stream $u$ associated with $m$ has been canceled,
+then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fresh variable referencing the stream subscription $s$.
+Then, if the cancel completed normally, the stream execution of $s$ returns without a value (\ref{completion}).
+\item
+Otherwise, $x$, or $e$ with $t$, are added to the stream associated with $m$ in the order they appear in $o$.  The function $m$ may suspend.
 \end{itemize}
-\item If the stream $o$ is done, execution of $s$ is complete.
+\item If the stream $o$ is done, execution of $s$ completes normally.
 \end{itemize}
 
 
@@ -6474,19 +6593,24 @@
 
 \begin{grammar}
 {\bf assertStatement:}
-   assert `(' expression `)' `{\escapegrammar ;}'
+   assert `(' expression ( `,` expression )? `)' `{\escapegrammar ;}'
       .
 \end{grammar}
 
 \LMHash{}
-The assert statement has no effect in production mode. In checked mode, execution of an assert statement \code{\ASSERT{}($e$);} proceeds as follows:
+An assert statement on the form \code{\ASSERT($e$);)} is equivalent to a statment on the form \code{\ASSERT($e$, null);}.
 
 \LMHash{}
-The expression $e$ is evaluated to an object $o$. If the class of $o$ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ with no arguments. Otherwise, let $r$ be $o$.
-It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Function}, or if $r$ is not of type \code{bool}.  If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, an \code{AssertionError} is thrown.
+The assert statement has no effect in production mode. In checked mode, execution of an assert statement \code{\ASSERT{}($c$, $e$);} proceeds as follows:
 
-%\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} AssertionError();\}} (in checked mode only).
-%What about an error message as part of the assert?}
+\LMHash{}
+The expression $c$ is evaluated to an object $o$. If the class of $o$ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ with no arguments. Otherwise, let $r$ be $o$.
+It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Function}, or if $r$ is not of type \code{bool}.
+If $r$ is \FALSE{}, we say that the assertion failed.
+If $r$ is \TRUE{}, we say that the assertion succeeded.
+If the assertion succeeded, execution of the assert statement completes normally (\ref{completion}).
+If the assertion failed, $e$ is evaluated to an object $m$.
+Then the execution of the assert statement throws (\ref{completion}) an \code{AssertionError} containing $m$ and with a stack trace corresponding to the current execution state at the \ASSERT{} statement.
 
 \LMHash{}
  It is a static type warning if the type of $e$ may not be assigned to either  \code{bool} or $() \rightarrow$ \code{bool}.
@@ -6650,7 +6774,7 @@
 The {\em current library} is the library currently being compiled. The import modifies the  namespace of the current library in a manner that is determined by the imported library and by the optional elements of  the import.
 
 \LMHash{}
-An immediate import directive $I$ may optionally include a prefix clause of the form \AS{} \code{Id} used to prefix names imported by $I$. A deferred import must include a prefix clause or a compile time error occurs. It is a compile-time error if a prefix used in a deferred import is used in another import clause.
+An immediate import directive $I$ may optionally include a prefix clause of the form \code{\AS{} $id$} used to prefix names imported by $I$. A deferred import must include a prefix clause or a compile time error occurs. It is a compile-time error if a prefix used in a deferred import is used in another import clause.
 
 \LMHash{}
 An import directive $I$ may optionally include a namespace combinator clauses used to restrict the set of names imported by $I$. Currently, two namespace combinators are supported: \HIDE{} and \SHOW{}.
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 7d70974..076e01c 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -24,6 +24,7 @@
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal2.dart';
 import 'package:analysis_server/src/single_context_manager.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -119,7 +120,7 @@
   /**
    * The [SearchEngine] for this server, may be `null` if indexing is disabled.
    */
-  final SearchEngine searchEngine;
+  SearchEngine searchEngine;
 
   /**
    * The plugin associated with this analysis server.
@@ -346,7 +347,7 @@
       this.channel,
       this.resourceProvider,
       PubPackageMapProvider packageMapProvider,
-      Index _index,
+      this.index,
       this.serverPlugin,
       this.options,
       this.sdkManager,
@@ -354,9 +355,7 @@
       {ResolverProvider fileResolverProvider: null,
       ResolverProvider packageResolverProvider: null,
       bool useSingleContextManager: false,
-      this.rethrowExceptions: true})
-      : index = _index,
-        searchEngine = _index != null ? new SearchEngineImpl(_index) : null {
+      this.rethrowExceptions: true}) {
     _performance = performanceDuringStartup;
     defaultContextOptions.incremental = true;
     defaultContextOptions.incrementalApi =
@@ -414,6 +413,11 @@
       });
     });
     _setupIndexInvalidation();
+    if (options.enableNewAnalysisDriver) {
+      searchEngine = new SearchEngineImpl2(driverMap.values);
+    } else if (index != null) {
+      searchEngine = new SearchEngineImpl(index);
+    }
     pubSummaryManager =
         new PubSummaryManager(resourceProvider, '${io.pid}.temp');
     Notification notification = new ServerConnectedParams(VERSION, io.pid,
@@ -584,14 +588,21 @@
   }
 
   /**
-   * Return the analysis driver to which the file with the given [path] is
-   * added if exists, otherwise the first driver, otherwise `null`.
+   * Return an analysis driver to which the file with the given [path] is
+   * added if one exists, otherwise a driver in which the file was analyzed if
+   * one exists, otherwise the first driver, otherwise `null`.
    */
   nd.AnalysisDriver getAnalysisDriver(String path) {
     Iterable<nd.AnalysisDriver> drivers = driverMap.values;
     if (drivers.isNotEmpty) {
-      return drivers.firstWhere((driver) => driver.knownFiles.contains(path),
-          orElse: () => drivers.first);
+      nd.AnalysisDriver driver = drivers.firstWhere(
+          (driver) => driver.addedFiles.contains(path),
+          orElse: () => null);
+      driver ??= drivers.firstWhere(
+          (driver) => driver.knownFiles.contains(path),
+          orElse: () => null);
+      driver ??= drivers.first;
+      return driver;
     }
     return null;
   }
@@ -706,41 +717,37 @@
   }
 
   /**
-   * Returns [Element]s at the given [offset] of the given [file].
-   *
-   * May be empty if cannot be resolved, but not `null`.
+   * Return a [Future] that completes with the [Element] at the given
+   * [offset] of the given [file], or with `null` if there is no node at the
+   * [offset] or the node does not have an element.
    */
-  List<Element> getElementsAtOffset(String file, int offset) {
-    List<AstNode> nodes = getNodesAtOffset(file, offset);
-    return getElementsOfNodes(nodes);
+  Future<Element> getElementAtOffset(String file, int offset) async {
+    AstNode node = await getNodeAtOffset(file, offset);
+    return getElementOfNode(node);
   }
 
   /**
-   * Returns [Element]s of the given [nodes].
-   *
-   * May be empty if not resolved, but not `null`.
+   * Return the [Element] of the given [node], or `null` if [node] is `null` or
+   * does not have an element.
    */
-  List<Element> getElementsOfNodes(List<AstNode> nodes) {
-    List<Element> elements = <Element>[];
-    for (AstNode node in nodes) {
-      if (node is SimpleIdentifier && node.parent is LibraryIdentifier) {
-        node = node.parent;
-      }
-      if (node is LibraryIdentifier) {
-        node = node.parent;
-      }
-      if (node is StringLiteral && node.parent is UriBasedDirective) {
-        continue;
-      }
-      Element element = ElementLocator.locate(node);
-      if (node is SimpleIdentifier && element is PrefixElement) {
-        element = getImportElement(node);
-      }
-      if (element != null) {
-        elements.add(element);
-      }
+  Element getElementOfNode(AstNode node) {
+    if (node == null) {
+      return null;
     }
-    return elements;
+    if (node is SimpleIdentifier && node.parent is LibraryIdentifier) {
+      node = node.parent;
+    }
+    if (node is LibraryIdentifier) {
+      node = node.parent;
+    }
+    if (node is StringLiteral && node.parent is UriBasedDirective) {
+      return null;
+    }
+    Element element = ElementLocator.locate(node);
+    if (node is SimpleIdentifier && element is PrefixElement) {
+      element = getImportElement(node);
+    }
+    return element;
   }
 
   /**
@@ -770,49 +777,43 @@
   }
 
   /**
-   * Returns resolved [AstNode]s at the given [offset] of the given [file].
-   *
-   * May be empty, but not `null`.
+   * Return a [Future] that completes with the resolved [AstNode] at the
+   * given [offset] of the given [file], or with `null` if there is no node as
+   * the [offset].
    */
-  List<AstNode> getNodesAtOffset(String file, int offset) {
-    List<CompilationUnit> units = getResolvedCompilationUnits(file);
-    List<AstNode> nodes = <AstNode>[];
-    for (CompilationUnit unit in units) {
-      AstNode node = new NodeLocator(offset).searchWithin(unit);
-      if (node != null) {
-        nodes.add(node);
-      }
+  Future<AstNode> getNodeAtOffset(String file, int offset) async {
+    CompilationUnit unit;
+    if (options.enableNewAnalysisDriver) {
+      nd.AnalysisResult result = await getAnalysisResult(file);
+      unit = result?.unit;
+    } else {
+      unit = await getResolvedCompilationUnit(file);
     }
-    return nodes;
+    if (unit != null) {
+      return new NodeLocator(offset).searchWithin(unit);
+    }
+    return null;
   }
 
   /**
-   * Returns resolved [CompilationUnit]s of the Dart file with the given [path].
-   *
-   * May be empty, but not `null`.
+   * Return a [Future] that completes with the resolved [CompilationUnit] for
+   * the Dart file with the given [path], or with `null` if the file is not a
+   * Dart file or cannot be resolved.
    */
-  List<CompilationUnit> getResolvedCompilationUnits(String path) {
-    List<CompilationUnit> units = <CompilationUnit>[];
+  Future<CompilationUnit> getResolvedCompilationUnit(String path) async {
     ContextSourcePair contextSource = getContextSourcePair(path);
-    // prepare AnalysisContext
     AnalysisContext context = contextSource.context;
     if (context == null) {
-      return units;
+      return null;
     }
-    // add a unit for each unit/library combination
-    runWithActiveContext(context, () {
+    return runWithActiveContext(context, () {
       Source unitSource = contextSource.source;
       List<Source> librarySources = context.getLibrariesContaining(unitSource);
       for (Source librarySource in librarySources) {
-        CompilationUnit unit =
-            context.resolveCompilationUnit2(unitSource, librarySource);
-        if (unit != null) {
-          units.add(unit);
-        }
+        return context.resolveCompilationUnit2(unitSource, librarySource);
       }
+      return null;
     });
-    // done
-    return units;
   }
 
 // TODO(brianwilkerson) Add the following method after 'prioritySources' has
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index eda11af..499fd99 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -90,17 +90,17 @@
     var params = new AnalysisGetHoverParams.fromRequest(request);
 
     // Prepare the resolved units.
-    List<CompilationUnit> units;
+    CompilationUnit unit;
     if (server.options.enableNewAnalysisDriver) {
       AnalysisResult result = await server.getAnalysisResult(params.file);
-      units = result != null ? [result.unit] : null;
+      unit = result?.unit;
     } else {
-      units = server.getResolvedCompilationUnits(params.file);
+      unit = await server.getResolvedCompilationUnit(params.file);
     }
 
     // Prepare the hovers.
     List<HoverInformation> hovers = <HoverInformation>[];
-    for (CompilationUnit unit in units) {
+    if (unit != null) {
       HoverInformation hoverInformation =
           new DartUnitHoverComputer(unit, params.offset).compute();
       if (hoverInformation != null) {
@@ -144,15 +144,14 @@
     if (analysisFuture == null) {
       return new Response.getNavigationInvalidFile(request);
     }
-    analysisFuture.then((AnalysisDoneReason reason) {
+    analysisFuture.then((AnalysisDoneReason reason) async {
       switch (reason) {
         case AnalysisDoneReason.COMPLETE:
-          List<CompilationUnit> units =
-              server.getResolvedCompilationUnits(file);
-          if (units.isEmpty) {
+          CompilationUnit unit = await server.getResolvedCompilationUnit(file);
+          if (unit == null) {
             server.sendResponse(new Response.getNavigationInvalidFile(request));
           } else {
-            CompilationUnitElement unitElement = units.first.element;
+            CompilationUnitElement unitElement = unit.element;
             NavigationCollectorImpl collector = computeNavigation(
                 server,
                 unitElement.context,
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 3ab679a..441a9f4 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -201,27 +201,25 @@
         }
       }
     } else {
-      List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-      for (CompilationUnit unit in units) {
-        engine.AnalysisErrorInfo errorInfo = server.getErrors(file);
-        if (errorInfo != null) {
-          LineInfo lineInfo = errorInfo.lineInfo;
-          int requestLine = lineInfo.getLocation(offset).lineNumber;
-          for (engine.AnalysisError error in errorInfo.errors) {
-            int errorLine = lineInfo.getLocation(error.offset).lineNumber;
-            if (errorLine == requestLine) {
-              List<Fix> fixes = await computeFixes(server.serverPlugin,
-                  server.resourceProvider, unit.element.context, error);
-              if (fixes.isNotEmpty) {
-                AnalysisError serverError =
-                    newAnalysisError_fromEngine(lineInfo, error);
-                AnalysisErrorFixes errorFixes =
-                    new AnalysisErrorFixes(serverError);
-                errorFixesList.add(errorFixes);
-                fixes.forEach((fix) {
-                  errorFixes.fixes.add(fix.change);
-                });
-              }
+      CompilationUnit unit = await server.getResolvedCompilationUnit(file);
+      engine.AnalysisErrorInfo errorInfo = server.getErrors(file);
+      if (errorInfo != null) {
+        LineInfo lineInfo = errorInfo.lineInfo;
+        int requestLine = lineInfo.getLocation(offset).lineNumber;
+        for (engine.AnalysisError error in errorInfo.errors) {
+          int errorLine = lineInfo.getLocation(error.offset).lineNumber;
+          if (errorLine == requestLine) {
+            List<Fix> fixes = await computeFixes(server.serverPlugin,
+                server.resourceProvider, unit.element.context, error);
+            if (fixes.isNotEmpty) {
+              AnalysisError serverError =
+                  newAnalysisError_fromEngine(lineInfo, error);
+              AnalysisErrorFixes errorFixes =
+                  new AnalysisErrorFixes(serverError);
+              errorFixesList.add(errorFixes);
+              fixes.forEach((fix) {
+                errorFixes.fixes.add(fix.change);
+              });
             }
           }
         }
@@ -286,14 +284,13 @@
       unit = result.unit;
       errors = result.errors;
     } else {
-      // prepare resolved units
-      List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-      if (units.isEmpty) {
+      // prepare resolved unit
+      unit = await server.getResolvedCompilationUnit(file);
+      if (unit == null) {
         server.sendResponse(new Response.fileNotAnalyzed(request, file));
         return;
       }
       // prepare context
-      unit = units.first;
       engine.AnalysisContext context = unit.element.context;
       Source source = unit.element.source;
       errors = context.computeErrors(source);
@@ -400,9 +397,8 @@
     }
     // check elements
     {
-      List<Element> elements = server.getElementsAtOffset(file, offset);
-      if (elements.isNotEmpty) {
-        Element element = elements[0];
+      Element element = await server.getElementAtOffset(file, offset);
+      if (element != null) {
         // try CONVERT_METHOD_TO_GETTER
         if (element is ExecutableElement) {
           Refactoring refactoring =
@@ -708,9 +704,8 @@
     }
     // create a new Refactoring instance
     if (kind == RefactoringKind.CONVERT_GETTER_TO_METHOD) {
-      List<Element> elements = server.getElementsAtOffset(file, offset);
-      if (elements.isNotEmpty) {
-        Element element = elements[0];
+      Element element = await server.getElementAtOffset(file, offset);
+      if (element != null) {
         if (element is ExecutableElement) {
           _resetOnAnalysisStarted();
           refactoring =
@@ -719,9 +714,8 @@
       }
     }
     if (kind == RefactoringKind.CONVERT_METHOD_TO_GETTER) {
-      List<Element> elements = server.getElementsAtOffset(file, offset);
-      if (elements.isNotEmpty) {
-        Element element = elements[0];
+      Element element = await server.getElementAtOffset(file, offset);
+      if (element != null) {
         if (element is ExecutableElement) {
           _resetOnAnalysisStarted();
           refactoring =
@@ -730,10 +724,10 @@
       }
     }
     if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
-      List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-      if (units.isNotEmpty) {
+      CompilationUnit unit = await server.getResolvedCompilationUnit(file);
+      if (unit != null) {
         _resetOnFileResolutionChanged(file);
-        refactoring = new ExtractLocalRefactoring(units[0], offset, length);
+        refactoring = new ExtractLocalRefactoring(unit, offset, length);
         feedback = new ExtractLocalVariableFeedback(
             <String>[], <int>[], <int>[],
             coveringExpressionOffsets: <int>[],
@@ -741,29 +735,27 @@
       }
     }
     if (kind == RefactoringKind.EXTRACT_METHOD) {
-      List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-      if (units.isNotEmpty) {
+      CompilationUnit unit = await server.getResolvedCompilationUnit(file);
+      if (unit != null) {
         _resetOnAnalysisStarted();
-        refactoring = new ExtractMethodRefactoring(
-            searchEngine, units[0], offset, length);
+        refactoring =
+            new ExtractMethodRefactoring(searchEngine, unit, offset, length);
         feedback = new ExtractMethodFeedback(offset, length, '', <String>[],
             false, <RefactoringMethodParameter>[], <int>[], <int>[]);
       }
     }
     if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) {
-      List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-      if (units.isNotEmpty) {
+      CompilationUnit unit = await server.getResolvedCompilationUnit(file);
+      if (unit != null) {
         _resetOnFileResolutionChanged(file);
-        refactoring =
-            new InlineLocalRefactoring(searchEngine, units[0], offset);
+        refactoring = new InlineLocalRefactoring(searchEngine, unit, offset);
       }
     }
     if (kind == RefactoringKind.INLINE_METHOD) {
-      List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-      if (units.isNotEmpty) {
+      CompilationUnit unit = await server.getResolvedCompilationUnit(file);
+      if (unit != null) {
         _resetOnAnalysisStarted();
-        refactoring =
-            new InlineMethodRefactoring(searchEngine, units[0], offset);
+        refactoring = new InlineMethodRefactoring(searchEngine, unit, offset);
       }
     }
     if (kind == RefactoringKind.MOVE_FILE) {
@@ -775,11 +767,9 @@
           server.resourceProvider, searchEngine, context, source, file);
     }
     if (kind == RefactoringKind.RENAME) {
-      List<AstNode> nodes = server.getNodesAtOffset(file, offset);
-      List<Element> elements = server.getElementsOfNodes(nodes);
-      if (nodes.isNotEmpty && elements.isNotEmpty) {
-        AstNode node = nodes[0];
-        Element element = elements[0];
+      AstNode node = await server.getNodeAtOffset(file, offset);
+      Element element = server.getElementOfNode(node);
+      if (node != null && element != null) {
         if (element is FieldFormalParameterElement) {
           element = (element as FieldFormalParameterElement).field;
         }
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index dd72b49..0c4c85f 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -35,7 +35,7 @@
       context.isActive = false;
     }
   } else {
-    f();
+    return f();
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 63d5280..476716e 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -10,9 +10,7 @@
     show SearchResult, newSearchResult_fromMatch;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/source.dart';
 
 /**
  * A computer for `search.findElementReferences` request results.
@@ -52,12 +50,6 @@
     List<SearchResult> allResults = <SearchResult>[];
     Iterable<Element> refElements = await _getRefElements(element);
     for (Element refElement in refElements) {
-      // add declaration
-      if (_isDeclarationInteresting(refElement)) {
-        SearchResult searchResult = _newDeclarationResult(refElement);
-        allResults.add(searchResult);
-      }
-      // do search
       List<SearchResult> elementResults =
           await _findSingleElementReferences(refElement);
       allResults.addAll(elementResults);
@@ -90,43 +82,10 @@
     return new Future.value([element]);
   }
 
-  SearchResult _newDeclarationResult(Element refElement) {
-    int nameOffset = refElement.nameOffset;
-    int nameLength = refElement.nameLength;
-    SearchMatch searchMatch = new SearchMatchImpl(
-        refElement.context,
-        refElement.library.source.uri.toString(),
-        refElement.source.uri.toString(),
-        MatchKind.DECLARATION,
-        new SourceRange(nameOffset, nameLength),
-        true,
-        false);
-    return newSearchResult_fromMatch(searchMatch);
-  }
-
   static SearchResult toResult(SearchMatch match) {
     return newSearchResult_fromMatch(match);
   }
 
-  static bool _isDeclarationInteresting(Element element) {
-    if (element is LabelElement) {
-      return true;
-    }
-    if (element is LocalVariableElement) {
-      return true;
-    }
-    if (element is ParameterElement) {
-      return true;
-    }
-    if (element is PrefixElement) {
-      return true;
-    }
-    if (element is PropertyInducingElement) {
-      return !element.isSynthetic;
-    }
-    return false;
-  }
-
   static bool _isMemberElement(Element element) {
     if (element is ConstructorElement) {
       return false;
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index b77f2df..9031325 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -49,51 +49,38 @@
         searchEngine = server.searchEngine;
 
   Future findElementReferences(protocol.Request request) async {
-    if (server.options.enableNewAnalysisDriver) {
-      // TODO(scheglov) implement for the new analysis driver
-      String searchId = (_nextSearchId++).toString();
-      var result = new protocol.SearchFindElementReferencesResult();
-      result.id = searchId;
-      _sendSearchResult(request, result);
-      _sendSearchNotification(searchId, true, <protocol.SearchResult>[]);
-      return;
-    }
     var params =
         new protocol.SearchFindElementReferencesParams.fromRequest(request);
-    await server.onAnalysisComplete;
-    // prepare elements
-    List<Element> elements =
-        server.getElementsAtOffset(params.file, params.offset);
-    elements = elements.map((Element element) {
-      if (element is ImportElement) {
-        return element.prefix;
-      }
-      if (element is FieldFormalParameterElement) {
-        return element.field;
-      }
-      if (element is PropertyAccessorElement) {
-        return element.variable;
-      }
-      return element;
-    }).where((Element element) {
-      return element != null;
-    }).toList();
+    String file = params.file;
+    // prepare element
+    if (!server.options.enableNewAnalysisDriver) {
+      await server.onAnalysisComplete;
+    }
+    Element element = await server.getElementAtOffset(file, params.offset);
+    if (element is ImportElement) {
+      element = (element as ImportElement).prefix;
+    }
+    if (element is FieldFormalParameterElement) {
+      element = (element as FieldFormalParameterElement).field;
+    }
+    if (element is PropertyAccessorElement) {
+      element = (element as PropertyAccessorElement).variable;
+    }
     // respond
     String searchId = (_nextSearchId++).toString();
     var result = new protocol.SearchFindElementReferencesResult();
-    if (elements.isNotEmpty) {
+    if (element != null) {
       result.id = searchId;
-      result.element = protocol.convertElement(elements.first);
+      result.element = protocol.convertElement(element);
     }
     _sendSearchResult(request, result);
     // search elements
-    elements.forEach((Element element) async {
+    if (element != null) {
       var computer = new ElementReferencesComputer(searchEngine);
       List<protocol.SearchResult> results =
           await computer.compute(element, params.includePotential);
-      bool isLast = identical(element, elements.last);
-      _sendSearchNotification(searchId, isLast, results);
-    });
+      _sendSearchNotification(searchId, true, results);
+    }
   }
 
   Future findMemberDeclarations(protocol.Request request) async {
@@ -171,12 +158,11 @@
       await server.onAnalysisComplete;
     }
     // prepare element
-    List<Element> elements = server.getElementsAtOffset(file, params.offset);
-    if (elements.isEmpty) {
+    Element element = await server.getElementAtOffset(file, params.offset);
+    if (element == null) {
       _sendTypeHierarchyNull(request);
       return;
     }
-    Element element = elements.first;
     // maybe supertype hierarchy only
     if (params.superOnly == true) {
       TypeHierarchyComputer computer =
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index 85aabea..85c3557 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/channel/web_socket_channel.dart';
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analysis_server/src/status/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler2.dart';
 
 /**
  * Instances of the class [HttpServer] implement a simple HTTP server. The
@@ -31,7 +32,7 @@
   /**
    * An object that can handle GET requests.
    */
-  GetHandler getHandler;
+  AbstractGetHandler getHandler;
 
   /**
    * Future that is completed with the HTTP server once it is running.
@@ -78,7 +79,11 @@
    */
   void _handleGetRequest(HttpRequest request) {
     if (getHandler == null) {
-      getHandler = new GetHandler(socketServer, _printBuffer);
+      if (socketServer.analysisServer.options.enableNewAnalysisDriver) {
+        getHandler = new GetHandler2(socketServer, _printBuffer);
+      } else {
+        getHandler = new GetHandler(socketServer, _printBuffer);
+      }
     }
     getHandler.handleGetRequest(request);
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 1a886be..76ee0e1 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -285,15 +285,17 @@
                 .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
       // make class abstract
       _addFix_makeEnclosingClassAbstract();
-      // implement methods
-      AnalysisErrorWithProperties errorWithProperties =
-          error as AnalysisErrorWithProperties;
-      Object property =
-          errorWithProperties.getProperty(ErrorProperty.UNIMPLEMENTED_METHODS);
-      List<ExecutableElement> missingOverrides =
-          property as List<ExecutableElement>;
-      _addFix_createMissingOverrides(missingOverrides);
       _addFix_createNoSuchMethod();
+      // implement methods
+      // TODO(scheglov) Fix another way to get unimplemented methods.
+      // AnalysisErrorWithProperties does not work with the new analysis driver.
+      if (error is AnalysisErrorWithProperties) {
+        AnalysisErrorWithProperties errorWithProperties =
+            error as AnalysisErrorWithProperties;
+        List<ExecutableElement> missingOverrides = errorWithProperties
+            .getProperty(ErrorProperty.UNIMPLEMENTED_METHODS);
+        _addFix_createMissingOverrides(missingOverrides);
+      }
     }
     if (errorCode == StaticWarningCode.CAST_TO_NON_TYPE ||
         errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME ||
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
new file mode 100644
index 0000000..72cd494
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/search.dart';
+import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
+
+/**
+ * A [SearchEngine] implementation.
+ */
+class SearchEngineImpl2 implements SearchEngine {
+  final Iterable<AnalysisDriver> _drivers;
+
+  SearchEngineImpl2(this._drivers);
+
+  @override
+  Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) async {
+    // TODO(scheglov) implement
+    return [];
+  }
+
+  @override
+  Future<List<SearchMatch>> searchMemberDeclarations(String name) async {
+    // TODO(scheglov) implement
+    return [];
+  }
+
+  @override
+  Future<List<SearchMatch>> searchMemberReferences(String name) async {
+    // TODO(scheglov) implement
+    return [];
+  }
+
+  @override
+  Future<List<SearchMatch>> searchReferences(Element element) async {
+    List<SearchResult> allResults = [];
+    for (AnalysisDriver driver in _drivers) {
+      List<SearchResult> results = await driver.search.references(element);
+      allResults.addAll(results);
+    }
+    return allResults.map(_SearchMatch.forSearchResult).toList();
+  }
+
+  @override
+  Future<List<SearchMatch>> searchSubtypes(ClassElement type) async {
+    // TODO(scheglov) implement
+    return [];
+  }
+
+  @override
+  Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) async {
+    // TODO(scheglov) implement
+    return [];
+  }
+}
+
+class _SearchMatch implements SearchMatch {
+  @override
+  final String file;
+
+  @override
+  final Source librarySource;
+
+  @override
+  final Source unitSource;
+
+  @override
+  final LibraryElement libraryElement;
+
+  @override
+  final Element element;
+
+  @override
+  final bool isResolved;
+
+  @override
+  final bool isQualified;
+
+  @override
+  final MatchKind kind;
+
+  @override
+  final SourceRange sourceRange;
+
+  _SearchMatch(
+      this.file,
+      this.librarySource,
+      this.unitSource,
+      this.libraryElement,
+      this.element,
+      this.isResolved,
+      this.isQualified,
+      this.kind,
+      this.sourceRange);
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("SearchMatch(kind=");
+    buffer.write(kind);
+    buffer.write(", libraryUri=");
+    buffer.write(librarySource.uri);
+    buffer.write(", unitUri=");
+    buffer.write(unitSource.uri);
+    buffer.write(", range=");
+    buffer.write(sourceRange);
+    buffer.write(", isResolved=");
+    buffer.write(isResolved);
+    buffer.write(", isQualified=");
+    buffer.write(isQualified);
+    buffer.write(")");
+    return buffer.toString();
+  }
+
+  static _SearchMatch forSearchResult(SearchResult result) {
+    Element enclosingElement = result.enclosingElement;
+    return new _SearchMatch(
+        enclosingElement.source.fullName,
+        enclosingElement.librarySource,
+        enclosingElement.source,
+        enclosingElement.library,
+        enclosingElement,
+        result.isResolved,
+        result.isQualified,
+        toMatchKind(result.kind),
+        new SourceRange(result.offset, result.length));
+  }
+
+  static MatchKind toMatchKind(SearchResultKind kind) {
+    if (kind == SearchResultKind.READ) {
+      return MatchKind.READ;
+    }
+    if (kind == SearchResultKind.READ_WRITE) {
+      return MatchKind.READ_WRITE;
+    }
+    if (kind == SearchResultKind.WRITE) {
+      return MatchKind.WRITE;
+    }
+    if (kind == SearchResultKind.INVOCATION) {
+      return MatchKind.INVOCATION;
+    }
+    return MatchKind.REFERENCE;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 32ba194..d6ed6eb 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -46,8 +46,6 @@
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/task/options.dart'
-    show CONFIGURED_ERROR_PROCESSORS;
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/html.dart';
@@ -61,6 +59,16 @@
  */
 typedef void HtmlGenerator(StringBuffer buffer);
 
+/**
+ * Instances of the class [AbstractGetHandler] handle GET requests.
+ */
+abstract class AbstractGetHandler {
+  /**
+   * Handle a GET request received by the HTTP server.
+   */
+  void handleGetRequest(HttpRequest request);
+}
+
 class ElementCounter extends RecursiveElementVisitor {
   Map<Type, int> counts = new HashMap<Type, int>();
   int elementsWithDocs = 0;
@@ -199,7 +207,7 @@
 /**
  * Instances of the class [GetHandler] handle GET requests.
  */
-class GetHandler {
+class GetHandler implements AbstractGetHandler {
   /**
    * The path used to request overall performance information.
    */
@@ -1408,8 +1416,6 @@
       _writeOption(
           buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
       _writeOption(
-          buffer, 'Enable generic methods', options.enableGenericMethods);
-      _writeOption(
           buffer, 'Enable strict call checks', options.enableStrictCallChecks);
       _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
       _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
@@ -1452,8 +1458,7 @@
             });
           },
           (StringBuffer buffer) {
-            List<Linter> lints =
-                context.getConfigurationData(CONFIGURED_LINTS_KEY);
+            List<Linter> lints = context.analysisOptions.lintRules;
             buffer.write('<p><b>Lints</b></p>');
             if (lints.isEmpty) {
               buffer.write('<p>none</p>');
@@ -1466,7 +1471,7 @@
             }
 
             List<ErrorProcessor> errorProcessors =
-                context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+                context.analysisOptions.errorProcessors;
             int processorCount = errorProcessors?.length ?? 0;
             buffer
                 .write('<p><b>Error Processor count</b>: $processorCount</p>');
@@ -2511,6 +2516,9 @@
       }
       buffer.write('<p>');
       buffer.write('Status: Running<br>');
+      buffer.write('New analysis driver: ');
+      buffer.write(analysisServer.options.enableNewAnalysisDriver);
+      buffer.write('<br>');
       buffer.write('Instrumentation: ');
       if (AnalysisEngine.instance.instrumentationService.isActive) {
         buffer.write('<span style="color:red">Active</span>');
diff --git a/pkg/analysis_server/lib/src/status/get_handler2.dart b/pkg/analysis_server/lib/src/status/get_handler2.dart
new file mode 100644
index 0000000..8bd958e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/get_handler2.dart
@@ -0,0 +1,1242 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/domain_diagnostic.dart';
+import 'package:analysis_server/src/domain_execution.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/socket_server.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
+import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/context/source.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * A function that can be used to generate HTML output into the given [buffer].
+ * The HTML that is generated must be valid (special characters must already be
+ * encoded).
+ */
+typedef void HtmlGenerator(StringBuffer buffer);
+
+/**
+ * Instances of the class [GetHandler2] handle GET requests.
+ */
+class GetHandler2 implements AbstractGetHandler {
+  /**
+   * The path used to request overall performance information.
+   */
+  static const String ANALYSIS_PERFORMANCE_PATH = '/perf/analysis';
+
+  /**
+   * The path used to request code completion information.
+   */
+  static const String COMPLETION_PATH = '/completion';
+
+  /**
+   * The path used to request communication performance information.
+   */
+  static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
+
+  /**
+   * The path used to request information about a specific context.
+   */
+  static const String CONTEXT_PATH = '/context';
+
+  /**
+   * The path used to request an overlay contents.
+   */
+  static const String OVERLAY_PATH = '/overlay';
+
+  /**
+   * The path used to request overlays information.
+   */
+  static const String OVERLAYS_PATH = '/overlays';
+
+  /**
+   * The path used to request the status of the analysis server as a whole.
+   */
+  static const String STATUS_PATH = '/status';
+
+  /**
+   * Query parameter used to represent the context to search for.
+   */
+  static const String CONTEXT_QUERY_PARAM = 'context';
+
+  /**
+   * Query parameter used to represent the path of an overlayed file.
+   */
+  static const String PATH_PARAM = 'path';
+
+  static final ContentType _htmlContent =
+      new ContentType("text", "html", charset: "utf-8");
+
+  /**
+   * The socket server whose status is to be reported on.
+   */
+  SocketServer _server;
+
+  /**
+   * Buffer containing strings printed by the analysis server.
+   */
+  List<String> _printBuffer;
+
+  /**
+   * Contents of overlay files.
+   */
+  final Map<String, String> _overlayContents = <String, String>{};
+
+  /**
+   * Handler for diagnostics requests.
+   */
+  DiagnosticDomainHandler _diagnosticHandler;
+
+  /**
+   * Initialize a newly created handler for GET requests.
+   */
+  GetHandler2(this._server, this._printBuffer);
+
+  DiagnosticDomainHandler get diagnosticHandler {
+    if (_diagnosticHandler == null) {
+      _diagnosticHandler = new DiagnosticDomainHandler(_server.analysisServer);
+    }
+    return _diagnosticHandler;
+  }
+
+  /**
+   * Return the active [CompletionDomainHandler]
+   * or `null` if either analysis server is not running
+   * or there is no completion domain handler.
+   */
+  CompletionDomainHandler get _completionDomainHandler {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return null;
+    }
+    return analysisServer.handlers
+        .firstWhere((h) => h is CompletionDomainHandler, orElse: () => null);
+  }
+
+  /**
+   * Handle a GET request received by the HTTP server.
+   */
+  void handleGetRequest(HttpRequest request) {
+    String path = request.uri.path;
+    if (path == '/' || path == STATUS_PATH) {
+      _returnServerStatus(request);
+    } else if (path == ANALYSIS_PERFORMANCE_PATH) {
+      _returnAnalysisPerformance(request);
+    } else if (path == COMPLETION_PATH) {
+      _returnCompletionInfo(request);
+    } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
+      _returnCommunicationPerformance(request);
+    } else if (path == CONTEXT_PATH) {
+      _returnContextInfo(request);
+    } else if (path == OVERLAY_PATH) {
+      _returnOverlayContents(request);
+    } else if (path == OVERLAYS_PATH) {
+      _returnOverlaysInfo(request);
+    } else {
+      _returnUnknownRequest(request);
+    }
+  }
+
+  /**
+   * Return the folder being managed by the given [analysisServer] that matches
+   * the given [contextFilter], or `null` if there is none.
+   */
+  Folder _findFolder(AnalysisServer analysisServer, String contextFilter) {
+    return analysisServer.driverMap.keys.firstWhere(
+        (Folder folder) => folder.path == contextFilter,
+        orElse: () => null);
+  }
+
+  /**
+   * Return `true` if the given analysis [driver] has at least one entry with
+   * an exception.
+   */
+  bool _hasException(AnalysisDriver driver) {
+//    if (driver == null) {
+//      return false;
+//    }
+//    MapIterator<AnalysisTarget, CacheEntry> iterator =
+//        context.analysisCache.iterator();
+//    while (iterator.moveNext()) {
+//      CacheEntry entry = iterator.value;
+//      if (entry == null || entry.exception != null) {
+//        return true;
+//      }
+//    }
+    // TODO(scheglov)
+    return false;
+  }
+
+  /**
+   * Return a response displaying overall performance information.
+   */
+  void _returnAnalysisPerformance(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Analysis Performance', [],
+          (StringBuffer buffer) {
+        buffer.write('<h3>Analysis Performance</h3>');
+        _writeTwoColumns(buffer, (StringBuffer buffer) {
+          //
+          // Write performance tags.
+          //
+          buffer.write('<p><b>Performance tag data</b></p>');
+          buffer.write(
+              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+          _writeRow(buffer, ['Time (in ms)', 'Percent', 'Tag name'],
+              header: true);
+          // prepare sorted tags
+          List<PerformanceTag> tags = PerformanceTag.all.toList();
+          tags.remove(ServerPerformanceStatistics.idle);
+          tags.sort((a, b) => b.elapsedMs - a.elapsedMs);
+          // prepare total time
+          int totalTagTime = 0;
+          tags.forEach((PerformanceTag tag) {
+            totalTagTime += tag.elapsedMs;
+          });
+          // write rows
+          void writeRow(PerformanceTag tag) {
+            double percent = (tag.elapsedMs * 100) / totalTagTime;
+            String percentStr = '${percent.toStringAsFixed(2)}%';
+            _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
+                classes: ["right", "right", null]);
+          }
+
+          tags.forEach(writeRow);
+          buffer.write('</table>');
+        }, (StringBuffer buffer) {
+          //
+          // Write task model timing information.
+          //
+          buffer.write('<p><b>Task performance data</b></p>');
+          buffer.write(
+              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+          _writeRow(
+              buffer,
+              [
+                'Task Name',
+                'Count',
+                'Total Time (in ms)',
+                'Average Time (in ms)'
+              ],
+              header: true);
+
+          Map<Type, int> countMap = AnalysisTask.countMap;
+          Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap;
+          List<Type> taskClasses = stopwatchMap.keys.toList();
+          taskClasses.sort((Type first, Type second) =>
+              first.toString().compareTo(second.toString()));
+          int totalTaskTime = 0;
+          taskClasses.forEach((Type taskClass) {
+            int count = countMap[taskClass];
+            if (count == null) {
+              count = 0;
+            }
+            int taskTime = stopwatchMap[taskClass].elapsedMilliseconds;
+            totalTaskTime += taskTime;
+            _writeRow(buffer, [
+              taskClass.toString(),
+              count,
+              taskTime,
+              count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
+            ], classes: [
+              null,
+              "right",
+              "right",
+              "right"
+            ]);
+          });
+          _writeRow(buffer, ['Total', '-', totalTaskTime, '-'],
+              classes: [null, "right", "right", "right"]);
+          buffer.write('</table>');
+        });
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying overall performance information.
+   */
+  void _returnCommunicationPerformance(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Communication Performance', [],
+          (StringBuffer buffer) {
+        buffer.write('<h3>Communication Performance</h3>');
+        _writeTwoColumns(buffer, (StringBuffer buffer) {
+          ServerPerformance perf = analysisServer.performanceDuringStartup;
+          int requestCount = perf.requestCount;
+          num averageLatency = requestCount > 0
+              ? (perf.requestLatency / requestCount).round()
+              : 0;
+          int maximumLatency = perf.maxLatency;
+          num slowRequestPercent = requestCount > 0
+              ? (perf.slowRequestCount * 100 / requestCount).round()
+              : 0;
+          buffer.write('<h4>Startup</h4>');
+          buffer.write('<table>');
+          _writeRow(buffer, [requestCount, 'requests'],
+              classes: ["right", null]);
+          _writeRow(buffer, [averageLatency, 'ms average latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
+              classes: ["right", null]);
+          if (analysisServer.performanceAfterStartup != null) {
+            int startupTime = analysisServer.performanceAfterStartup.startTime -
+                perf.startTime;
+            _writeRow(
+                buffer, [startupTime, 'ms for initial analysis to complete']);
+          }
+          buffer.write('</table>');
+        }, (StringBuffer buffer) {
+          ServerPerformance perf = analysisServer.performanceAfterStartup;
+          if (perf == null) {
+            return;
+          }
+          int requestCount = perf.requestCount;
+          num averageLatency = requestCount > 0
+              ? (perf.requestLatency * 10 / requestCount).round() / 10
+              : 0;
+          int maximumLatency = perf.maxLatency;
+          num slowRequestPercent = requestCount > 0
+              ? (perf.slowRequestCount * 100 / requestCount).round()
+              : 0;
+          buffer.write('<h4>Current</h4>');
+          buffer.write('<table>');
+          _writeRow(buffer, [requestCount, 'requests'],
+              classes: ["right", null]);
+          _writeRow(buffer, [averageLatency, 'ms average latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
+              classes: ["right", null]);
+          buffer.write('</table>');
+        });
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying code completion information.
+   */
+  void _returnCompletionInfo(HttpRequest request) {
+    String value = request.requestedUri.queryParameters['index'];
+    int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Completion Stats', [],
+          (StringBuffer buffer) {
+        _writeCompletionPerformanceDetail(buffer, index);
+        _writeCompletionPerformanceList(buffer);
+      });
+    });
+  }
+
+  /**
+   * Return a response containing information about a single source file in the
+   * cache.
+   */
+  void _returnContextInfo(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    AnalysisDriver driver = null;
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    } else {
+      driver = analysisServer.driverMap[folder];
+    }
+
+    // TODO(scheglov) Show priority files.
+//    List<String> priorityNames = <String>[];
+    List<String> addedFiles = driver.addedFiles.toList();
+    List<String> implicitFiles =
+        driver.knownFiles.difference(driver.addedFiles).toList();
+    addedFiles.sort();
+    implicitFiles.sort();
+
+    // TODO(scheglov) Use file overlays.
+//    _overlayContents.clear();
+//    context.visitContentCache((String fullName, int stamp, String contents) {
+//      _overlayContents[fullName] = contents;
+//    });
+
+    void _writeFiles(StringBuffer buffer, String title, List<String> files) {
+      buffer.write('<h3>$title</h3>');
+      if (files == null || files.isEmpty) {
+        buffer.write('<p>None</p>');
+      } else {
+        buffer.write('<p><table style="width: 100%">');
+        for (String file in files) {
+          buffer.write('<tr><td>');
+          buffer.write(file);
+          buffer.write('</td><td>');
+          if (_overlayContents.containsKey(files)) {
+            buffer.write(makeLink(OVERLAY_PATH, {PATH_PARAM: file}, 'overlay'));
+          }
+          buffer.write('</td></tr>');
+        }
+        buffer.write('</table></p>');
+      }
+    }
+
+    void writeOptions(StringBuffer buffer, AnalysisOptionsImpl options,
+        {void writeAdditionalOptions(StringBuffer buffer)}) {
+      if (options == null) {
+        buffer.write('<p>No option information available.</p>');
+        return;
+      }
+      buffer.write('<p>');
+      _writeOption(
+          buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
+      _writeOption(
+          buffer, 'Enable strict call checks', options.enableStrictCallChecks);
+      _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
+      _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
+      _writeOption(buffer, 'Generate errors in implicit files',
+          options.generateImplicitErrors);
+      _writeOption(
+          buffer, 'Generate errors in SDK files', options.generateSdkErrors);
+      _writeOption(buffer, 'Generate hints', options.hint);
+      _writeOption(buffer, 'Incremental resolution', options.incremental);
+      _writeOption(buffer, 'Incremental resolution with API changes',
+          options.incrementalApi);
+      _writeOption(buffer, 'Preserve comments', options.preserveComments);
+      _writeOption(buffer, 'Strong mode', options.strongMode);
+      _writeOption(buffer, 'Strong mode hints', options.strongModeHints);
+      if (writeAdditionalOptions != null) {
+        writeAdditionalOptions(buffer);
+      }
+      buffer.write('</p>');
+    }
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(
+          buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
+          (StringBuffer buffer) {
+        buffer.write('<h3>Configuration</h3>');
+
+        _writeColumns(buffer, <HtmlGenerator>[
+          (StringBuffer buffer) {
+            buffer.write('<p><b>Context Options</b></p>');
+            writeOptions(buffer, driver.analysisOptions);
+          },
+          (StringBuffer buffer) {
+            buffer.write('<p><b>SDK Context Options</b></p>');
+            DartSdk sdk = driver?.sourceFactory?.dartSdk;
+            writeOptions(buffer, sdk?.context?.analysisOptions,
+                writeAdditionalOptions: (StringBuffer buffer) {
+              if (sdk is FolderBasedDartSdk) {
+                _writeOption(buffer, 'Use summaries', sdk.useSummary);
+              }
+            });
+          },
+          (StringBuffer buffer) {
+            List<Linter> lints = driver.analysisOptions.lintRules;
+            buffer.write('<p><b>Lints</b></p>');
+            if (lints.isEmpty) {
+              buffer.write('<p>none</p>');
+            } else {
+              for (Linter lint in lints) {
+                buffer.write('<p>');
+                buffer.write(lint.runtimeType);
+                buffer.write('</p>');
+              }
+            }
+
+            List<ErrorProcessor> errorProcessors =
+                driver.analysisOptions.errorProcessors;
+            int processorCount = errorProcessors?.length ?? 0;
+            buffer
+                .write('<p><b>Error Processor count</b>: $processorCount</p>');
+          }
+        ]);
+
+        SourceFactory sourceFactory = driver.sourceFactory;
+        if (sourceFactory is SourceFactoryImpl) {
+          buffer.write('<h3>Resolvers</h3>');
+          for (UriResolver resolver in sourceFactory.resolvers) {
+            buffer.write('<p>');
+            buffer.write(resolver.runtimeType);
+            if (resolver is DartUriResolver) {
+              DartSdk sdk = resolver.dartSdk;
+              buffer.write(' (sdk = ');
+              buffer.write(sdk.runtimeType);
+              if (sdk is FolderBasedDartSdk) {
+                buffer.write(' (path = ');
+                buffer.write(sdk.directory.path);
+                buffer.write(')');
+              } else if (sdk is EmbedderSdk) {
+                buffer.write(' (map = ');
+                _writeMapOfStringToString(buffer, sdk.urlMappings);
+                buffer.write(')');
+              }
+              buffer.write(')');
+            } else if (resolver is SdkExtUriResolver) {
+              buffer.write(' (map = ');
+              _writeMapOfStringToString(buffer, resolver.urlMappings);
+              buffer.write(')');
+            }
+            buffer.write('</p>');
+          }
+        }
+
+        // TODO(scheglov) Show priority files.
+//        _writeFiles(
+//            buffer, 'Priority Files (${priorityNames.length})', priorityNames);
+        _writeFiles(buffer, 'Added Files (${addedFiles.length})', addedFiles);
+        _writeFiles(
+            buffer,
+            'Implicitly Analyzed Files (${implicitFiles.length})',
+            implicitFiles);
+
+        // TODO(scheglov) Show exceptions.
+//        buffer.write('<h3>Exceptions</h3>');
+//        if (exceptions.isEmpty) {
+//          buffer.write('<p>none</p>');
+//        } else {
+//          exceptions.forEach((CaughtException exception) {
+//            _writeException(buffer, exception);
+//          });
+//        }
+      });
+    });
+  }
+
+  void _returnFailure(HttpRequest request, String message) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Failure', [],
+          (StringBuffer buffer) {
+        buffer.write(HTML_ESCAPE.convert(message));
+      });
+    });
+  }
+
+  void _returnOverlayContents(HttpRequest request) {
+    String path = request.requestedUri.queryParameters[PATH_PARAM];
+    if (path == null) {
+      return _returnFailure(request, 'Query parameter $PATH_PARAM required');
+    }
+    String contents = _overlayContents[path];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Overlay', [],
+          (StringBuffer buffer) {
+        buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying overlays information.
+   */
+  void _returnOverlaysInfo(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Overlays', [],
+          (StringBuffer buffer) {
+        buffer.write('<table border="1">');
+        _overlayContents.clear();
+        ContentCache overlayState = analysisServer.overlayState;
+        overlayState.accept((String fullName, int stamp, String contents) {
+          buffer.write('<tr>');
+          String link =
+              makeLink(OVERLAY_PATH, {PATH_PARAM: fullName}, fullName);
+          DateTime time = new DateTime.fromMillisecondsSinceEpoch(stamp);
+          _writeRow(buffer, [link, time]);
+          _overlayContents[fullName] = contents;
+        });
+        int count = _overlayContents.length;
+        buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
+        buffer.write('</table>');
+      });
+    });
+  }
+
+  /**
+   * Return a response indicating the status of the analysis server.
+   */
+  void _returnServerStatus(HttpRequest request) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
+        if (_writeServerStatus(buffer)) {
+          _writeAnalysisStatus(buffer);
+          _writeEditStatus(buffer);
+          _writeExecutionStatus(buffer);
+          _writePluginStatus(buffer);
+          _writeRecentOutput(buffer);
+        }
+      });
+    });
+  }
+
+  /**
+   * Return an error in response to an unrecognized request received by the HTTP
+   * server.
+   */
+  void _returnUnknownRequest(HttpRequest request) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
+        buffer.write('<h3>Unknown page: ');
+        buffer.write(request.uri.path);
+        buffer.write('</h3>');
+        buffer.write('''
+        <p>
+        You have reached an un-recognized page. If you reached this page by
+        following a link from a status page, please report the broken link to
+        the Dart analyzer team:
+        <a>https://github.com/dart-lang/sdk/issues/new</a>.
+        </p><p>
+        If you mistyped the URL, you can correct it or return to
+        ${makeLink(STATUS_PATH, {}, 'the main status page')}.
+        </p>''');
+      });
+    });
+  }
+
+  /**
+   * Return a two digit decimal representation of the given non-negative integer
+   * [value].
+   */
+  String _twoDigit(int value) {
+    if (value < 10) {
+      return '0$value';
+    }
+    return value.toString();
+  }
+
+  /**
+   * Write the status of the analysis domain (on the main status page) to the
+   * given [buffer] object.
+   */
+  void _writeAnalysisStatus(StringBuffer buffer) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    Map<Folder, AnalysisDriver> driverMap = analysisServer.driverMap;
+    List<Folder> folders = driverMap.keys.toList();
+    folders.sort((Folder first, Folder second) =>
+        first.shortName.compareTo(second.shortName));
+
+    buffer.write('<h3>Analysis Domain</h3>');
+    _writeTwoColumns(buffer, (StringBuffer buffer) {
+      buffer.write('<p>Using package resolver provider: ');
+      buffer.write(_server.packageResolverProvider != null);
+      buffer.write('</p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(OVERLAYS_PATH, {}, 'All overlay information'));
+      buffer.write('</p>');
+
+      buffer.write('<p><b>Analysis Contexts</b></p>');
+      buffer.write('<p>');
+      bool first = true;
+      folders.forEach((Folder folder) {
+        if (first) {
+          first = false;
+        } else {
+          buffer.write('<br>');
+        }
+        String key = folder.shortName;
+        buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
+            key, _hasException(driverMap[folder])));
+        if (!folder.getChild('.packages').exists) {
+          buffer.write(' <small>[no .packages file]</small>');
+        }
+      });
+      buffer.write('</p>');
+
+      int freq = AnalysisServer.performOperationDelayFrequency;
+      String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
+
+      buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>Perform operation delay: $delay</p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
+      buffer.write('</p>');
+    }, (StringBuffer buffer) {
+      _writeSubscriptionMap(
+          buffer, AnalysisService.VALUES, analysisServer.analysisServices);
+    });
+  }
+
+  /**
+   * Write multiple columns of information to the given [buffer], where the list
+   * of [columns] functions are used to generate the content of those columns.
+   */
+  void _writeColumns(StringBuffer buffer, List<HtmlGenerator> columns) {
+    buffer
+        .write('<table class="column"><tr class="column"><td class="column">');
+    int count = columns.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write('</td><td class="column">');
+      }
+      columns[i](buffer);
+    }
+    buffer.write('</td></tr></table>');
+  }
+
+  /**
+   * Write performance information about a specific completion request
+   * to the given [buffer] object.
+   */
+  void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
+    CompletionDomainHandler handler = _completionDomainHandler;
+    CompletionPerformance performance;
+    if (handler != null) {
+      List<CompletionPerformance> list = handler.performanceList;
+      if (list != null && list.isNotEmpty) {
+        performance = list[max(0, min(list.length - 1, index))];
+      }
+    }
+    if (performance == null) {
+      buffer.write('<h3>Completion Performance Detail</h3>');
+      buffer.write('<p>No completions yet</p>');
+      return;
+    }
+    buffer.write('<h3>Completion Performance Detail</h3>');
+    buffer.write('<p>${performance.startTimeAndMs} for ${performance.source}');
+    buffer.write('<table>');
+    _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
+    performance.operations.forEach((OperationPerformance op) {
+      String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
+      _writeRow(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
+    });
+    buffer.write('</table>');
+    buffer.write('<p><b>Compute Cache Performance</b>: ');
+    if (handler.computeCachePerformance == null) {
+      buffer.write('none');
+    } else {
+      int elapsed = handler.computeCachePerformance.elapsedInMilliseconds;
+      Source source = handler.computeCachePerformance.source;
+      buffer.write(' $elapsed ms for $source');
+    }
+    buffer.write('</p>');
+  }
+
+  /**
+   * Write a table showing summary information for the last several
+   * completion requests to the given [buffer] object.
+   */
+  void _writeCompletionPerformanceList(StringBuffer buffer) {
+    CompletionDomainHandler handler = _completionDomainHandler;
+    buffer.write('<h3>Completion Performance List</h3>');
+    if (handler == null) {
+      return;
+    }
+    buffer.write('<table>');
+    _writeRow(
+        buffer,
+        [
+          'Start Time',
+          '',
+          'First (ms)',
+          '',
+          'Complete (ms)',
+          '',
+          '# Notifications',
+          '',
+          '# Suggestions',
+          '',
+          'Snippet'
+        ],
+        header: true);
+    int index = 0;
+    for (CompletionPerformance performance in handler.performanceList) {
+      String link = makeLink(COMPLETION_PATH, {'index': '$index'},
+          '${performance.startTimeAndMs}');
+      _writeRow(buffer, [
+        link,
+        '&nbsp;&nbsp;',
+        performance.firstNotificationInMilliseconds,
+        '&nbsp;&nbsp;',
+        performance.elapsedInMilliseconds,
+        '&nbsp;&nbsp;',
+        performance.notificationCount,
+        '&nbsp;&nbsp;',
+        performance.suggestionCount,
+        '&nbsp;&nbsp;',
+        HTML_ESCAPE.convert(performance.snippet)
+      ]);
+      ++index;
+    }
+
+    buffer.write('</table>');
+    buffer.write('''
+      <p><strong>First (ms)</strong> - the number of milliseconds
+        from when completion received the request until the first notification
+        with completion results was queued for sending back to the client.
+      <p><strong>Complete (ms)</strong> - the number of milliseconds
+        from when completion received the request until the final notification
+        with completion results was queued for sending back to the client.
+      <p><strong># Notifications</strong> - the total number of notifications
+        sent to the client with completion results for this request.
+      <p><strong># Suggestions</strong> - the number of suggestions
+        sent to the client in the first notification, followed by a comma,
+        followed by the number of suggestions send to the client
+        in the last notification. If there is only one notification,
+        then there will be only one number in this column.''');
+  }
+
+  /**
+   * Write the status of the edit domain (on the main status page) to the given
+   * [buffer].
+   */
+  void _writeEditStatus(StringBuffer buffer) {
+    buffer.write('<h3>Edit Domain</h3>');
+    _writeTwoColumns(buffer, (StringBuffer buffer) {
+      buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
+      buffer.write('</p>');
+    }, (StringBuffer buffer) {});
+  }
+
+  /**
+   * Write a representation of the given [caughtException] to the given
+   * [buffer]. If [isCause] is `true`, then the exception was a cause for
+   * another exception.
+   */
+  void _writeException(StringBuffer buffer, CaughtException caughtException,
+      {bool isCause: false}) {
+    Object exception = caughtException.exception;
+
+    if (exception is AnalysisException) {
+      buffer.write('<p>');
+      if (isCause) {
+        buffer.write('Caused by ');
+      }
+      buffer.write(exception.message);
+      buffer.write('</p>');
+      _writeStackTrace(buffer, caughtException.stackTrace);
+      CaughtException cause = exception.cause;
+      if (cause != null) {
+        buffer.write('<blockquote>');
+        _writeException(buffer, cause, isCause: true);
+        buffer.write('</blockquote>');
+      }
+    } else {
+      buffer.write('<p>');
+      if (isCause) {
+        buffer.write('Caused by ');
+      }
+      buffer.write(exception.toString());
+      buffer.write('<p>');
+      _writeStackTrace(buffer, caughtException.stackTrace);
+    }
+  }
+
+  /**
+   * Write the status of the execution domain (on the main status page) to the
+   * given [buffer].
+   */
+  void _writeExecutionStatus(StringBuffer buffer) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    ExecutionDomainHandler handler = analysisServer.handlers.firstWhere(
+        (RequestHandler handler) => handler is ExecutionDomainHandler,
+        orElse: () => null);
+    Set<ExecutionService> services = new Set<ExecutionService>();
+    if (handler.onFileAnalyzed != null) {
+      services.add(ExecutionService.LAUNCH_DATA);
+    }
+
+    if (handler != null) {
+      buffer.write('<h3>Execution Domain</h3>');
+      _writeTwoColumns(buffer, (StringBuffer buffer) {
+        _writeSubscriptionList(buffer, ExecutionService.VALUES, services);
+      }, (StringBuffer buffer) {});
+    }
+  }
+
+  /**
+   * Write to the given [buffer] a representation of the given [map] of strings
+   * to strings.
+   */
+  void _writeMapOfStringToString(StringBuffer buffer, Map<String, String> map) {
+    List<String> keys = map.keys.toList();
+    keys.sort();
+    int length = keys.length;
+    buffer.write('{');
+    for (int i = 0; i < length; i++) {
+      buffer.write('<br>');
+      String key = keys[i];
+      if (i > 0) {
+        buffer.write(', ');
+      }
+      buffer.write(key);
+      buffer.write(' = ');
+      buffer.write(map[key]);
+    }
+    buffer.write('<br>}');
+  }
+
+  /**
+   * Write a representation of an analysis option with the given [name] and
+   * [value] to the given [buffer]. The option should be separated from other
+   * options unless the [last] flag is true, indicating that this is the last
+   * option in the list of options.
+   */
+  void _writeOption(StringBuffer buffer, String name, Object value,
+      {bool last: false}) {
+    buffer.write(name);
+    buffer.write(' = ');
+    buffer.write(value.toString());
+    if (!last) {
+      buffer.write('<br>');
+    }
+  }
+
+  /**
+   * Write a standard HTML page to the given [buffer]. The page will have the
+   * given [title] and a body that is generated by the given [body] generator.
+   */
+  void _writePage(StringBuffer buffer, String title, List<String> subtitles,
+      HtmlGenerator body) {
+    DateTime now = new DateTime.now();
+    String date = "${now.month}/${now.day}/${now.year}";
+    String time =
+        "${now.hour}:${_twoDigit(now.minute)}:${_twoDigit(now.second)}.${now.millisecond}";
+
+    buffer.write('<!DOCTYPE html>');
+    buffer.write('<html>');
+    buffer.write('<head>');
+    buffer.write('<meta charset="utf-8">');
+    buffer.write(
+        '<meta name="viewport" content="width=device-width, initial-scale=1.0">');
+    buffer.write('<title>$title</title>');
+    buffer.write('<style>');
+    buffer.write('a {color: #0000DD; text-decoration: none;}');
+    buffer.write('a:link.error {background-color: #FFEEEE;}');
+    buffer.write('a:visited.error {background-color: #FFEEEE;}');
+    buffer.write('a:hover.error {background-color: #FFEEEE;}');
+    buffer.write('a:active.error {background-color: #FFEEEE;}');
+    buffer.write(
+        'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
+    buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
+    buffer.write(
+        'p.commentary {margin-top: 1em; margin-bottom: 1em; margin-left: 2em; font-style: italic;}');
+//    response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
+    buffer.write(
+        'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
+    buffer.write('td.column {vertical-align: top; width: 50%;}');
+    buffer.write('td.right {text-align: right;}');
+    buffer.write('th {text-align: left; vertical-align:top;}');
+    buffer.write('tr {vertical-align:top;}');
+    buffer.write('</style>');
+    buffer.write('</head>');
+
+    buffer.write('<body>');
+    buffer.write(
+        '<h2>$title <small><small>(as of $time on $date)</small></small></h2>');
+    if (subtitles != null && subtitles.isNotEmpty) {
+      buffer.write('<blockquote>');
+      bool first = true;
+      for (String subtitle in subtitles) {
+        if (first) {
+          first = false;
+        } else {
+          buffer.write('<br>');
+        }
+        buffer.write('<b>');
+        buffer.write(subtitle);
+        buffer.write('</b>');
+      }
+      buffer.write('</blockquote>');
+    }
+    try {
+      body(buffer);
+    } catch (exception, stackTrace) {
+      buffer.write('<h3>Exception while creating page</h3>');
+      _writeException(buffer, new CaughtException(exception, stackTrace));
+    }
+    buffer.write('</body>');
+    buffer.write('</html>');
+  }
+
+  /**
+   * Write the recent output section (on the main status page) to the given
+   * [buffer] object.
+   */
+  void _writePluginStatus(StringBuffer buffer) {
+    void writePlugin(Plugin plugin) {
+      buffer.write(plugin.uniqueIdentifier);
+      buffer.write(' (');
+      buffer.write(plugin.runtimeType);
+      buffer.write(')<br>');
+    }
+
+    buffer.write('<h3>Plugin Status</h3><p>');
+    writePlugin(AnalysisEngine.instance.enginePlugin);
+    writePlugin(_server.serverPlugin);
+    for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
+      writePlugin(plugin);
+    }
+    buffer.write('<p>');
+  }
+
+  /**
+   * Write the recent output section (on the main status page) to the given
+   * [buffer] object.
+   */
+  void _writeRecentOutput(StringBuffer buffer) {
+    buffer.write('<h3>Recent Output</h3>');
+    String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
+    if (output.isEmpty) {
+      buffer.write('<i>none</i>');
+    } else {
+      buffer.write('<pre>');
+      buffer.write(output);
+      buffer.write('</pre>');
+    }
+  }
+
+  void _writeResponse(HttpRequest request, HtmlGenerator writePage) {
+    HttpResponse response = request.response;
+    response.statusCode = HttpStatus.OK;
+    response.headers.contentType = _htmlContent;
+    try {
+      StringBuffer buffer = new StringBuffer();
+      try {
+        writePage(buffer);
+      } catch (exception, stackTrace) {
+        buffer.clear();
+        _writePage(buffer, 'Internal Exception', [], (StringBuffer buffer) {
+          _writeException(buffer, new CaughtException(exception, stackTrace));
+        });
+      }
+      response.write(buffer.toString());
+    } finally {
+      response.close();
+    }
+  }
+
+  /**
+   * Write a single row within a table to the given [buffer]. The row will have
+   * one cell for each of the [columns], and will be a header row if [header] is
+   * `true`.
+   */
+  void _writeRow(StringBuffer buffer, List<Object> columns,
+      {bool header: false, List<String> classes}) {
+    buffer.write('<tr>');
+    int count = columns.length;
+    int maxClassIndex = classes == null ? 0 : classes.length - 1;
+    for (int i = 0; i < count; i++) {
+      String classAttribute = '';
+      if (classes != null) {
+        String className = classes[min(i, maxClassIndex)];
+        if (className != null) {
+          classAttribute = ' class="$className"';
+        }
+      }
+      if (header) {
+        buffer.write('<th$classAttribute>');
+      } else {
+        buffer.write('<td$classAttribute>');
+      }
+      buffer.write(columns[i]);
+      if (header) {
+        buffer.write('</th>');
+      } else {
+        buffer.write('</td>');
+      }
+    }
+    buffer.write('</tr>');
+  }
+
+  /**
+   * Write the status of the service domain (on the main status page) to the
+   * given [response] object.
+   */
+  bool _writeServerStatus(StringBuffer buffer) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    Set<ServerService> services = analysisServer.serverServices;
+
+    buffer.write('<h3>Server Domain</h3>');
+    _writeTwoColumns(buffer, (StringBuffer buffer) {
+      if (analysisServer == null) {
+        buffer.write('Status: <span style="color:red">Not running</span>');
+        return;
+      }
+      buffer.write('<p>');
+      buffer.write('Status: Running<br>');
+      buffer.write('New analysis driver: ');
+      buffer.write(analysisServer.options.enableNewAnalysisDriver);
+      buffer.write('<br>');
+      buffer.write('Instrumentation: ');
+      if (AnalysisEngine.instance.instrumentationService.isActive) {
+        buffer.write('<span style="color:red">Active</span>');
+      } else {
+        buffer.write('Inactive');
+      }
+      buffer.write('<br>');
+      buffer.write('Version: ');
+      buffer.write(AnalysisServer.VERSION);
+      buffer.write('<br>');
+      buffer.write('Process ID: ');
+      buffer.write(pid);
+      buffer.write('</p>');
+
+      buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(
+          COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
+      buffer.write('</p>');
+    }, (StringBuffer buffer) {
+      _writeSubscriptionList(buffer, ServerService.VALUES, services);
+    });
+    return analysisServer != null;
+  }
+
+  /**
+   * Write a representation of the given [stackTrace] to the given [buffer].
+   */
+  void _writeStackTrace(StringBuffer buffer, StackTrace stackTrace) {
+    if (stackTrace != null) {
+      String trace = stackTrace.toString().replaceAll('#', '<br>#');
+      if (trace.startsWith('<br>#')) {
+        trace = trace.substring(4);
+      }
+      buffer.write('<p>');
+      buffer.write(trace);
+      buffer.write('</p>');
+    }
+  }
+
+  /**
+   * Given a [service] that could be subscribed to and a set of the services
+   * that are actually subscribed to ([subscribedServices]), write a
+   * representation of the service to the given [buffer].
+   */
+  void _writeSubscriptionInList(
+      StringBuffer buffer, Enum service, Set<Enum> subscribedServices) {
+    if (subscribedServices.contains(service)) {
+      buffer.write('<code>+ </code>');
+    } else {
+      buffer.write('<code>- </code>');
+    }
+    buffer.write(service.name);
+    buffer.write('<br>');
+  }
+
+  /**
+   * Given a [service] that could be subscribed to and a set of paths that are
+   * subscribed to the services ([subscribedPaths]), write a representation of
+   * the service to the given [buffer].
+   */
+  void _writeSubscriptionInMap(
+      StringBuffer buffer, Enum service, Set<String> subscribedPaths) {
+    buffer.write('<p>');
+    buffer.write(service.name);
+    buffer.write('</p>');
+    if (subscribedPaths == null || subscribedPaths.isEmpty) {
+      buffer.write('none');
+    } else {
+      List<String> paths = subscribedPaths.toList();
+      paths.sort();
+      for (String path in paths) {
+        buffer.write('<p>');
+        buffer.write(path);
+        buffer.write('</p>');
+      }
+    }
+  }
+
+  /**
+   * Given a list containing all of the services that can be subscribed to in a
+   * single domain ([allServices]) and a set of the services that are actually
+   * subscribed to ([subscribedServices]), write a representation of the
+   * subscriptions to the given [buffer].
+   */
+  void _writeSubscriptionList(StringBuffer buffer, List<Enum> allServices,
+      Set<Enum> subscribedServices) {
+    buffer.write('<p><b>Subscriptions</b></p>');
+    buffer.write('<p>');
+    for (Enum service in allServices) {
+      _writeSubscriptionInList(buffer, service, subscribedServices);
+    }
+    buffer.write('</p>');
+  }
+
+  /**
+   * Given a list containing all of the services that can be subscribed to in a
+   * single domain ([allServices]) and a set of the services that are actually
+   * subscribed to ([subscribedServices]), write a representation of the
+   * subscriptions to the given [buffer].
+   */
+  void _writeSubscriptionMap(StringBuffer buffer, List<Enum> allServices,
+      Map<Enum, Set<String>> subscribedServices) {
+    buffer.write('<p><b>Subscriptions</b></p>');
+    for (Enum service in allServices) {
+      _writeSubscriptionInMap(buffer, service, subscribedServices[service]);
+    }
+  }
+
+  /**
+   * Write two columns of information to the given [buffer], where the
+   * [leftColumn] and [rightColumn] functions are used to generate the content
+   * of those columns.
+   */
+  void _writeTwoColumns(StringBuffer buffer, HtmlGenerator leftColumn,
+      HtmlGenerator rightColumn) {
+    buffer
+        .write('<table class="column"><tr class="column"><td class="column">');
+    leftColumn(buffer);
+    buffer.write('</td><td class="column">');
+    rightColumn(buffer);
+    buffer.write('</td></tr></table>');
+  }
+
+  /**
+   * Create a link to [path] with query parameters [params], with inner HTML
+   * [innerHtml]. If [hasError] is `true`, then the link will have the class
+   * 'error'.
+   */
+  static String makeLink(
+      String path, Map<String, String> params, String innerHtml,
+      [bool hasError = false]) {
+    Uri uri = params.isEmpty
+        ? new Uri(path: path)
+        : new Uri(path: path, queryParameters: params);
+    String href = HTML_ESCAPE.convert(uri.toString());
+    String classAttribute = hasError ? ' class="error"' : '';
+    return '<a href="$href"$classAttribute>$innerHtml</a>';
+  }
+}
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 1039788..46a2d44 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -20,8 +20,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/task/options.dart'
-    show CONFIGURED_ERROR_PROCESSORS;
 import 'package:analyzer/src/util/glob.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
 import 'package:linter/src/rules/avoid_as.dart';
@@ -1747,8 +1745,8 @@
         .toList();
   }
 
-  List<ErrorProcessor> get errorProcessors => callbacks.currentContext
-      .getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+  List<ErrorProcessor> get errorProcessors =>
+      callbacks.currentContext.analysisOptions.errorProcessors;
 
   List<Linter> get lints => getLints(callbacks.currentContext);
 
@@ -1851,7 +1849,7 @@
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
   language:
-    enableGenericMethods: true
+    enableStrictCallChecks: true
   errors:
     unused_local_variable: false
 linter:
@@ -1866,7 +1864,7 @@
     // Verify options were set.
     expect(errorProcessors, hasLength(1));
     expect(lints, hasLength(1));
-    expect(options.enableGenericMethods, isTrue);
+    expect(options.enableStrictCallChecks, isTrue);
 
     // Remove options.
     deleteFile([projPath, optionsFileName]);
@@ -1875,7 +1873,7 @@
     // Verify defaults restored.
     expect(errorProcessors, isEmpty);
     expect(lints, isEmpty);
-    expect(options.enableGenericMethods, isFalse);
+    expect(options.enableStrictCallChecks, isFalse);
   }
 
   test_analysis_options_file_delete_with_embedder() async {
@@ -1905,7 +1903,7 @@
         r'''
 analyzer:
   language:
-    enableGenericMethods: true
+    enableStrictCallChecks: true
   errors:
     unused_local_variable: false
 linter:
@@ -1918,7 +1916,7 @@
     await pumpEventQueue();
 
     // Verify options were set.
-    expect(options.enableGenericMethods, isTrue);
+    expect(options.enableStrictCallChecks, isTrue);
     expect(options.strongMode, isTrue);
     expect(errorProcessors, hasLength(2));
     expect(lints, hasLength(2));
@@ -1928,7 +1926,7 @@
     await pumpEventQueue();
 
     // Verify defaults restored.
-    expect(options.enableGenericMethods, isFalse);
+    expect(options.enableStrictCallChecks, isFalse);
     expect(lints, hasLength(1));
     expect(lints.first, new isInstanceOf<AvoidAs>());
     expect(errorProcessors, hasLength(1));
@@ -1954,7 +1952,7 @@
         r'''
 analyzer:
   language:
-    enableGenericMethods: true
+    enableStrictCallChecks: true
   errors:
     unused_local_variable: false
 linter:
@@ -1964,9 +1962,8 @@
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     await pumpEventQueue();
-
     // Verify options were set.
-    expect(options.enableGenericMethods, isTrue);
+    expect(options.enableStrictCallChecks, isTrue);
     expect(errorProcessors, hasLength(1));
     expect(lints, hasLength(1));
     expect(lints[0].name, 'camel_case_types');
@@ -2028,7 +2025,7 @@
   exclude:
     - 'test/**'
   language:
-    enableGenericMethods: true
+    enableStrictCallChecks: true
   errors:
     unused_local_variable: false
 linter:
@@ -2052,7 +2049,7 @@
     expect(context.analysisOptions.strongMode, isTrue);
     expect(context.analysisOptions.enableSuperMixins, isTrue);
     // * from analysis options:
-    expect(context.analysisOptions.enableGenericMethods, isTrue);
+    expect(context.analysisOptions.enableStrictCallChecks, isTrue);
 
     // * verify tests are excluded
     expect(
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 76d12c8..9230d23 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -105,7 +105,7 @@
       }
 
       group('excluded', () {
-        test('excluded folder', () {
+        test('excluded folder', () async {
           String fileA = '/project/aaa/a.dart';
           String fileB = '/project/bbb/b.dart';
           resourceProvider.newFile(fileA, '// a');
@@ -115,10 +115,9 @@
           expect(response, isResponseSuccess('0'));
           // unit "a" is resolved eventually
           // unit "b" is not resolved
-          return server.onAnalysisComplete.then((_) {
-            expect(serverRef.getResolvedCompilationUnits(fileA), hasLength(1));
-            expect(serverRef.getResolvedCompilationUnits(fileB), isEmpty);
-          });
+          await server.onAnalysisComplete;
+          expect(await serverRef.getResolvedCompilationUnit(fileA), isNotNull);
+          expect(await serverRef.getResolvedCompilationUnit(fileB), isNull);
         });
 
         test('not absolute', () async {
@@ -139,7 +138,7 @@
       });
 
       group('included', () {
-        test('new folder', () {
+        test('new folder', () async {
           String file = '/project/bin/test.dart';
           resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
           resourceProvider.newFile(file, 'main() {}');
@@ -147,10 +146,9 @@
           var serverRef = server;
           expect(response, isResponseSuccess('0'));
           // verify that unit is resolved eventually
-          return server.onAnalysisComplete.then((_) {
-            var units = serverRef.getResolvedCompilationUnits(file);
-            expect(units, hasLength(1));
-          });
+          await server.onAnalysisComplete;
+          var unit = await serverRef.getResolvedCompilationUnit(file);
+          expect(unit, isNotNull);
         });
 
         test('nonexistent folder', () async {
@@ -162,7 +160,8 @@
           // Non-existence of /project_a should not prevent files in /project_b
           // from being analyzed.
           await server.onAnalysisComplete;
-          expect(serverRef.getResolvedCompilationUnits(fileB), hasLength(1));
+          var unit = await serverRef.getResolvedCompilationUnit(fileB);
+          expect(unit, isNotNull);
         });
 
         test('not absolute', () async {
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index d3f44e0..acb2095 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
+import 'package:analyzer/src/summary/summary_file_builder.dart';
 
 class MockSdk implements DartSdk {
   static const MockSdkLibrary LIB_CORE = const MockSdkLibrary(
@@ -263,6 +264,11 @@
    */
   InternalAnalysisContext _analysisContext;
 
+  /**
+   * The cached linked bundle of the SDK.
+   */
+  PackageBundle _bundle;
+
   MockSdk({resource.ResourceProvider resourceProvider})
       : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
     LIBRARIES.forEach((SdkLibrary library) {
@@ -333,7 +339,18 @@
   }
 
   @override
-  PackageBundle getLinkedBundle() => null;
+  PackageBundle getLinkedBundle() {
+    if (_bundle == null) {
+      List<Source> librarySources = sdkLibraries
+          .map((SdkLibrary library) => mapDartUri(library.shortName))
+          .toList();
+      List<int> bytes = new SummaryBuilder(
+              librarySources, context, context.analysisOptions.strongMode)
+          .build();
+      _bundle = new PackageBundle.fromBuffer(bytes);
+    }
+    return _bundle;
+  }
 
   @override
   SdkLibrary getSdkLibrary(String dartUri) {
diff --git a/pkg/analysis_server/test/search/abstract_search_domain.dart b/pkg/analysis_server/test/search/abstract_search_domain.dart
index b59ac7d..dbdacdf 100644
--- a/pkg/analysis_server/test/search/abstract_search_domain.dart
+++ b/pkg/analysis_server/test/search/abstract_search_domain.dart
@@ -78,6 +78,7 @@
 
   @override
   void processNotification(Notification notification) {
+    super.processNotification(notification);
     if (notification.event == SEARCH_RESULTS) {
       var params = new SearchResultsParams.fromNotification(notification);
       String id = params.id;
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 76aace1..3f0daba 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -29,7 +29,7 @@
     expect(result.isPotential, isPotential);
   }
 
-  Future findElementReferences(String search, bool includePotential) async {
+  Future<Null> findElementReferences(String search, bool includePotential) async {
     int offset = findOffset(search);
     await waitForTasksFinished();
     Request request = new SearchFindElementReferencesParams(
@@ -39,11 +39,10 @@
     var result = new SearchFindElementReferencesResult.fromResponse(response);
     searchId = result.id;
     searchElement = result.element;
-    if (searchId == null) {
-      return null;
-    } else {
-      return waitForSearchResults();
+    if (searchId != null) {
+      await waitForSearchResults();
     }
+    expect(serverErrors, isEmpty);
   }
 
   test_constructor_named() async {
@@ -153,8 +152,7 @@
 ''');
     await findElementReferences('fff; // declaration', false);
     expect(searchElement.kind, ElementKind.FIELD);
-    expect(results, hasLength(11));
-    assertHasResult(SearchResultKind.DECLARATION, 'fff; // declaration');
+    expect(results, hasLength(10));
     assertHasResult(SearchResultKind.WRITE, 'fff); // in constructor');
     assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
     // m()
@@ -216,8 +214,7 @@
 ''');
     await findElementReferences('fff); // in constructor', false);
     expect(searchElement.kind, ElementKind.FIELD);
-    expect(results, hasLength(4));
-    assertHasResult(SearchResultKind.DECLARATION, 'fff; // declaration');
+    expect(results, hasLength(3));
     assertHasResult(SearchResultKind.WRITE, 'fff); // in constructor');
     assertHasResult(SearchResultKind.WRITE, 'fff = 2;');
     assertHasResult(SearchResultKind.READ, 'fff); // in m()');
@@ -257,9 +254,6 @@
   ''');
     await findElementReferences('fff; // in B', false);
     expect(searchElement.kind, ElementKind.FIELD);
-    assertHasResult(SearchResultKind.DECLARATION, 'fff; // in A');
-    assertHasResult(SearchResultKind.DECLARATION, 'fff; // in B');
-    assertHasResult(SearchResultKind.DECLARATION, 'fff; // in C');
     assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
     assertHasResult(SearchResultKind.WRITE, 'fff = 20;');
     assertHasResult(SearchResultKind.WRITE, 'fff = 30;');
@@ -326,8 +320,7 @@
 ''');
     await findElementReferences('myLabel; // break', false);
     expect(searchElement.kind, ElementKind.LABEL);
-    expect(results, hasLength(3));
-    assertHasResult(SearchResultKind.DECLARATION, 'myLabel:');
+    expect(results, hasLength(2));
     assertHasResult(SearchResultKind.REFERENCE, 'myLabel; // continue');
     assertHasResult(SearchResultKind.REFERENCE, 'myLabel; // break');
   }
@@ -344,8 +337,7 @@
 ''');
     await findElementReferences('vvv = 1', false);
     expect(searchElement.kind, ElementKind.LOCAL_VARIABLE);
-    expect(results, hasLength(5));
-    assertHasResult(SearchResultKind.DECLARATION, 'vvv = 1');
+    expect(results, hasLength(4));
     assertHasResult(SearchResultKind.READ, 'vvv);');
     assertHasResult(SearchResultKind.READ_WRITE, 'vvv += 3');
     assertHasResult(SearchResultKind.WRITE, 'vvv = 2');
@@ -403,38 +395,6 @@
     expect(searchId, isNull);
   }
 
-  test_oneUnit_twoLibraries() async {
-    var pathA = '/project/bin/libA.dart';
-    var pathB = '/project/bin/libB.dart';
-    var codeA = '''
-library lib;
-part 'test.dart';
-main() {
-  fff(1);
-}
-''';
-    var codeB = '''
-library lib;
-part 'test.dart';
-main() {
-  fff(2);
-}
-''';
-    addFile(pathA, codeA);
-    addFile(pathB, codeB);
-    addTestFile('''
-part of lib;
-fff(p) {}
-''');
-    await findElementReferences('fff(p) {}', false);
-    expect(searchElement.kind, ElementKind.FUNCTION);
-    expect(results, hasLength(2));
-    findResult(
-        SearchResultKind.INVOCATION, pathA, codeA.indexOf('fff(1)'), 3, true);
-    findResult(
-        SearchResultKind.INVOCATION, pathB, codeB.indexOf('fff(2)'), 3, true);
-  }
-
   test_oneUnit_zeroLibraries() async {
     addTestFile('''
 part of lib;
@@ -458,8 +418,7 @@
 ''');
     await findElementReferences('ppp) {', false);
     expect(searchElement.kind, ElementKind.PARAMETER);
-    expect(results, hasLength(5));
-    assertHasResult(SearchResultKind.DECLARATION, 'ppp) {');
+    expect(results, hasLength(4));
     assertHasResult(SearchResultKind.READ, 'ppp);');
     assertHasResult(SearchResultKind.READ_WRITE, 'ppp += 3');
     assertHasResult(SearchResultKind.WRITE, 'ppp = 2');
@@ -626,8 +585,7 @@
     expect(searchElement.kind, ElementKind.PREFIX);
     expect(searchElement.name, 'ppp');
     expect(searchElement.location.startLine, 1);
-    expect(results, hasLength(3));
-    assertHasResult(SearchResultKind.DECLARATION, 'ppp;');
+    expect(results, hasLength(2));
     assertHasResult(SearchResultKind.REFERENCE, 'ppp.Future');
     assertHasResult(SearchResultKind.REFERENCE, 'ppp.Stream');
   }
@@ -644,8 +602,7 @@
 ''');
     await findElementReferences('vvv = 1', false);
     expect(searchElement.kind, ElementKind.TOP_LEVEL_VARIABLE);
-    expect(results, hasLength(5));
-    assertHasResult(SearchResultKind.DECLARATION, 'vvv = 1;');
+    expect(results, hasLength(4));
     assertHasResult(SearchResultKind.READ, 'vvv);');
     assertHasResult(SearchResultKind.WRITE, 'vvv += 3');
     assertHasResult(SearchResultKind.WRITE, 'vvv = 2');
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 137d374..e7a9e48 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,7 @@
 ## 0.30.0-alpha.0
 * Changed the API for creating BazelWorkspace.  It should now be constructed using BazelWorkspace.find().  Note that this might return `null` in the event that the given path is not part of a BazelWorkspace.
 * Added an AST structure to support asserts in constructor initializers (AssertInitializer).  AstVisitor classes must now implement visitAssertInitializer().
+* Changed the API for creating PartOfDirective.  It now accepts a StringLiteral URI, to accomodate "part of" declarations with a URI string rather than a library name.
 
 ## 0.29.0-alpha.0
 * Removed `Element.docRange`.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index b027e4c..851890c 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -6338,17 +6338,19 @@
   /**
    * Initialize a newly created part-of directive. Either or both of the
    * [comment] and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute.
+   * corresponding attribute. Only one of the [uri] and [libraryName] should be
+   * provided.
    */
   factory PartOfDirective(
           Comment comment,
           List<Annotation> metadata,
           Token partKeyword,
           Token ofKeyword,
+          StringLiteral uri,
           LibraryIdentifier libraryName,
           Token semicolon) =>
-      new PartOfDirectiveImpl(
-          comment, metadata, partKeyword, ofKeyword, libraryName, semicolon);
+      new PartOfDirectiveImpl(comment, metadata, partKeyword, ofKeyword, uri,
+          libraryName, semicolon);
 
   /**
    * Return the name of the library that the containing compilation unit is part
@@ -6391,6 +6393,20 @@
    * Set the semicolon terminating the directive to the given [token].
    */
   void set semicolon(Token token);
+
+  /**
+   * Return the URI of the library that the containing compilation unit is part
+   * of, or `null` if no URI was given (typically because a library name was
+   * provided).
+   */
+  StringLiteral get uri;
+
+  /**
+   * Return the URI of the library that the containing compilation unit is part
+   * of, or `null` if no URI was given (typically because a library name was
+   * provided).
+   */
+  void set uri(StringLiteral uri);
 }
 
 /**
@@ -7994,28 +8010,6 @@
    * Set the source to which the [uri] was resolved to the given [source].
    */
   void set uriSource(Source source);
-
-  /**
-   * Validate this directive, but do not check for existence. Return a code
-   * indicating the problem if there is one, or `null` no problem
-   */
-  UriValidationCode validate();
-}
-
-/**
- * Validation codes returned by [UriBasedDirective.validate].
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class UriValidationCode {
-  static const UriValidationCode INVALID_URI =
-      UriValidationCodeImpl.INVALID_URI;
-
-  static const UriValidationCode URI_WITH_INTERPOLATION =
-      UriValidationCodeImpl.URI_WITH_INTERPOLATION;
-
-  static const UriValidationCode URI_WITH_DART_EXT_SCHEME =
-      UriValidationCodeImpl.URI_WITH_DART_EXT_SCHEME;
 }
 
 /**
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
new file mode 100644
index 0000000..ffaf90e
--- /dev/null
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -0,0 +1,1018 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:front_end/src/scanner/token.dart';
+
+/**
+ * A collection of factory methods which may be used to create concrete
+ * instances of the interfaces that constitute the AST.
+ *
+ * Clients should not extend, implement or mix-in this class.
+ */
+abstract class AstFactory {
+  /**
+   * Returns a newly created list of adjacent strings. To be syntactically
+   * valid, the list of [strings] must contain at least two elements.
+   */
+  AdjacentStrings adjacentStrings(List<StringLiteral> strings);
+
+  /**
+   * Returns a newly created annotation. Both the [period] and the
+   * [constructorName] can be `null` if the annotation is not referencing a
+   * named constructor. The [arguments] can be `null` if the annotation is not
+   * referencing a constructor.
+   */
+  Annotation annotation(Token atSign, Identifier name, Token period,
+      SimpleIdentifier constructorName, ArgumentList arguments);
+
+  /**
+   * Returns a newly created list of arguments. The list of [arguments] can
+   * be `null` if there are no arguments.
+   */
+  ArgumentList argumentList(Token leftParenthesis, List<Expression> arguments,
+      Token rightParenthesis);
+
+  /**
+   * Returns a newly created as expression.
+   */
+  AsExpression asExpression(
+      Expression expression, Token asOperator, TypeName type);
+
+  /**
+   * Returns a newly created assert initializer. The [comma] and [message]
+   * can be `null` if there is no message.
+   */
+  AssertInitializer assertInitializer(
+      Token assertKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token comma,
+      Expression message,
+      Token rightParenthesis);
+
+  /**
+   * Returns a newly created assert statement. The [comma] and [message] can
+   * be `null` if there is no message.
+   */
+  AssertStatement assertStatement(
+      Token assertKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token comma,
+      Expression message,
+      Token rightParenthesis,
+      Token semicolon);
+
+  /**
+   * Returns a newly created assignment expression.
+   */
+  AssignmentExpression assignmentExpression(
+      Expression leftHandSide, Token operator, Expression rightHandSide);
+
+  /**
+   * Returns a newly created await expression.
+   */
+  AwaitExpression awaitExpression(Token awaitKeyword, Expression expression);
+
+  /**
+   * Returns a newly created binary expression.
+   */
+  BinaryExpression binaryExpression(
+      Expression leftOperand, Token operator, Expression rightOperand);
+  /**
+   * Returns a newly created block of code.
+   */
+  Block block(
+      Token leftBracket, List<Statement> statements, Token rightBracket);
+
+  /**
+   * Returns a block comment consisting of the given [tokens].
+   */
+  Comment blockComment(List<Token> tokens);
+
+  /**
+   * Returns a newly created function body consisting of a block of
+   * statements. The [keyword] can be `null` if there is no keyword specified
+   * for the block. The [star] can be `null` if there is no star following the
+   * keyword (and must be `null` if there is no keyword).
+   */
+  BlockFunctionBody blockFunctionBody(Token keyword, Token star, Block block);
+
+  /**
+   * Returns a newly created boolean literal.
+   */
+  BooleanLiteral booleanLiteral(Token literal, bool value);
+
+  /**
+   * Returns a newly created break statement. The [label] can be `null` if
+   * there is no label associated with the statement.
+   */
+  BreakStatement breakStatement(
+      Token breakKeyword, SimpleIdentifier label, Token semicolon);
+
+  /**
+   * Returns a newly created cascade expression. The list of
+   * [cascadeSections] must contain at least one element.
+   */
+  CascadeExpression cascadeExpression(
+      Expression target, List<Expression> cascadeSections);
+
+  /**
+   * Returns a newly created catch clause. The [onKeyword] and
+   * [exceptionType] can be `null` if the clause will catch all exceptions. The
+   * [comma] and [stackTraceParameter] can be `null` if the stack trace
+   * parameter is not defined.
+   */
+  CatchClause catchClause(
+      Token onKeyword,
+      TypeName exceptionType,
+      Token catchKeyword,
+      Token leftParenthesis,
+      SimpleIdentifier exceptionParameter,
+      Token comma,
+      SimpleIdentifier stackTraceParameter,
+      Token rightParenthesis,
+      Block body);
+
+  /**
+   * Returns a newly created class declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the class does not have the
+   * corresponding attribute. The [abstractKeyword] can be `null` if the class
+   * is not abstract. The [typeParameters] can be `null` if the class does not
+   * have any type parameters. Any or all of the [extendsClause], [withClause],
+   * and [implementsClause] can be `null` if the class does not have the
+   * corresponding clause. The list of [members] can be `null` if the class does
+   * not have any members.
+   */
+  ClassDeclaration classDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token abstractKeyword,
+      Token classKeyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      ExtendsClause extendsClause,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      Token leftBracket,
+      List<ClassMember> members,
+      Token rightBracket);
+
+  /**
+   * Returns a newly created class type alias. Either or both of the
+   * [comment] and [metadata] can be `null` if the class type alias does not
+   * have the corresponding attribute. The [typeParameters] can be `null` if the
+   * class does not have any type parameters. The [abstractKeyword] can be
+   * `null` if the class is not abstract. The [implementsClause] can be `null`
+   * if the class does not implement any interfaces.
+   */
+  ClassTypeAlias classTypeAlias(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      Token equals,
+      Token abstractKeyword,
+      TypeName superclass,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      Token semicolon);
+
+  /**
+   * Returns a newly created reference to a Dart element. The [newKeyword]
+   * can be `null` if the reference is not to a constructor.
+   */
+  CommentReference commentReference(Token newKeyword, Identifier identifier);
+
+  /**
+   * Returns a newly created compilation unit to have the given directives
+   * and declarations. The [scriptTag] can be `null` if there is no script tag
+   * in the compilation unit. The list of [directives] can be `null` if there
+   * are no directives in the compilation unit. The list of [declarations] can
+   * be `null` if there are no declarations in the compilation unit.
+   */
+  CompilationUnit compilationUnit(
+      Token beginToken,
+      ScriptTag scriptTag,
+      List<Directive> directives,
+      List<CompilationUnitMember> declarations,
+      Token endToken);
+
+  /**
+   * Returns a newly created conditional expression.
+   */
+  ConditionalExpression conditionalExpression(
+      Expression condition,
+      Token question,
+      Expression thenExpression,
+      Token colon,
+      Expression elseExpression);
+
+  /**
+   * Returns a newly created configuration.
+   */
+  Configuration configuration(
+      Token ifKeyword,
+      Token leftParenthesis,
+      DottedName name,
+      Token equalToken,
+      StringLiteral value,
+      Token rightParenthesis,
+      StringLiteral libraryUri);
+
+  /**
+   * Returns a newly created constructor declaration. The [externalKeyword]
+   * can be `null` if the constructor is not external. Either or both of the
+   * [comment] and [metadata] can be `null` if the constructor does not have the
+   * corresponding attribute. The [constKeyword] can be `null` if the
+   * constructor cannot be used to create a constant. The [factoryKeyword] can
+   * be `null` if the constructor is not a factory. The [period] and [name] can
+   * both be `null` if the constructor is not a named constructor. The
+   * [separator] can be `null` if the constructor does not have any initializers
+   * and does not redirect to a different constructor. The list of
+   * [initializers] can be `null` if the constructor does not have any
+   * initializers. The [redirectedConstructor] can be `null` if the constructor
+   * does not redirect to a different constructor. The [body] can be `null` if
+   * the constructor does not have a body.
+   */
+  ConstructorDeclaration constructorDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token externalKeyword,
+      Token constKeyword,
+      Token factoryKeyword,
+      Identifier returnType,
+      Token period,
+      SimpleIdentifier name,
+      FormalParameterList parameters,
+      Token separator,
+      List<ConstructorInitializer> initializers,
+      ConstructorName redirectedConstructor,
+      FunctionBody body);
+
+  /**
+   * Returns a newly created field initializer to initialize the field with
+   * the given name to the value of the given expression. The [thisKeyword] and
+   * [period] can be `null` if the 'this' keyword was not specified.
+   */
+  ConstructorFieldInitializer constructorFieldInitializer(
+      Token thisKeyword,
+      Token period,
+      SimpleIdentifier fieldName,
+      Token equals,
+      Expression expression);
+
+  /**
+   * Returns a newly created constructor name. The [period] and [name] can be
+   * `null` if the constructor being named is the unnamed constructor.
+   */
+  ConstructorName constructorName(
+      TypeName type, Token period, SimpleIdentifier name);
+
+  /**
+   * Returns a newly created continue statement. The [label] can be `null` if
+   * there is no label associated with the statement.
+   */
+  ContinueStatement continueStatement(
+      Token continueKeyword, SimpleIdentifier label, Token semicolon);
+
+  /**
+   * Returns a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [keyword] can be `null` if a type name is
+   * given. The [type] must be `null` if the keyword is 'var'.
+   */
+  DeclaredIdentifier declaredIdentifier(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      SimpleIdentifier identifier);
+
+  /**
+   * Returns a newly created default formal parameter. The [separator] and
+   * [defaultValue] can be `null` if there is no default value.
+   */
+  DefaultFormalParameter defaultFormalParameter(NormalFormalParameter parameter,
+      ParameterKind kind, Token separator, Expression defaultValue);
+
+  /**
+   * Returns a documentation comment consisting of the given [tokens] and having
+   * the given [references] (if supplied) embedded within it.
+   */
+  Comment documentationComment(
+      List<Token> tokens, [List<CommentReference> references]);
+
+  /**
+   * Returns a newly created do loop.
+   */
+  DoStatement doStatement(
+      Token doKeyword,
+      Statement body,
+      Token whileKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      Token semicolon);
+
+  /**
+   * Returns a newly created dotted name.
+   */
+  DottedName dottedName(List<SimpleIdentifier> components);
+
+  /**
+   * Returns a newly created floating point literal.
+   */
+  DoubleLiteral doubleLiteral(Token literal, double value);
+
+  /**
+   * Returns a newly created function body.
+   */
+  EmptyFunctionBody emptyFunctionBody(Token semicolon);
+
+  /**
+   * Returns a newly created empty statement.
+   */
+  EmptyStatement emptyStatement(Token semicolon);
+
+  /**
+   * Returns an end-of-line comment consisting of the given [tokens].
+   */
+  Comment endOfLineComment(List<Token> tokens);
+
+  /**
+   * Returns a newly created enum constant declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the constant does not have the
+   * corresponding attribute. (Technically, enum constants cannot have metadata,
+   * but we allow it for consistency.)
+   */
+  EnumConstantDeclaration enumConstantDeclaration(
+      Comment comment, List<Annotation> metadata, SimpleIdentifier name);
+
+  /**
+   * Returns a newly created enumeration declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The list of [constants] must contain at least one
+   * value.
+   */
+  EnumDeclaration enumDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token enumKeyword,
+      SimpleIdentifier name,
+      Token leftBracket,
+      List<EnumConstantDeclaration> constants,
+      Token rightBracket);
+
+  /**
+   * Returns a newly created export directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  ExportDirective exportDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      Token semicolon);
+  /**
+   * Returns a newly created function body consisting of a block of
+   * statements. The [keyword] can be `null` if the function body is not an
+   * async function body.
+   */
+  ExpressionFunctionBody expressionFunctionBody(Token keyword,
+      Token functionDefinition, Expression expression, Token semicolon);
+
+  /**
+   * Returns a newly created expression statement.
+   */
+  ExpressionStatement expressionStatement(
+      Expression expression, Token semicolon);
+
+  /**
+   * Returns a newly created extends clause.
+   */
+  ExtendsClause extendsClause(Token extendsKeyword, TypeName superclass);
+
+  /**
+   * Returns a newly created field declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [staticKeyword] can be `null` if the field is
+   * not a static field.
+   */
+  FieldDeclaration fieldDeclaration(Comment comment, List<Annotation> metadata,
+      Token staticKeyword, VariableDeclarationList fieldList, Token semicolon);
+
+  /**
+   * Returns a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [keyword] can be `null` if there is a type.
+   * The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
+   * [period] can be `null` if the keyword 'this' was not provided.  The
+   * [parameters] can be `null` if this is not a function-typed field formal
+   * parameter.
+   */
+  FieldFormalParameter fieldFormalParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      Token thisKeyword,
+      Token period,
+      SimpleIdentifier identifier,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters);
+
+  /**
+   * Returns a newly created for-each statement whose loop control variable
+   * is declared internally (in the for-loop part). The [awaitKeyword] can be
+   * `null` if this is not an asynchronous for loop.
+   */
+  ForEachStatement forEachStatementWithDeclaration(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      DeclaredIdentifier loopVariable,
+      Token inKeyword,
+      Expression iterator,
+      Token rightParenthesis,
+      Statement body);
+
+  /**
+   * Returns a newly created for-each statement whose loop control variable
+   * is declared outside the for loop. The [awaitKeyword] can be `null` if this
+   * is not an asynchronous for loop.
+   */
+  ForEachStatement forEachStatementWithReference(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      SimpleIdentifier identifier,
+      Token inKeyword,
+      Expression iterator,
+      Token rightParenthesis,
+      Statement body);
+
+  /**
+   * Returns a newly created parameter list. The list of [parameters] can be
+   * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
+   * can be `null` if there are no optional parameters.
+   */
+  FormalParameterList formalParameterList(
+      Token leftParenthesis,
+      List<FormalParameter> parameters,
+      Token leftDelimiter,
+      Token rightDelimiter,
+      Token rightParenthesis);
+
+  /**
+   * Returns a newly created for statement. Either the [variableList] or the
+   * [initialization] must be `null`. Either the [condition] and the list of
+   * [updaters] can be `null` if the loop does not have the corresponding
+   * attribute.
+   */
+  ForStatement forStatement(
+      Token forKeyword,
+      Token leftParenthesis,
+      VariableDeclarationList variableList,
+      Expression initialization,
+      Token leftSeparator,
+      Expression condition,
+      Token rightSeparator,
+      List<Expression> updaters,
+      Token rightParenthesis,
+      Statement body);
+
+  /**
+   * Returns a newly created function declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [externalKeyword] can be `null` if the
+   * function is not an external function. The [returnType] can be `null` if no
+   * return type was specified. The [propertyKeyword] can be `null` if the
+   * function is neither a getter or a setter.
+   */
+  FunctionDeclaration functionDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token externalKeyword,
+      TypeName returnType,
+      Token propertyKeyword,
+      SimpleIdentifier name,
+      FunctionExpression functionExpression);
+
+  /**
+   * Returns a newly created function declaration statement.
+   */
+  FunctionDeclarationStatement functionDeclarationStatement(
+      FunctionDeclaration functionDeclaration);
+
+  /**
+   * Returns a newly created function declaration.
+   */
+  FunctionExpression functionExpression(TypeParameterList typeParameters,
+      FormalParameterList parameters, FunctionBody body);
+
+  /**
+   * Returns a newly created function expression invocation.
+   */
+  FunctionExpressionInvocation functionExpressionInvocation(Expression function,
+      TypeArgumentList typeArguments, ArgumentList argumentList);
+
+  /**
+   * Returns a newly created function type alias. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [returnType] can be `null` if no return type
+   * was specified. The [typeParameters] can be `null` if the function has no
+   * type parameters.
+   */
+  FunctionTypeAlias functionTypeAlias(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName returnType,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      Token semicolon);
+
+  /**
+   * Returns a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [returnType] can be `null` if no return type
+   * was specified.
+   */
+  FunctionTypedFormalParameter functionTypedFormalParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      TypeName returnType,
+      SimpleIdentifier identifier,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      {Token question: null});
+
+  /**
+   * Returns a newly created import show combinator.
+   */
+  HideCombinator hideCombinator(
+      Token keyword, List<SimpleIdentifier> hiddenNames);
+
+  /**
+   * Returns a newly created if statement. The [elseKeyword] and
+   * [elseStatement] can be `null` if there is no else clause.
+   */
+  IfStatement ifStatement(
+      Token ifKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      Statement thenStatement,
+      Token elseKeyword,
+      Statement elseStatement);
+
+  /**
+   * Returns a newly created implements clause.
+   */
+  ImplementsClause implementsClause(
+      Token implementsKeyword, List<TypeName> interfaces);
+
+  /**
+   * Returns a newly created import directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [deferredKeyword] can be `null` if the import
+   * is not deferred. The [asKeyword] and [prefix] can be `null` if the import
+   * does not specify a prefix. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  ImportDirective importDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      Token deferredKeyword,
+      Token asKeyword,
+      SimpleIdentifier prefix,
+      List<Combinator> combinators,
+      Token semicolon);
+
+  /**
+   * Returns a newly created index expression.
+   */
+  IndexExpression indexExpressionForCascade(
+      Token period, Token leftBracket, Expression index, Token rightBracket);
+
+  /**
+   * Returns a newly created index expression.
+   */
+  IndexExpression indexExpressionForTarget(Expression target, Token leftBracket,
+      Expression index, Token rightBracket);
+
+  /**
+   * Returns a newly created instance creation expression.
+   */
+  InstanceCreationExpression instanceCreationExpression(Token keyword,
+      ConstructorName constructorName, ArgumentList argumentList);
+
+  /**
+   * Returns a newly created integer literal.
+   */
+  IntegerLiteral integerLiteral(Token literal, int value);
+
+  /**
+   * Returns a newly created interpolation expression.
+   */
+  InterpolationExpression interpolationExpression(
+      Token leftBracket, Expression expression, Token rightBracket);
+
+  /**
+   * Returns a newly created string of characters that are part of a string
+   * interpolation.
+   */
+  InterpolationString interpolationString(Token contents, String value);
+
+  /**
+   * Returns a newly created is expression. The [notOperator] can be `null`
+   * if the sense of the test is not negated.
+   */
+  IsExpression isExpression(Expression expression, Token isOperator,
+      Token notOperator, TypeName type);
+
+  /**
+   * Returns a newly created label.
+   */
+  Label label(SimpleIdentifier label, Token colon);
+
+  /**
+   * Returns a newly created labeled statement.
+   */
+  LabeledStatement labeledStatement(List<Label> labels, Statement statement);
+
+  /**
+   * Returns a newly created library directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  LibraryDirective libraryDirective(Comment comment, List<Annotation> metadata,
+      Token libraryKeyword, LibraryIdentifier name, Token semicolon);
+
+  /**
+   * Returns a newly created prefixed identifier.
+   */
+  LibraryIdentifier libraryIdentifier(List<SimpleIdentifier> components);
+
+  /**
+   * Returns a newly created list literal. The [constKeyword] can be `null`
+   * if the literal is not a constant. The [typeArguments] can be `null` if no
+   * type arguments were declared. The list of [elements] can be `null` if the
+   * list is empty.
+   */
+  ListLiteral listLiteral(Token constKeyword, TypeArgumentList typeArguments,
+      Token leftBracket, List<Expression> elements, Token rightBracket);
+
+  /**
+   * Returns a newly created map literal. The [constKeyword] can be `null` if
+   * the literal is not a constant. The [typeArguments] can be `null` if no type
+   * arguments were declared. The [entries] can be `null` if the map is empty.
+   */
+  MapLiteral mapLiteral(Token constKeyword, TypeArgumentList typeArguments,
+      Token leftBracket, List<MapLiteralEntry> entries, Token rightBracket);
+
+  /**
+   * Returns a newly created map literal entry.
+   */
+  MapLiteralEntry mapLiteralEntry(
+      Expression key, Token separator, Expression value);
+
+  /**
+   * Returns a newly created method declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [externalKeyword] can be `null` if the method
+   * is not external. The [modifierKeyword] can be `null` if the method is
+   * neither abstract nor static. The [returnType] can be `null` if no return
+   * type was specified. The [propertyKeyword] can be `null` if the method is
+   * neither a getter or a setter. The [operatorKeyword] can be `null` if the
+   * method does not implement an operator. The [parameters] must be `null` if
+   * this method declares a getter.
+   */
+  MethodDeclaration methodDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token externalKeyword,
+      Token modifierKeyword,
+      TypeName returnType,
+      Token propertyKeyword,
+      Token operatorKeyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      FunctionBody body);
+
+  /**
+   * Returns a newly created method invocation. The [target] and [operator]
+   * can be `null` if there is no target.
+   */
+  MethodInvocation methodInvocation(
+      Expression target,
+      Token operator,
+      SimpleIdentifier methodName,
+      TypeArgumentList typeArguments,
+      ArgumentList argumentList);
+
+  /**
+   * Returns a newly created named expression..
+   */
+  NamedExpression namedExpression(Label name, Expression expression);
+
+  /**
+   * Returns a newly created native clause.
+   */
+  NativeClause nativeClause(Token nativeKeyword, StringLiteral name);
+
+  /**
+   * Returns a newly created function body consisting of the 'native' token,
+   * a string literal, and a semicolon.
+   */
+  NativeFunctionBody nativeFunctionBody(
+      Token nativeKeyword, StringLiteral stringLiteral, Token semicolon);
+
+  /**
+   * Returns a newly created list of nodes such that all of the nodes that
+   * are added to the list will have their parent set to the given [owner]. The
+   * list will initially be populated with the given [elements].
+   */
+  NodeList/*<E>*/ nodeList/*<E extends AstNode>*/(AstNode owner,
+      [List/*<E>*/ elements]);
+
+  /**
+   * Returns a newly created null literal.
+   */
+  NullLiteral nullLiteral(Token literal);
+
+  /**
+   * Returns a newly created parenthesized expression.
+   */
+  ParenthesizedExpression parenthesizedExpression(
+      Token leftParenthesis, Expression expression, Token rightParenthesis);
+
+  /**
+   * Returns a newly created part directive. Either or both of the [comment]
+   * and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  PartDirective partDirective(Comment comment, List<Annotation> metadata,
+      Token partKeyword, StringLiteral partUri, Token semicolon);
+
+  /**
+   * Returns a newly created part-of directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  PartOfDirective partOfDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token partKeyword,
+      Token ofKeyword,
+      StringLiteral uri,
+      LibraryIdentifier libraryName,
+      Token semicolon);
+
+  /**
+   * Returns a newly created postfix expression.
+   */
+  PostfixExpression postfixExpression(Expression operand, Token operator);
+
+  /**
+   * Returns a newly created prefixed identifier.
+   */
+  PrefixedIdentifier prefixedIdentifier(
+      SimpleIdentifier prefix, Token period, SimpleIdentifier identifier);
+
+  /**
+   * Returns a newly created prefix expression.
+   */
+  PrefixExpression prefixExpression(Token operator, Expression operand);
+
+  /**
+   * Returns a newly created property access expression.
+   */
+  PropertyAccess propertyAccess(
+      Expression target, Token operator, SimpleIdentifier propertyName);
+
+  /**
+   * Returns a newly created redirecting invocation to invoke the constructor
+   * with the given name with the given arguments. The [constructorName] can be
+   * `null` if the constructor being invoked is the unnamed constructor.
+   */
+  RedirectingConstructorInvocation redirectingConstructorInvocation(
+      Token thisKeyword,
+      Token period,
+      SimpleIdentifier constructorName,
+      ArgumentList argumentList);
+
+  /**
+   * Returns a newly created rethrow expression.
+   */
+  RethrowExpression rethrowExpression(Token rethrowKeyword);
+
+  /**
+   * Returns a newly created return statement. The [expression] can be `null`
+   * if no explicit value was provided.
+   */
+  ReturnStatement returnStatement(
+      Token returnKeyword, Expression expression, Token semicolon);
+
+  /**
+   * Returns a newly created script tag.
+   */
+  ScriptTag scriptTag(Token scriptTag);
+
+  /**
+   * Returns a newly created import show combinator.
+   */
+  ShowCombinator showCombinator(
+      Token keyword, List<SimpleIdentifier> shownNames);
+
+  /**
+   * Returns a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [keyword] can be `null` if a type was
+   * specified. The [type] must be `null` if the keyword is 'var'.
+   */
+  SimpleFormalParameter simpleFormalParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      SimpleIdentifier identifier);
+
+  /**
+   * Returns a newly created identifier.
+   */
+  SimpleIdentifier simpleIdentifier(Token token, {bool isDeclaration: false});
+
+  /**
+   * Returns a newly created simple string literal.
+   */
+  SimpleStringLiteral simpleStringLiteral(Token literal, String value);
+
+  /**
+   * Returns a newly created string interpolation expression.
+   */
+  StringInterpolation stringInterpolation(List<InterpolationElement> elements);
+
+  /**
+   * Returns a newly created super invocation to invoke the inherited
+   * constructor with the given name with the given arguments. The [period] and
+   * [constructorName] can be `null` if the constructor being invoked is the
+   * unnamed constructor.
+   */
+  SuperConstructorInvocation superConstructorInvocation(
+      Token superKeyword,
+      Token period,
+      SimpleIdentifier constructorName,
+      ArgumentList argumentList);
+
+  /**
+   * Returns a newly created super expression.
+   */
+  SuperExpression superExpression(Token superKeyword);
+
+  /**
+   * Returns a newly created switch case. The list of [labels] can be `null`
+   * if there are no labels.
+   */
+  SwitchCase switchCase(List<Label> labels, Token keyword,
+      Expression expression, Token colon, List<Statement> statements);
+
+  /**
+   * Returns a newly created switch default. The list of [labels] can be
+   * `null` if there are no labels.
+   */
+  SwitchDefault switchDefault(List<Label> labels, Token keyword, Token colon,
+      List<Statement> statements);
+  /**
+   * Returns a newly created switch statement. The list of [members] can be
+   * `null` if there are no switch members.
+   */
+  SwitchStatement switchStatement(
+      Token switchKeyword,
+      Token leftParenthesis,
+      Expression expression,
+      Token rightParenthesis,
+      Token leftBracket,
+      List<SwitchMember> members,
+      Token rightBracket);
+
+  /**
+   * Returns a newly created symbol literal.
+   */
+  SymbolLiteral symbolLiteral(Token poundSign, List<Token> components);
+
+  /**
+   * Returns a newly created this expression.
+   */
+  ThisExpression thisExpression(Token thisKeyword);
+
+  /**
+   * Returns a newly created throw expression.
+   */
+  ThrowExpression throwExpression(Token throwKeyword, Expression expression);
+
+  /**
+   * Returns a newly created top-level variable declaration. Either or both
+   * of the [comment] and [metadata] can be `null` if the variable does not have
+   * the corresponding attribute.
+   */
+  TopLevelVariableDeclaration topLevelVariableDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      VariableDeclarationList variableList,
+      Token semicolon);
+
+  /**
+   * Returns a newly created try statement. The list of [catchClauses] can be
+   * `null` if there are no catch clauses. The [finallyKeyword] and
+   * [finallyBlock] can be `null` if there is no finally clause.
+   */
+  TryStatement tryStatement(Token tryKeyword, Block body,
+      List<CatchClause> catchClauses, Token finallyKeyword, Block finallyBlock);
+
+  /**
+   * Returns a newly created list of type arguments.
+   */
+  TypeArgumentList typeArgumentList(
+      Token leftBracket, List<TypeName> arguments, Token rightBracket);
+
+  /**
+   * Returns a newly created type name. The [typeArguments] can be `null` if
+   * there are no type arguments.
+   */
+  TypeName typeName(Identifier name, TypeArgumentList typeArguments,
+      {Token question: null});
+
+  /**
+   * Returns a newly created type parameter. Either or both of the [comment]
+   * and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
+   * the parameter does not have an upper bound.
+   */
+  TypeParameter typeParameter(Comment comment, List<Annotation> metadata,
+      SimpleIdentifier name, Token extendsKeyword, TypeName bound);
+
+  /**
+   * Returns a newly created list of type parameters.
+   */
+  TypeParameterList typeParameterList(Token leftBracket,
+      List<TypeParameter> typeParameters, Token rightBracket);
+
+  /**
+   * Returns a newly created variable declaration. The [equals] and
+   * [initializer] can be `null` if there is no initializer.
+   */
+  VariableDeclaration variableDeclaration(
+      SimpleIdentifier name, Token equals, Expression initializer);
+
+  /**
+   * Returns a newly created variable declaration list. Either or both of the
+   * [comment] and [metadata] can be `null` if the variable list does not have
+   * the corresponding attribute. The [keyword] can be `null` if a type was
+   * specified. The [type] must be `null` if the keyword is 'var'.
+   */
+  VariableDeclarationList variableDeclarationList(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      List<VariableDeclaration> variables);
+
+  /**
+   * Returns a newly created variable declaration statement.
+   */
+  VariableDeclarationStatement variableDeclarationStatement(
+      VariableDeclarationList variableList, Token semicolon);
+
+  /**
+   * Returns a newly created while statement.
+   */
+  WhileStatement whileStatement(Token whileKeyword, Token leftParenthesis,
+      Expression condition, Token rightParenthesis, Statement body);
+
+  /**
+   * Returns a newly created with clause.
+   */
+  WithClause withClause(Token withKeyword, List<TypeName> mixinTypes);
+
+  /**
+   * Returns a newly created yield expression. The [star] can be `null` if no
+   * star was provided.
+   */
+  YieldStatement yieldStatement(
+      Token yieldKeyword, Token star, Expression expression, Token semicolon);
+}
diff --git a/pkg/analyzer/lib/dart/ast/standard_ast_factory.dart b/pkg/analyzer/lib/dart/ast/standard_ast_factory.dart
new file mode 100644
index 0000000..9333242
--- /dev/null
+++ b/pkg/analyzer/lib/dart/ast/standard_ast_factory.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/ast_factory.dart';
+
+/**
+ * Gets an instance of [AstFactory] based on the standard AST implementation.
+ */
+final AstFactory astFactory = new AstFactoryImpl();
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
index b5fe38f..9b09559 100644
--- a/pkg/analyzer/lib/source/error_processor.dart
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -8,8 +8,6 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/task/options.dart'
-    show CONFIGURED_ERROR_PROCESSORS;
 import 'package:analyzer/src/task/options.dart';
 import 'package:yaml/yaml.dart';
 
@@ -98,8 +96,7 @@
     }
 
     // Let the user configure how specific errors are processed.
-    List<ErrorProcessor> processors =
-        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    List<ErrorProcessor> processors = context.analysisOptions.errorProcessors;
 
     // Give strong mode a chance to upgrade it.
     if (context.analysisOptions.strongMode) {
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index c09171c..3068176 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -30,7 +30,6 @@
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/incremental_element_builder.dart';
 import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/html.dart';
@@ -38,13 +37,6 @@
 import 'package:html/dom.dart' show Document;
 
 /**
- * The descriptor used to associate exclude patterns with an analysis context in
- * configuration data.
- */
-final ListResultDescriptor<String> CONTEXT_EXCLUDES =
-    new ListResultDescriptorImpl('CONTEXT_EXCLUDES', const <String>[]);
-
-/**
  * Type of callback functions used by PendingFuture. Functions of this type
  * should perform a computation based on the data in [entry] and return it. If
  * the computation can't be performed yet because more analysis is needed,
@@ -281,8 +273,11 @@
             options.generateImplicitErrors ||
         this._options.generateSdkErrors != options.generateSdkErrors ||
         this._options.dart2jsHint != options.dart2jsHint ||
+        _notEqual(this._options.errorProcessors, options.errorProcessors) ||
+        _notEqual(this._options.excludePatterns, options.excludePatterns) ||
         (this._options.hint && !options.hint) ||
         (this._options.lint && !options.lint) ||
+        _notEqual(this._options.lintRules, options.lintRules) ||
         this._options.preserveComments != options.preserveComments ||
         this._options.strongMode != options.strongMode ||
         this._options.enableAssertInitializer !=
@@ -306,7 +301,6 @@
             : false) ||
         this._options.enableStrictCallChecks !=
             options.enableStrictCallChecks ||
-        this._options.enableGenericMethods != options.enableGenericMethods ||
         this._options.enableSuperMixins != options.enableSuperMixins ||
         this._options.patchPlatform != options.patchPlatform;
     this._options.analyzeFunctionBodiesPredicate =
@@ -314,7 +308,6 @@
     this._options.generateImplicitErrors = options.generateImplicitErrors;
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
-    this._options.enableGenericMethods = options.enableGenericMethods;
     this._options.enableAssertInitializer = options.enableAssertInitializer;
     this._options.enableAssertMessage = options.enableAssertMessage;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
@@ -324,11 +317,14 @@
         options.enableLazyAssignmentOperators;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.enableTiming = options.enableTiming;
+    this._options.errorProcessors = options.errorProcessors;
+    this._options.excludePatterns = options.excludePatterns;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
     this._options.incrementalApi = options.incrementalApi;
     this._options.incrementalValidation = options.incrementalValidation;
     this._options.lint = options.lint;
+    this._options.lintRules = options.lintRules;
     this._options.preserveComments = options.preserveComments;
     if (this._options.strongMode != options.strongMode) {
       _typeSystem = null;
@@ -849,6 +845,7 @@
     return getResult(target, COMPILATION_UNIT_ELEMENT);
   }
 
+  @deprecated
   @override
   Object/*=V*/ getConfigurationData/*<V>*/(ResultDescriptor/*<V>*/ key) =>
       (_configurationData[key] ?? key?.defaultValue) as Object/*=V*/;
@@ -1309,6 +1306,7 @@
     }
   }
 
+  @deprecated
   @override
   void setConfigurationData(ResultDescriptor key, Object data) {
     _configurationData[key] = data;
@@ -1698,6 +1696,19 @@
     AnalysisEngine.instance.logger.logInformation(message);
   }
 
+  bool _notEqual/*<T>*/(List/*<T>*/ first, List/*<T>*/ second) {
+    int length = first.length;
+    if (length != second.length) {
+      return true;
+    }
+    for (int i = 0; i < length; i++) {
+      if (first[i] != second[i]) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /**
    * Notify all of the analysis listeners that the errors associated with the
    * given [source] has been updated to the given [errors].
diff --git a/pkg/analyzer/lib/src/dart/analysis/byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
index e8079ee..3f3f5db 100644
--- a/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
@@ -63,9 +63,11 @@
     List<int> bytes = _map.remove(key);
     if (bytes == null) {
       bytes = _store.get(key);
-      _map[key] = bytes;
-      _currentSizeBytes += bytes?.length ?? 0;
-      _evict();
+      if (bytes != null) {
+        _map[key] = bytes;
+        _currentSizeBytes += bytes.length;
+        _evict();
+      }
     } else {
       _map[key] = bytes;
     }
@@ -84,6 +86,10 @@
   void _evict() {
     while (_currentSizeBytes > _maxSizeBytes) {
       if (_map.isEmpty) {
+        // Should be impossible, since _currentSizeBytes should always match
+        // _map.  But recover anyway.
+        assert(false);
+        _currentSizeBytes = 0;
         break;
       }
       String key = _map.keys.first;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 0a43fa5..7d493d6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -7,6 +7,7 @@
 import 'dart:typed_data';
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement;
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -24,7 +25,8 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:analyzer/src/task/dart.dart' show COMPILATION_UNIT_ELEMENT;
+import 'package:analyzer/task/dart.dart' show LibrarySpecificUnit;
 
 /**
  * This class computes [AnalysisResult]s for Dart files.
@@ -69,7 +71,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 7;
+  static const int DATA_VERSION = 8;
 
   /**
    * The name of the driver, e.g. the name of the folder.
@@ -109,12 +111,12 @@
    * The [SourceFactory] is used to resolve URIs to paths and restore URIs
    * from file paths.
    */
-  final SourceFactory _sourceFactory;
+  final SourceFactory sourceFactory;
 
   /**
    * The analysis options to analyze with.
    */
-  final AnalysisOptions _analysisOptions;
+  final AnalysisOptions analysisOptions;
 
   /**
    * The salt to mix into all hashes used as keys for serialized data.
@@ -150,6 +152,17 @@
   final _requestedFiles = <String, List<Completer<AnalysisResult>>>{};
 
   /**
+   * The list of tasks to compute files referencing a name.
+   */
+  final _referencingNameTasks = <_FilesReferencingNameTask>[];
+
+  /**
+   * The mapping from the files for which the index was requested using
+   * [getIndex] to the [Completer]s to report the result.
+   */
+  final _indexRequestedFiles = <String, List<Completer<IndexResult>>>{};
+
+  /**
    * The set of files were reported as changed through [changeFile] and not
    * checked for actual changes yet.
    */
@@ -200,8 +213,8 @@
       this._byteStore,
       this._contentOverlay,
       SourceFactory sourceFactory,
-      this._analysisOptions)
-      : _sourceFactory = sourceFactory.clone() {
+      this.analysisOptions)
+      : sourceFactory = sourceFactory.clone() {
     _fillSalt();
     _sdkBundle = sourceFactory.dartSdk.getLinkedBundle();
     _fsState = new FileSystemState(
@@ -209,8 +222,8 @@
         _byteStore,
         _contentOverlay,
         _resourceProvider,
-        _sourceFactory,
-        _analysisOptions,
+        sourceFactory,
+        analysisOptions,
         _salt,
         _sdkBundle.apiSignature);
     _scheduler._add(this);
@@ -284,6 +297,12 @@
     if (_requestedFiles.isNotEmpty) {
       return AnalysisDriverPriority.interactive;
     }
+    if (_referencingNameTasks.isNotEmpty) {
+      return AnalysisDriverPriority.referencingName;
+    }
+    if (_indexRequestedFiles.isNotEmpty) {
+      return AnalysisDriverPriority.getIndex;
+    }
     if (_priorityFiles.isNotEmpty) {
       for (String path in _priorityFiles) {
         if (_filesToAnalyze.contains(path)) {
@@ -357,7 +376,36 @@
   }
 
   /**
-   * Return the [Future] that completes with a [AnalysisResult] for the Dart
+   * Return a [Future] that completes with the list of added files that
+   * reference the given external [name].
+   */
+  Future<List<String>> getFilesReferencingName(String name) {
+    var task = new _FilesReferencingNameTask(this, name);
+    _referencingNameTasks.add(task);
+    _statusSupport.transitionToAnalyzing();
+    _scheduler._notify(this);
+    return task.completer.future;
+  }
+
+  /**
+   * Return a [Future] that completes with the [IndexResult] for the file with
+   * the given [path].
+   */
+  Future<IndexResult> getIndex(String path) {
+    if (AnalysisEngine.isDartFileName(path)) {
+      var completer = new Completer<IndexResult>();
+      _indexRequestedFiles
+          .putIfAbsent(path, () => <Completer<IndexResult>>[])
+          .add(completer);
+      _statusSupport.transitionToAnalyzing();
+      _scheduler._notify(this);
+      return completer.future;
+    }
+    return new Future.value();
+  }
+
+  /**
+   * Return a [Future] that completes with a [AnalysisResult] for the Dart
    * file with the given [path]. If the file is not a Dart file, the [Future]
    * completes with `null`.
    *
@@ -385,7 +433,7 @@
   }
 
   /**
-   * Return the [Future] that completes with a [ParseResult] for the file
+   * Return a [Future] that completes with a [ParseResult] for the file
    * with the given [path].
    *
    * The [path] must be absolute and normalized.
@@ -477,19 +525,11 @@
         return null;
       }
 
-      // Prepare the key for the cached result.
-      String key = _getResolvedUnitKey(libraryFile, file);
-      if (key == null) {
-        _logger.run('Compute the dependency hash for $path', () {
-          _createLibraryContext(libraryFile);
-          key = _getResolvedUnitKey(libraryFile, file);
-        });
-      }
-
       // Check for the cached result.
+      String key = _getResolvedUnitKey(libraryFile, file);
       List<int> bytes = _byteStore.get(key);
       if (bytes != null) {
-        return _getAnalysisResultFromBytes(file, bytes);
+        return _getAnalysisResultFromBytes(libraryFile, file, bytes);
       }
     }
 
@@ -532,7 +572,7 @@
 
         // Return the result, full or partial.
         _logger.writeln('Computed new analysis result.');
-        return _getAnalysisResultFromBytes(file, bytes,
+        return _getAnalysisResultFromBytes(libraryFile, file, bytes,
             content: withUnit ? file.content : null,
             resolvedUnit: withUnit ? resolvedUnit : null);
       } finally {
@@ -541,12 +581,31 @@
     });
   }
 
+  IndexResult _computeIndexResult(String path) {
+    AnalysisResult analysisResult = _computeAnalysisResult(path,
+        withUnit: false, asIsIfPartWithoutLibrary: true);
+    FileState libraryFile = analysisResult._libraryFile;
+    FileState file = analysisResult._file;
+
+    // Create the AnalysisContext to resynthesize elements in.
+    _LibraryContext libraryContext = _createLibraryContext(libraryFile);
+    AnalysisContext analysisContext = _createAnalysisContext(libraryContext);
+
+    // Resynthesize the CompilationUnitElement in the context.
+    CompilationUnitElement unitElement = analysisContext.computeResult(
+        new LibrarySpecificUnit(libraryFile.source, file.source),
+        COMPILATION_UNIT_ELEMENT);
+
+    // Return as IndexResult.
+    return new IndexResult(unitElement, analysisResult._index);
+  }
+
   AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) {
     AnalysisContextImpl analysisContext =
         AnalysisEngine.instance.createAnalysisContext();
-    analysisContext.analysisOptions = _analysisOptions;
+    analysisContext.analysisOptions = analysisOptions;
 
-    analysisContext.sourceFactory = _sourceFactory.clone();
+    analysisContext.sourceFactory = sourceFactory.clone();
     analysisContext.resultProvider =
         new InputPackagesResultProvider(analysisContext, libraryContext.store);
     analysisContext
@@ -555,71 +614,58 @@
   }
 
   /**
-   * Return the context in which the library represented by the given
-   * [libraryFile] should be analyzed it.
-   *
-   * TODO(scheglov) We often don't need [SummaryDataStore], only dependency
-   * signature.
+   * Return the context in which the [library] should be analyzed it.
    */
-  _LibraryContext _createLibraryContext(FileState libraryFile) {
+  _LibraryContext _createLibraryContext(FileState library) {
     return _logger.run('Create library context', () {
-      Map<String, _LibraryNode> nodes = <String, _LibraryNode>{};
+      Map<String, FileState> libraries = <String, FileState>{};
       SummaryDataStore store = new SummaryDataStore(const <String>[]);
       store.addBundle(null, _sdkBundle);
 
-      _LibraryNode createLibraryNodes(FileState libraryFile) {
-        Uri libraryUri = libraryFile.uri;
-
+      void appendLibraryFiles(FileState library) {
         // URIs with the 'dart:' scheme are served from the SDK bundle.
-        if (libraryUri.scheme == 'dart') {
+        if (library.uri.scheme == 'dart') {
           return null;
         }
 
-        String libraryUriStr = libraryUri.toString();
-        _LibraryNode node = nodes[libraryUriStr];
-        if (node == null) {
-          node = new _LibraryNode(this, libraryFile, libraryUri);
-          nodes[libraryUriStr] = node;
+        if (!libraries.containsKey(library.uriStr)) {
+          libraries[library.uriStr] = library;
 
           // Append the defining unit.
           {
-            UnlinkedUnit unlinked = libraryFile.unlinked;
-            _addToStoreUnlinked(store, libraryFile.uri, unlinked);
+            UnlinkedUnit unlinked = library.unlinked;
+            _addToStoreUnlinked(store, library.uri, unlinked);
           }
 
           // Append parts.
-          for (FileState part in libraryFile.partedFiles) {
+          for (FileState part in library.partedFiles) {
             UnlinkedUnit unlinked = part.unlinked;
             _addToStoreUnlinked(store, part.uri, unlinked);
           }
 
-          // Create nodes for referenced libraries.
-          libraryFile.importedFiles.forEach(createLibraryNodes);
-          libraryFile.exportedFiles.forEach(createLibraryNodes);
+          // Append referenced libraries.
+          library.importedFiles.forEach(appendLibraryFiles);
+          library.exportedFiles.forEach(appendLibraryFiles);
         }
-
-        // Done with this node.
-        return node;
       }
 
-      _LibraryNode libraryNode = _logger.run('Compute library nodes', () {
-        return createLibraryNodes(libraryFile);
+      _logger.run('Append library files', () {
+        return appendLibraryFiles(library);
       });
 
       Set<String> libraryUrisToLink = new Set<String>();
       _logger.run('Load linked bundles', () {
-        for (_LibraryNode node in nodes.values) {
-          String key = '${node.dependencySignature}.linked';
+        for (FileState library in libraries.values) {
+          String key = '${library.transitiveSignature}.linked';
           List<int> bytes = _byteStore.get(key);
           if (bytes != null) {
-            PackageBundle linked = new PackageBundle.fromBuffer(bytes);
-            _addToStoreLinked(
-                store, node.file.uri.toString(), linked.linkedLibraries.single);
+            LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
+            _addToStoreLinked(store, library.uriStr, linked);
           } else {
-            libraryUrisToLink.add(node.uri.toString());
+            libraryUrisToLink.add(library.uriStr);
           }
         }
-        int numOfLoaded = nodes.length - libraryUrisToLink.length;
+        int numOfLoaded = libraries.length - libraryUrisToLink.length;
         _logger.writeln('Loaded $numOfLoaded linked bundles.');
       });
 
@@ -631,25 +677,20 @@
         }, (String uri) {
           UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
           return unlinkedUnit;
-        }, (_) => null, _analysisOptions.strongMode);
+        }, (_) => null, analysisOptions.strongMode);
         _logger.writeln('Linked ${linkedLibraries.length} bundles.');
       });
 
       linkedLibraries.forEach((uri, linkedBuilder) {
-        _LibraryNode node = nodes[uri];
-        String key = '${node.dependencySignature}.linked';
-        List<int> bytes;
-        {
-          PackageBundleAssembler assembler = new PackageBundleAssembler();
-          assembler.addLinkedLibrary(uri, linkedBuilder);
-          bytes = assembler.assemble().toBuffer();
-        }
-        PackageBundle linked = new PackageBundle.fromBuffer(bytes);
-        _addToStoreLinked(store, uri, linked.linkedLibraries.single);
+        FileState library = libraries[uri];
+        String key = '${library.transitiveSignature}.linked';
+        List<int> bytes = linkedBuilder.toBuffer();
+        LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
+        _addToStoreLinked(store, uri, linked);
         _byteStore.put(key, bytes);
       });
 
-      return new _LibraryContext(libraryFile, libraryNode, store);
+      return new _LibraryContext(library, store);
     });
   }
 
@@ -658,8 +699,7 @@
    */
   void _fillSalt() {
     _salt[0] = DATA_VERSION;
-    List<int> crossContextOptions =
-        _analysisOptions.encodeCrossContextOptions();
+    List<int> crossContextOptions = analysisOptions.encodeCrossContextOptions();
     assert(crossContextOptions.length ==
         AnalysisOptions.crossContextOptionsLength);
     for (int i = 0; i < crossContextOptions.length; i++) {
@@ -671,20 +711,31 @@
    * Load the [AnalysisResult] for the given [file] from the [bytes]. Set
    * optional [content] and [resolvedUnit].
    */
-  AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes,
+  AnalysisResult _getAnalysisResultFromBytes(
+      FileState libraryFile, FileState file, List<int> bytes,
       {String content, CompilationUnit resolvedUnit}) {
     var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes);
-    List<AnalysisError> errors = unit.errors
-        .map((error) => new AnalysisError.forValues(
-            file.source,
-            error.offset,
-            error.length,
-            errorCodeByUniqueName(error.uniqueName),
-            error.message,
-            error.correction))
-        .toList();
-    return new AnalysisResult(_sourceFactory, file.path, file.uri, content,
-        file.contentHash, file.lineInfo, resolvedUnit, errors, unit.index);
+    List<AnalysisError> errors = unit.errors.map((error) {
+      String errorName = error.uniqueName;
+      ErrorCode errorCode = errorCodeByUniqueName(errorName);
+      if (errorCode == null) {
+        throw new StateError('No ErrorCode for $errorName in $file');
+      }
+      return new AnalysisError.forValues(file.source, error.offset,
+          error.length, errorCode, error.message, error.correction);
+    }).toList();
+    return new AnalysisResult(
+        libraryFile,
+        file,
+        sourceFactory,
+        file.path,
+        file.uri,
+        content,
+        file.contentHash,
+        file.lineInfo,
+        resolvedUnit,
+        errors,
+        unit.index);
   }
 
   /**
@@ -732,6 +783,26 @@
       return;
     }
 
+    // Process an index request.
+    if (_indexRequestedFiles.isNotEmpty) {
+      String path = _indexRequestedFiles.keys.first;
+      IndexResult result = _computeIndexResult(path);
+      _indexRequestedFiles.remove(path).forEach((completer) {
+        completer.complete(result);
+      });
+      return;
+    }
+
+    // Compute files referencing a name.
+    if (_referencingNameTasks.isNotEmpty) {
+      _FilesReferencingNameTask task = _referencingNameTasks.first;
+      bool isDone = await task.perform();
+      if (isDone) {
+        _referencingNameTasks.remove(task);
+      }
+      return;
+    }
+
     // Analyze a priority file.
     if (_priorityFiles.isNotEmpty) {
       for (String path in _priorityFiles) {
@@ -823,7 +894,14 @@
  * of the list, the earlier the corresponding [AnalysisDriver] should be asked
  * to perform work.
  */
-enum AnalysisDriverPriority { nothing, general, priority, interactive }
+enum AnalysisDriverPriority {
+  nothing,
+  general,
+  priority,
+  referencingName,
+  getIndex,
+  interactive
+}
 
 /**
  * Instances of this class schedule work in multiple [AnalysisDriver]s so that
@@ -959,6 +1037,9 @@
  * any previously returned result, even inside of the same library.
  */
 class AnalysisResult {
+  final FileState _libraryFile;
+  final FileState _file;
+
   /**
    * The [SourceFactory] with which the file was analyzed.
    */
@@ -1004,10 +1085,37 @@
   /**
    * The index of the unit.
    */
+  final AnalysisDriverUnitIndex _index;
+
+  AnalysisResult(
+      this._libraryFile,
+      this._file,
+      this.sourceFactory,
+      this.path,
+      this.uri,
+      this.content,
+      this.contentHash,
+      this.lineInfo,
+      this.unit,
+      this.errors,
+      this._index);
+}
+
+/**
+ * The result of indexing of a single file.
+ */
+class IndexResult {
+  /**
+   * The element of the file.
+   */
+  final CompilationUnitElement unitElement;
+
+  /**
+   * The index of the file.
+   */
   final AnalysisDriverUnitIndex index;
 
-  AnalysisResult(this.sourceFactory, this.path, this.uri, this.content,
-      this.contentHash, this.lineInfo, this.unit, this.errors, this.index);
+  IndexResult(this.unitElement, this.index);
 }
 
 /**
@@ -1132,33 +1240,64 @@
 }
 
 /**
+ * Task that computes the list of files that were added to the driver and
+ * have at least one reference to an identifier [name] defined outside of the
+ * file.
+ */
+class _FilesReferencingNameTask {
+  final AnalysisDriver driver;
+  final String name;
+  final Completer<List<String>> completer = new Completer<List<String>>();
+
+  final List<String> referencingFiles = <String>[];
+  final Set<String> checkedFiles = new Set<String>();
+  final List<String> filesToCheck = <String>[];
+
+  _FilesReferencingNameTask(this.driver, this.name);
+
+  /**
+   * Perform work for a fixed length of time, and either complete the
+   * [completer] and return `true` to indicate that the task is done, return
+   * `false` to indicate that the task should continue to be run.
+   *
+   * Relinquishing execution flow and running event loop after every file
+   * works, but has too much overhead. Instead we use a fixed length of time,
+   * so we can spend less time overall and keep quick enough response time.
+   */
+  Future<bool> perform() async {
+    Stopwatch timer = new Stopwatch()..start();
+    while (timer.elapsedMilliseconds < 5) {
+      // Prepare files to check.
+      if (filesToCheck.isEmpty) {
+        Set<String> newFiles = driver.addedFiles.difference(checkedFiles);
+        filesToCheck.addAll(newFiles);
+      }
+
+      // If no more files to check, complete and done.
+      if (filesToCheck.isEmpty) {
+        completer.complete(referencingFiles);
+        return true;
+      }
+
+      // Check the next file.
+      String path = filesToCheck.removeLast();
+      FileState file = driver._fsState.getFileForPath(path);
+      if (file.referencedNames.contains(name)) {
+        referencingFiles.add(path);
+      }
+      checkedFiles.add(path);
+    }
+
+    // We're not done yet.
+    return false;
+  }
+}
+
+/**
  * TODO(scheglov) document
  */
 class _LibraryContext {
   final FileState file;
-  final _LibraryNode node;
   final SummaryDataStore store;
-  _LibraryContext(this.file, this.node, this.store);
-}
-
-class _LibraryNode {
-  final AnalysisDriver driver;
-  final FileState file;
-  final Uri uri;
-
-  _LibraryNode(this.driver, this.file, this.uri);
-
-  String get dependencySignature {
-    return file.transitiveSignature;
-  }
-
-  @override
-  int get hashCode => uri.hashCode;
-
-  bool operator ==(other) {
-    return other is _LibraryNode && other.uri == uri;
-  }
-
-  @override
-  String toString() => uri.toString();
+  _LibraryContext(this.file, this.store);
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 3540d69..3a88ed6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -209,6 +209,11 @@
    */
   UnlinkedUnit get unlinked => _unlinked;
 
+  /**
+   * Return the [uri] string.
+   */
+  String get uriStr => uri.toString();
+
   @override
   bool operator ==(Object other) {
     return other is FileState && other.uri == uri;
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 8191ca4..6b5c09c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -426,6 +426,7 @@
     ElementKind elementKind = element?.kind;
     if (elementKind == null ||
         elementKind == ElementKind.DYNAMIC ||
+        elementKind == ElementKind.ERROR ||
         elementKind == ElementKind.LABEL ||
         elementKind == ElementKind.LOCAL_VARIABLE ||
         elementKind == ElementKind.PREFIX ||
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index e28a5b6..2c3448c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -9,8 +9,18 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/index.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:collection/collection.dart';
+
+Element _getEnclosingElement(CompilationUnitElement unitElement, int offset) {
+  var finder = new _ContainingElementFinder(offset);
+  unitElement.accept(finder);
+  return finder.containingElement;
+}
 
 /**
  * Search support for an [AnalysisDriver].
@@ -21,47 +31,170 @@
   Search(this._driver);
 
   /**
-   * Returns references to the element at the given [offset] in the file with
-   * the given [path].
+   * Returns references to the [element].
    */
-  Future<List<SearchResult>> references(String path, int offset) async {
-    // Search only in added files.
-    if (!_driver.addedFiles.contains(path)) {
-      return const <SearchResult>[];
-    }
-
-    AnalysisResult analysisResult = await _driver.getResult(path);
-    CompilationUnit unit = analysisResult.unit;
-
-    // Prepare the node.
-    AstNode node = new NodeLocator(offset).searchWithin(unit);
-    if (node == null) {
-      return const <SearchResult>[];
-    }
-
-    // Prepare the element.
-    Element element = ElementLocator.locate(node);
+  Future<List<SearchResult>> references(Element element) async {
     if (element == null) {
       return const <SearchResult>[];
     }
 
     ElementKind kind = element.kind;
-    if (kind == ElementKind.LABEL || kind == ElementKind.LOCAL_VARIABLE) {
-      Block block = node.getAncestor((n) => n is Block);
-      return _searchReferences_Local(element, unit.element, block);
+    if (kind == ElementKind.CLASS ||
+        kind == ElementKind.COMPILATION_UNIT ||
+        kind == ElementKind.CONSTRUCTOR ||
+        kind == ElementKind.FUNCTION_TYPE_ALIAS ||
+        kind == ElementKind.SETTER) {
+      return _searchReferences(element);
+    } else if (kind == ElementKind.GETTER) {
+      return _searchReferences_Getter(element);
+    } else if (kind == ElementKind.FIELD ||
+        kind == ElementKind.TOP_LEVEL_VARIABLE) {
+      return _searchReferences_Field(element);
+    } else if (kind == ElementKind.FUNCTION || kind == ElementKind.METHOD) {
+      if (element.enclosingElement is ExecutableElement) {
+        return _searchReferences_Local(element, (n) => n is Block);
+      }
+      return _searchReferences_Function(element);
+    } else if (kind == ElementKind.LABEL ||
+        kind == ElementKind.LOCAL_VARIABLE) {
+      return _searchReferences_Local(element, (n) => n is Block);
+    } else if (kind == ElementKind.PARAMETER) {
+      return _searchReferences_Parameter(element);
+    } else if (kind == ElementKind.TYPE_PARAMETER) {
+      return _searchReferences_Local(
+          element, (n) => n.parent is CompilationUnit);
     }
     // TODO(scheglov) support other kinds
-    return [];
+    return const <SearchResult>[];
+  }
+
+  Future<Null> _addResults(List<SearchResult> results, Element element,
+      IndexRelationKind relationKind, SearchResultKind resultKind) async {
+    String path = element.source.fullName;
+
+    // If the file with the element is not known, then the element is not used.
+    if (!_driver.knownFiles.contains(path)) {
+      return;
+    }
+
+    // TODO(scheglov) optimize for private elements
+    String name = element.displayName;
+
+    // Prepare the list of files that reference the element name.
+    List<String> files = await _driver.getFilesReferencingName(name);
+    if (!files.contains(path) && _driver.addedFiles.contains(path)) {
+      files.add(path);
+    }
+
+    // Check the index of every file that references the element name.
+    for (String file in files) {
+      IndexResult result = await _driver.getIndex(file);
+      _IndexRequest request = new _IndexRequest(result.index);
+      int elementId = request.findElementId(element);
+      if (elementId != -1) {
+        CompilationUnitElement unitElement = result.unitElement;
+        List<SearchResult> fileResults = request.getRelations(
+            elementId, relationKind, resultKind, unitElement);
+        results.addAll(fileResults);
+      }
+    }
+  }
+
+  Future<List<SearchResult>> _searchReferences(Element element) async {
+    List<SearchResult> results = <SearchResult>[];
+    await _addResults(results, element, IndexRelationKind.IS_REFERENCED_BY,
+        SearchResultKind.REFERENCE);
+    return results;
+  }
+
+  Future<List<SearchResult>> _searchReferences_Field(
+      PropertyInducingElement field) async {
+    List<SearchResult> results = <SearchResult>[];
+    PropertyAccessorElement getter = field.getter;
+    PropertyAccessorElement setter = field.setter;
+    if (!field.isSynthetic) {
+      await _addResults(results, field, IndexRelationKind.IS_WRITTEN_BY,
+          SearchResultKind.WRITE);
+      await _addResults(results, field, IndexRelationKind.IS_REFERENCED_BY,
+          SearchResultKind.REFERENCE);
+    }
+    if (getter != null) {
+      await _addResults(results, getter, IndexRelationKind.IS_REFERENCED_BY,
+          SearchResultKind.READ);
+      await _addResults(results, getter, IndexRelationKind.IS_INVOKED_BY,
+          SearchResultKind.INVOCATION);
+    }
+    if (setter != null) {
+      await _addResults(results, setter, IndexRelationKind.IS_REFERENCED_BY,
+          SearchResultKind.WRITE);
+    }
+    return results;
+  }
+
+  Future<List<SearchResult>> _searchReferences_Function(Element element) async {
+    if (element is Member) {
+      element = (element as Member).baseElement;
+    }
+    List<SearchResult> results = <SearchResult>[];
+    await _addResults(results, element, IndexRelationKind.IS_REFERENCED_BY,
+        SearchResultKind.REFERENCE);
+    await _addResults(results, element, IndexRelationKind.IS_INVOKED_BY,
+        SearchResultKind.INVOCATION);
+    return results;
+  }
+
+  Future<List<SearchResult>> _searchReferences_Getter(
+      PropertyAccessorElement getter) async {
+    List<SearchResult> results = <SearchResult>[];
+    await _addResults(results, getter, IndexRelationKind.IS_REFERENCED_BY,
+        SearchResultKind.REFERENCE);
+    await _addResults(results, getter, IndexRelationKind.IS_INVOKED_BY,
+        SearchResultKind.INVOCATION);
+    return results;
   }
 
   Future<List<SearchResult>> _searchReferences_Local(
-      Element element,
-      CompilationUnitElement enclosingUnitElement,
-      AstNode enclosingNode) async {
+      Element element, bool isRootNode(AstNode n)) async {
+    String path = element.source.fullName;
+    if (!_driver.addedFiles.contains(path)) {
+      return const <SearchResult>[];
+    }
+
+    // Prepare the unit.
+    AnalysisResult analysisResult = await _driver.getResult(path);
+    CompilationUnit unit = analysisResult.unit;
+    if (unit == null) {
+      return const <SearchResult>[];
+    }
+
+    // Prepare the node.
+    AstNode node = new NodeLocator(element.nameOffset).searchWithin(unit);
+    if (node == null) {
+      return const <SearchResult>[];
+    }
+
+    // Prepare the enclosing node.
+    AstNode enclosingNode = node.getAncestor(isRootNode);
+    if (enclosingNode == null) {
+      return const <SearchResult>[];
+    }
+
+    // Find the matches.
     _LocalReferencesVisitor visitor =
-        new _LocalReferencesVisitor(element, enclosingUnitElement);
-    enclosingNode?.accept(visitor);
-    return visitor.matches;
+        new _LocalReferencesVisitor(element, unit.element);
+    enclosingNode.accept(visitor);
+    return visitor.results;
+  }
+
+  Future<List<SearchResult>> _searchReferences_Parameter(
+      ParameterElement parameter) async {
+    List<SearchResult> results = <SearchResult>[];
+    results.addAll(await _searchReferences(parameter));
+    results.addAll(await _searchReferences_Local(parameter, (AstNode node) {
+      AstNode parent = node.parent;
+      return parent is ClassDeclaration || parent is CompilationUnit;
+    }));
+    return results;
   }
 }
 
@@ -112,6 +245,8 @@
     StringBuffer buffer = new StringBuffer();
     buffer.write("SearchResult(kind=");
     buffer.write(kind);
+    buffer.write(", enclosingElement=");
+    buffer.write(enclosingElement);
     buffer.write(", offset=");
     buffer.write(offset);
     buffer.write(", length=");
@@ -120,8 +255,6 @@
     buffer.write(isResolved);
     buffer.write(", isQualified=");
     buffer.write(isQualified);
-    buffer.write(", enclosingElement=");
-    buffer.write(enclosingElement);
     buffer.write(")");
     return buffer.toString();
   }
@@ -153,13 +286,196 @@
   }
 }
 
+class _IndexRequest {
+  final AnalysisDriverUnitIndex index;
+
+  _IndexRequest(this.index);
+
+  /**
+   * Return the [element]'s identifier in the [index] or `-1` if the
+   * [element] is not referenced in the [index].
+   */
+  int findElementId(Element element) {
+    IndexElementInfo info = new IndexElementInfo(element);
+    element = info.element;
+    // Find the id of the element's unit.
+    int unitId = getUnitId(element);
+    if (unitId == -1) {
+      return -1;
+    }
+    // Prepare information about the element.
+    int unitMemberId = getElementUnitMemberId(element);
+    if (unitMemberId == -1) {
+      return -1;
+    }
+    int classMemberId = getElementClassMemberId(element);
+    if (classMemberId == -1) {
+      return -1;
+    }
+    int parameterId = getElementParameterId(element);
+    if (parameterId == -1) {
+      return -1;
+    }
+    // Try to find the element id using classMemberId, parameterId, and kind.
+    int elementId =
+        _findFirstOccurrence(index.elementNameUnitMemberIds, unitMemberId);
+    if (elementId == -1) {
+      return -1;
+    }
+    for (;
+        elementId < index.elementNameUnitMemberIds.length &&
+            index.elementNameUnitMemberIds[elementId] == unitMemberId;
+        elementId++) {
+      if (index.elementUnits[elementId] == unitId &&
+          index.elementNameClassMemberIds[elementId] == classMemberId &&
+          index.elementNameParameterIds[elementId] == parameterId &&
+          index.elementKinds[elementId] == info.kind) {
+        return elementId;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Return the [element]'s class member name identifier, `null` is not a class
+   * member, or `-1` if the [element] is not referenced in the [index].
+   */
+  int getElementClassMemberId(Element element) {
+    for (; element != null; element = element.enclosingElement) {
+      if (element.enclosingElement is ClassElement) {
+        return getStringId(element.name);
+      }
+    }
+    return index.nullStringId;
+  }
+
+  /**
+   * Return the [element]'s class member name identifier, `null` is not a class
+   * member, or `-1` if the [element] is not referenced in the [index].
+   */
+  int getElementParameterId(Element element) {
+    for (; element != null; element = element.enclosingElement) {
+      if (element is ParameterElement) {
+        return getStringId(element.name);
+      }
+    }
+    return index.nullStringId;
+  }
+
+  /**
+   * Return the [element]'s top-level name identifier, `0` is the unit, or
+   * `-1` if the [element] is not referenced in the [index].
+   */
+  int getElementUnitMemberId(Element element) {
+    for (; element != null; element = element.enclosingElement) {
+      if (element.enclosingElement is CompilationUnitElement) {
+        return getStringId(element.name);
+      }
+    }
+    return index.nullStringId;
+  }
+
+  /**
+   * Return a list of results where an element with the given [elementId] has
+   * relation of the given [indexKind].
+   */
+  List<SearchResult> getRelations(
+      int elementId,
+      IndexRelationKind indexKind,
+      SearchResultKind searchKind,
+      CompilationUnitElement enclosingUnitElement) {
+    // Find the first usage of the element.
+    int i = _findFirstOccurrence(index.usedElements, elementId);
+    if (i == -1) {
+      return const <SearchResult>[];
+    }
+    // Create locations for every usage of the element.
+    List<SearchResult> results = <SearchResult>[];
+    for (;
+        i < index.usedElements.length && index.usedElements[i] == elementId;
+        i++) {
+      if (index.usedElementKinds[i] == indexKind) {
+        int offset = index.usedElementOffsets[i];
+        Element enclosingElement =
+            _getEnclosingElement(enclosingUnitElement, offset);
+        results.add(new SearchResult._(
+            null,
+            enclosingElement,
+            searchKind,
+            offset,
+            index.usedElementLengths[i],
+            true,
+            index.usedElementIsQualifiedFlags[i]));
+      }
+    }
+    return results;
+  }
+
+  /**
+   * Return the identifier of [str] in the [index] or `-1` if [str] is not
+   * used in the [index].
+   */
+  int getStringId(String str) {
+    return binarySearch(index.strings, str);
+  }
+
+  /**
+   * Return the identifier of the [CompilationUnitElement] containing the
+   * [element] in the [index] or `-1` if not found.
+   */
+  int getUnitId(Element element) {
+    CompilationUnitElement unitElement = getUnitElement(element);
+    int libraryUriId = getUriId(unitElement.library.source.uri);
+    if (libraryUriId == -1) {
+      return -1;
+    }
+    int unitUriId = getUriId(unitElement.source.uri);
+    if (unitUriId == -1) {
+      return -1;
+    }
+    for (int i = 0; i < index.unitLibraryUris.length; i++) {
+      if (index.unitLibraryUris[i] == libraryUriId &&
+          index.unitUnitUris[i] == unitUriId) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Return the identifier of the [uri] in the [index] or `-1` if the [uri] is
+   * not used in the [index].
+   */
+  int getUriId(Uri uri) {
+    String str = uri.toString();
+    return getStringId(str);
+  }
+
+  /**
+   * Return the index of the first occurrence of the [value] in the [sortedList],
+   * or `-1` if the [value] is not in the list.
+   */
+  int _findFirstOccurrence(List<int> sortedList, int value) {
+    // Find an occurrence.
+    int i = binarySearch(sortedList, value);
+    if (i == -1) {
+      return -1;
+    }
+    // Find the first occurrence.
+    while (i > 0 && sortedList[i - 1] == value) {
+      i--;
+    }
+    return i;
+  }
+}
+
 /**
  * Visitor that adds [SearchResult]s for local elements of a block, method,
  * class or a library - labels, local functions, local variables and parameters,
  * type parameters, import prefixes.
  */
 class _LocalReferencesVisitor extends RecursiveAstVisitor {
-  final List<SearchResult> matches = <SearchResult>[];
+  final List<SearchResult> results = <SearchResult>[];
 
   final Element element;
   final CompilationUnitElement enclosingUnitElement;
@@ -193,15 +509,15 @@
           kind = SearchResultKind.WRITE;
         }
       }
-      _addMatch(node, kind);
+      _addResult(node, kind);
     }
   }
 
-  void _addMatch(AstNode node, SearchResultKind kind) {
+  void _addResult(AstNode node, SearchResultKind kind) {
     bool isQualified = node.parent is Label;
-    var finder = new _ContainingElementFinder(node.offset);
-    enclosingUnitElement.accept(finder);
-    matches.add(new SearchResult._(element, finder.containingElement, kind,
-        node.offset, node.length, true, isQualified));
+    Element enclosingElement =
+        _getEnclosingElement(enclosingUnitElement, node.offset);
+    results.add(new SearchResult._(element, enclosingElement, kind, node.offset,
+        node.length, true, isQualified));
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 4d388d2..3238aed 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -8174,7 +8174,13 @@
   Token ofKeyword;
 
   /**
-   * The name of the library that the containing compilation unit is part of.
+   * The URI of the library that the containing compilation unit is part of.
+   */
+  StringLiteralImpl _uri;
+
+  /**
+   * The name of the library that the containing compilation unit is part of, or
+   * `null` if no name was given (typically because a library URI was provided).
    */
   LibraryIdentifier _libraryName;
 
@@ -8194,9 +8200,11 @@
       List<Annotation> metadata,
       this.partKeyword,
       this.ofKeyword,
+      StringLiteralImpl uri,
       LibraryIdentifierImpl libraryName,
       this.semicolon)
       : super(comment, metadata) {
+    _uri = _becomeParentOf(uri);
     _libraryName = _becomeParentOf(libraryName);
   }
 
@@ -8225,6 +8233,14 @@
   }
 
   @override
+  StringLiteral get uri => _uri;
+
+  @override
+  void set uri(StringLiteral uri) {
+    _uri = _becomeParentOf(uri as AstNodeImpl);
+  }
+
+  @override
   dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) =>
       visitor.visitPartOfDirective(this);
 
@@ -8232,6 +8248,7 @@
   void visitChildren(AstVisitor visitor) {
     super.visitChildren(visitor);
     _libraryName?.accept(visitor);
+    _uri?.accept(visitor);
   }
 }
 
@@ -10668,7 +10685,6 @@
     _uri = _becomeParentOf(uri as AstNodeImpl);
   }
 
-  @override
   UriValidationCode validate() {
     return validateUri(this is ImportDirective, uri, uriContent);
   }
@@ -10710,15 +10726,15 @@
 /**
  * Validation codes returned by [UriBasedDirective.validate].
  */
-class UriValidationCodeImpl implements UriValidationCode {
+class UriValidationCode {
   static const UriValidationCode INVALID_URI =
-      const UriValidationCodeImpl('INVALID_URI');
+      const UriValidationCode('INVALID_URI');
 
   static const UriValidationCode URI_WITH_INTERPOLATION =
-      const UriValidationCodeImpl('URI_WITH_INTERPOLATION');
+      const UriValidationCode('URI_WITH_INTERPOLATION');
 
   static const UriValidationCode URI_WITH_DART_EXT_SCHEME =
-      const UriValidationCodeImpl('URI_WITH_DART_EXT_SCHEME');
+      const UriValidationCode('URI_WITH_DART_EXT_SCHEME');
 
   /**
    * The name of the validation code.
@@ -10728,7 +10744,7 @@
   /**
    * Initialize a newly created validation code to have the given [name].
    */
-  const UriValidationCodeImpl(this.name);
+  const UriValidationCode(this.name);
 
   @override
   String toString() => name;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
new file mode 100644
index 0000000..72079b6
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -0,0 +1,897 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:front_end/src/scanner/token.dart';
+
+/**
+ * Concrete implementation of [AstFactory] based on the standard AST
+ * implementation.
+ */
+class AstFactoryImpl extends AstFactory {
+  @override
+  AdjacentStrings adjacentStrings(List<StringLiteral> strings) =>
+      new AdjacentStringsImpl(strings);
+
+  @override
+  Annotation annotation(Token atSign, Identifier name, Token period,
+          SimpleIdentifier constructorName, ArgumentList arguments) =>
+      new AnnotationImpl(atSign, name, period, constructorName, arguments);
+
+  @override
+  ArgumentList argumentList(Token leftParenthesis, List<Expression> arguments,
+          Token rightParenthesis) =>
+      new ArgumentListImpl(leftParenthesis, arguments, rightParenthesis);
+
+  @override
+  AsExpression asExpression(
+          Expression expression, Token asOperator, TypeName type) =>
+      new AsExpressionImpl(expression, asOperator, type);
+
+  @override
+  AssertInitializer assertInitializer(
+          Token assertKeyword,
+          Token leftParenthesis,
+          Expression condition,
+          Token comma,
+          Expression message,
+          Token rightParenthesis) =>
+      new AssertInitializerImpl(assertKeyword, leftParenthesis, condition,
+          comma, message, rightParenthesis);
+
+  @override
+  AssertStatement assertStatement(
+          Token assertKeyword,
+          Token leftParenthesis,
+          Expression condition,
+          Token comma,
+          Expression message,
+          Token rightParenthesis,
+          Token semicolon) =>
+      new AssertStatementImpl(assertKeyword, leftParenthesis, condition, comma,
+          message, rightParenthesis, semicolon);
+
+  @override
+  AssignmentExpression assignmentExpression(
+          Expression leftHandSide, Token operator, Expression rightHandSide) =>
+      new AssignmentExpressionImpl(leftHandSide, operator, rightHandSide);
+
+  @override
+  AwaitExpression awaitExpression(Token awaitKeyword, Expression expression) =>
+      new AwaitExpressionImpl(awaitKeyword, expression);
+
+  @override
+  BinaryExpression binaryExpression(
+          Expression leftOperand, Token operator, Expression rightOperand) =>
+      new BinaryExpressionImpl(leftOperand, operator, rightOperand);
+  @override
+  Block block(
+          Token leftBracket, List<Statement> statements, Token rightBracket) =>
+      new BlockImpl(leftBracket, statements, rightBracket);
+
+  @override
+  Comment blockComment(List<Token> tokens) =>
+      CommentImpl.createBlockComment(tokens);
+
+  @override
+  BlockFunctionBody blockFunctionBody(Token keyword, Token star, Block block) =>
+      new BlockFunctionBodyImpl(keyword, star, block);
+
+  @override
+  BooleanLiteral booleanLiteral(Token literal, bool value) =>
+      new BooleanLiteralImpl(literal, value);
+
+  @override
+  BreakStatement breakStatement(
+          Token breakKeyword, SimpleIdentifier label, Token semicolon) =>
+      new BreakStatementImpl(breakKeyword, label, semicolon);
+
+  @override
+  CascadeExpression cascadeExpression(
+          Expression target, List<Expression> cascadeSections) =>
+      new CascadeExpressionImpl(target, cascadeSections);
+
+  @override
+  CatchClause catchClause(
+          Token onKeyword,
+          TypeName exceptionType,
+          Token catchKeyword,
+          Token leftParenthesis,
+          SimpleIdentifier exceptionParameter,
+          Token comma,
+          SimpleIdentifier stackTraceParameter,
+          Token rightParenthesis,
+          Block body) =>
+      new CatchClauseImpl(
+          onKeyword,
+          exceptionType,
+          catchKeyword,
+          leftParenthesis,
+          exceptionParameter,
+          comma,
+          stackTraceParameter,
+          rightParenthesis,
+          body);
+
+  @override
+  ClassDeclaration classDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          Token abstractKeyword,
+          Token classKeyword,
+          SimpleIdentifier name,
+          TypeParameterList typeParameters,
+          ExtendsClause extendsClause,
+          WithClause withClause,
+          ImplementsClause implementsClause,
+          Token leftBracket,
+          List<ClassMember> members,
+          Token rightBracket) =>
+      new ClassDeclarationImpl(
+          comment,
+          metadata,
+          abstractKeyword,
+          classKeyword,
+          name,
+          typeParameters,
+          extendsClause,
+          withClause,
+          implementsClause,
+          leftBracket,
+          members,
+          rightBracket);
+
+  @override
+  ClassTypeAlias classTypeAlias(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          SimpleIdentifier name,
+          TypeParameterList typeParameters,
+          Token equals,
+          Token abstractKeyword,
+          TypeName superclass,
+          WithClause withClause,
+          ImplementsClause implementsClause,
+          Token semicolon) =>
+      new ClassTypeAliasImpl(
+          comment,
+          metadata,
+          keyword,
+          name,
+          typeParameters,
+          equals,
+          abstractKeyword,
+          superclass,
+          withClause,
+          implementsClause,
+          semicolon);
+
+  @override
+  CommentReference commentReference(Token newKeyword, Identifier identifier) =>
+      new CommentReferenceImpl(newKeyword, identifier);
+
+  @override
+  CompilationUnit compilationUnit(
+          Token beginToken,
+          ScriptTag scriptTag,
+          List<Directive> directives,
+          List<CompilationUnitMember> declarations,
+          Token endToken) =>
+      new CompilationUnitImpl(
+          beginToken, scriptTag, directives, declarations, endToken);
+
+  @override
+  ConditionalExpression conditionalExpression(
+          Expression condition,
+          Token question,
+          Expression thenExpression,
+          Token colon,
+          Expression elseExpression) =>
+      new ConditionalExpressionImpl(
+          condition, question, thenExpression, colon, elseExpression);
+
+  @override
+  Configuration configuration(
+          Token ifKeyword,
+          Token leftParenthesis,
+          DottedName name,
+          Token equalToken,
+          StringLiteral value,
+          Token rightParenthesis,
+          StringLiteral libraryUri) =>
+      new ConfigurationImpl(ifKeyword, leftParenthesis, name, equalToken, value,
+          rightParenthesis, libraryUri);
+
+  @override
+  ConstructorDeclaration constructorDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          Token externalKeyword,
+          Token constKeyword,
+          Token factoryKeyword,
+          Identifier returnType,
+          Token period,
+          SimpleIdentifier name,
+          FormalParameterList parameters,
+          Token separator,
+          List<ConstructorInitializer> initializers,
+          ConstructorName redirectedConstructor,
+          FunctionBody body) =>
+      new ConstructorDeclarationImpl(
+          comment,
+          metadata,
+          externalKeyword,
+          constKeyword,
+          factoryKeyword,
+          returnType,
+          period,
+          name,
+          parameters,
+          separator,
+          initializers,
+          redirectedConstructor,
+          body);
+
+  @override
+  ConstructorFieldInitializer constructorFieldInitializer(
+          Token thisKeyword,
+          Token period,
+          SimpleIdentifier fieldName,
+          Token equals,
+          Expression expression) =>
+      new ConstructorFieldInitializerImpl(
+          thisKeyword, period, fieldName, equals, expression);
+
+  @override
+  ConstructorName constructorName(
+          TypeName type, Token period, SimpleIdentifier name) =>
+      new ConstructorNameImpl(type, period, name);
+
+  @override
+  ContinueStatement continueStatement(
+          Token continueKeyword, SimpleIdentifier label, Token semicolon) =>
+      new ContinueStatementImpl(continueKeyword, label, semicolon);
+
+  @override
+  DeclaredIdentifier declaredIdentifier(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          TypeName type,
+          SimpleIdentifier identifier) =>
+      new DeclaredIdentifierImpl(comment, metadata, keyword, type, identifier);
+
+  @override
+  DefaultFormalParameter defaultFormalParameter(NormalFormalParameter parameter,
+          ParameterKind kind, Token separator, Expression defaultValue) =>
+      new DefaultFormalParameterImpl(parameter, kind, separator, defaultValue);
+
+  @override
+  Comment documentationComment(List<Token> tokens,
+          [List<CommentReference> references]) =>
+      CommentImpl.createDocumentationCommentWithReferences(
+          tokens, references ?? <CommentReference>[]);
+
+  @override
+  DoStatement doStatement(
+          Token doKeyword,
+          Statement body,
+          Token whileKeyword,
+          Token leftParenthesis,
+          Expression condition,
+          Token rightParenthesis,
+          Token semicolon) =>
+      new DoStatementImpl(doKeyword, body, whileKeyword, leftParenthesis,
+          condition, rightParenthesis, semicolon);
+
+  @override
+  DottedName dottedName(List<SimpleIdentifier> components) =>
+      new DottedNameImpl(components);
+
+  @override
+  DoubleLiteral doubleLiteral(Token literal, double value) =>
+      new DoubleLiteralImpl(literal, value);
+
+  @override
+  EmptyFunctionBody emptyFunctionBody(Token semicolon) =>
+      new EmptyFunctionBodyImpl(semicolon);
+
+  @override
+  EmptyStatement emptyStatement(Token semicolon) =>
+      new EmptyStatementImpl(semicolon);
+
+  @override
+  Comment endOfLineComment(List<Token> tokens) =>
+      CommentImpl.createEndOfLineComment(tokens);
+
+  @override
+  EnumConstantDeclaration enumConstantDeclaration(
+          Comment comment, List<Annotation> metadata, SimpleIdentifier name) =>
+      new EnumConstantDeclarationImpl(comment, metadata, name);
+
+  @override
+  EnumDeclaration enumDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          Token enumKeyword,
+          SimpleIdentifier name,
+          Token leftBracket,
+          List<EnumConstantDeclaration> constants,
+          Token rightBracket) =>
+      new EnumDeclarationImpl(comment, metadata, enumKeyword, name, leftBracket,
+          constants, rightBracket);
+
+  @override
+  ExportDirective exportDirective(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          StringLiteral libraryUri,
+          List<Configuration> configurations,
+          List<Combinator> combinators,
+          Token semicolon) =>
+      new ExportDirectiveImpl(comment, metadata, keyword, libraryUri,
+          configurations, combinators, semicolon);
+  @override
+  ExpressionFunctionBody expressionFunctionBody(Token keyword,
+          Token functionDefinition, Expression expression, Token semicolon) =>
+      new ExpressionFunctionBodyImpl(
+          keyword, functionDefinition, expression, semicolon);
+
+  @override
+  ExpressionStatement expressionStatement(
+          Expression expression, Token semicolon) =>
+      new ExpressionStatementImpl(expression, semicolon);
+
+  @override
+  ExtendsClause extendsClause(Token extendsKeyword, TypeName superclass) =>
+      new ExtendsClauseImpl(extendsKeyword, superclass);
+
+  @override
+  FieldDeclaration fieldDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          Token staticKeyword,
+          VariableDeclarationList fieldList,
+          Token semicolon) =>
+      new FieldDeclarationImpl(
+          comment, metadata, staticKeyword, fieldList, semicolon);
+
+  @override
+  FieldFormalParameter fieldFormalParameter(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          TypeName type,
+          Token thisKeyword,
+          Token period,
+          SimpleIdentifier identifier,
+          TypeParameterList typeParameters,
+          FormalParameterList parameters) =>
+      new FieldFormalParameterImpl(comment, metadata, keyword, type,
+          thisKeyword, period, identifier, typeParameters, parameters);
+
+  @override
+  ForEachStatement forEachStatementWithDeclaration(
+          Token awaitKeyword,
+          Token forKeyword,
+          Token leftParenthesis,
+          DeclaredIdentifier loopVariable,
+          Token inKeyword,
+          Expression iterator,
+          Token rightParenthesis,
+          Statement body) =>
+      new ForEachStatementImpl.withDeclaration(
+          awaitKeyword,
+          forKeyword,
+          leftParenthesis,
+          loopVariable,
+          inKeyword,
+          iterator,
+          rightParenthesis,
+          body);
+
+  @override
+  ForEachStatement forEachStatementWithReference(
+          Token awaitKeyword,
+          Token forKeyword,
+          Token leftParenthesis,
+          SimpleIdentifier identifier,
+          Token inKeyword,
+          Expression iterator,
+          Token rightParenthesis,
+          Statement body) =>
+      new ForEachStatementImpl.withReference(
+          awaitKeyword,
+          forKeyword,
+          leftParenthesis,
+          identifier,
+          inKeyword,
+          iterator,
+          rightParenthesis,
+          body);
+
+  @override
+  FormalParameterList formalParameterList(
+          Token leftParenthesis,
+          List<FormalParameter> parameters,
+          Token leftDelimiter,
+          Token rightDelimiter,
+          Token rightParenthesis) =>
+      new FormalParameterListImpl(leftParenthesis, parameters, leftDelimiter,
+          rightDelimiter, rightParenthesis);
+
+  @override
+  ForStatement forStatement(
+          Token forKeyword,
+          Token leftParenthesis,
+          VariableDeclarationList variableList,
+          Expression initialization,
+          Token leftSeparator,
+          Expression condition,
+          Token rightSeparator,
+          List<Expression> updaters,
+          Token rightParenthesis,
+          Statement body) =>
+      new ForStatementImpl(
+          forKeyword,
+          leftParenthesis,
+          variableList,
+          initialization,
+          leftSeparator,
+          condition,
+          rightSeparator,
+          updaters,
+          rightParenthesis,
+          body);
+
+  @override
+  FunctionDeclaration functionDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          Token externalKeyword,
+          TypeName returnType,
+          Token propertyKeyword,
+          SimpleIdentifier name,
+          FunctionExpression functionExpression) =>
+      new FunctionDeclarationImpl(comment, metadata, externalKeyword,
+          returnType, propertyKeyword, name, functionExpression);
+
+  @override
+  FunctionDeclarationStatement functionDeclarationStatement(
+          FunctionDeclaration functionDeclaration) =>
+      new FunctionDeclarationStatementImpl(functionDeclaration);
+
+  @override
+  FunctionExpression functionExpression(TypeParameterList typeParameters,
+          FormalParameterList parameters, FunctionBody body) =>
+      new FunctionExpressionImpl(typeParameters, parameters, body);
+
+  @override
+  FunctionExpressionInvocation functionExpressionInvocation(Expression function,
+          TypeArgumentList typeArguments, ArgumentList argumentList) =>
+      new FunctionExpressionInvocationImpl(
+          function, typeArguments, argumentList);
+
+  @override
+  FunctionTypeAlias functionTypeAlias(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          TypeName returnType,
+          SimpleIdentifier name,
+          TypeParameterList typeParameters,
+          FormalParameterList parameters,
+          Token semicolon) =>
+      new FunctionTypeAliasImpl(comment, metadata, keyword, returnType, name,
+          typeParameters, parameters, semicolon);
+
+  @override
+  FunctionTypedFormalParameter functionTypedFormalParameter(
+          Comment comment,
+          List<Annotation> metadata,
+          TypeName returnType,
+          SimpleIdentifier identifier,
+          TypeParameterList typeParameters,
+          FormalParameterList parameters,
+          {Token question: null}) =>
+      new FunctionTypedFormalParameterImpl(comment, metadata, returnType,
+          identifier, typeParameters, parameters, question);
+
+  @override
+  HideCombinator hideCombinator(
+          Token keyword, List<SimpleIdentifier> hiddenNames) =>
+      new HideCombinatorImpl(keyword, hiddenNames);
+
+  @override
+  IfStatement ifStatement(
+          Token ifKeyword,
+          Token leftParenthesis,
+          Expression condition,
+          Token rightParenthesis,
+          Statement thenStatement,
+          Token elseKeyword,
+          Statement elseStatement) =>
+      new IfStatementImpl(ifKeyword, leftParenthesis, condition,
+          rightParenthesis, thenStatement, elseKeyword, elseStatement);
+
+  @override
+  ImplementsClause implementsClause(
+          Token implementsKeyword, List<TypeName> interfaces) =>
+      new ImplementsClauseImpl(implementsKeyword, interfaces);
+
+  @override
+  ImportDirective importDirective(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          StringLiteral libraryUri,
+          List<Configuration> configurations,
+          Token deferredKeyword,
+          Token asKeyword,
+          SimpleIdentifier prefix,
+          List<Combinator> combinators,
+          Token semicolon) =>
+      new ImportDirectiveImpl(
+          comment,
+          metadata,
+          keyword,
+          libraryUri,
+          configurations,
+          deferredKeyword,
+          asKeyword,
+          prefix,
+          combinators,
+          semicolon);
+
+  @override
+  IndexExpression indexExpressionForCascade(Token period, Token leftBracket,
+          Expression index, Token rightBracket) =>
+      new IndexExpressionImpl.forCascade(
+          period, leftBracket, index, rightBracket);
+
+  @override
+  IndexExpression indexExpressionForTarget(Expression target, Token leftBracket,
+          Expression index, Token rightBracket) =>
+      new IndexExpressionImpl.forTarget(
+          target, leftBracket, index, rightBracket);
+
+  @override
+  InstanceCreationExpression instanceCreationExpression(Token keyword,
+          ConstructorName constructorName, ArgumentList argumentList) =>
+      new InstanceCreationExpressionImpl(
+          keyword, constructorName, argumentList);
+
+  @override
+  IntegerLiteral integerLiteral(Token literal, int value) =>
+      new IntegerLiteralImpl(literal, value);
+
+  @override
+  InterpolationExpression interpolationExpression(
+          Token leftBracket, Expression expression, Token rightBracket) =>
+      new InterpolationExpressionImpl(leftBracket, expression, rightBracket);
+
+  @override
+  InterpolationString interpolationString(Token contents, String value) =>
+      new InterpolationStringImpl(contents, value);
+
+  @override
+  IsExpression isExpression(Expression expression, Token isOperator,
+          Token notOperator, TypeName type) =>
+      new IsExpressionImpl(expression, isOperator, notOperator, type);
+
+  @override
+  Label label(SimpleIdentifier label, Token colon) =>
+      new LabelImpl(label, colon);
+
+  @override
+  LabeledStatement labeledStatement(List<Label> labels, Statement statement) =>
+      new LabeledStatementImpl(labels, statement);
+
+  @override
+  LibraryDirective libraryDirective(Comment comment, List<Annotation> metadata,
+          Token libraryKeyword, LibraryIdentifier name, Token semicolon) =>
+      new LibraryDirectiveImpl(
+          comment, metadata, libraryKeyword, name, semicolon);
+
+  @override
+  LibraryIdentifier libraryIdentifier(List<SimpleIdentifier> components) =>
+      new LibraryIdentifierImpl(components);
+
+  @override
+  ListLiteral listLiteral(Token constKeyword, TypeArgumentList typeArguments,
+          Token leftBracket, List<Expression> elements, Token rightBracket) =>
+      new ListLiteralImpl(
+          constKeyword, typeArguments, leftBracket, elements, rightBracket);
+
+  @override
+  MapLiteral mapLiteral(
+          Token constKeyword,
+          TypeArgumentList typeArguments,
+          Token leftBracket,
+          List<MapLiteralEntry> entries,
+          Token rightBracket) =>
+      new MapLiteralImpl(
+          constKeyword, typeArguments, leftBracket, entries, rightBracket);
+
+  @override
+  MapLiteralEntry mapLiteralEntry(
+          Expression key, Token separator, Expression value) =>
+      new MapLiteralEntryImpl(key, separator, value);
+
+  @override
+  MethodDeclaration methodDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          Token externalKeyword,
+          Token modifierKeyword,
+          TypeName returnType,
+          Token propertyKeyword,
+          Token operatorKeyword,
+          SimpleIdentifier name,
+          TypeParameterList typeParameters,
+          FormalParameterList parameters,
+          FunctionBody body) =>
+      new MethodDeclarationImpl(
+          comment,
+          metadata,
+          externalKeyword,
+          modifierKeyword,
+          returnType,
+          propertyKeyword,
+          operatorKeyword,
+          name,
+          typeParameters,
+          parameters,
+          body);
+
+  @override
+  MethodInvocation methodInvocation(
+          Expression target,
+          Token operator,
+          SimpleIdentifier methodName,
+          TypeArgumentList typeArguments,
+          ArgumentList argumentList) =>
+      new MethodInvocationImpl(
+          target, operator, methodName, typeArguments, argumentList);
+
+  @override
+  NamedExpression namedExpression(Label name, Expression expression) =>
+      new NamedExpressionImpl(name, expression);
+
+  @override
+  NativeClause nativeClause(Token nativeKeyword, StringLiteral name) =>
+      new NativeClauseImpl(nativeKeyword, name);
+
+  @override
+  NativeFunctionBody nativeFunctionBody(
+          Token nativeKeyword, StringLiteral stringLiteral, Token semicolon) =>
+      new NativeFunctionBodyImpl(nativeKeyword, stringLiteral, semicolon);
+
+  @override
+  NodeList/*<E>*/ nodeList/*<E extends AstNode>*/(AstNode owner,
+          [List/*<E>*/ elements]) =>
+      new NodeListImpl/*<E>*/(owner as AstNodeImpl, elements);
+
+  @override
+  NullLiteral nullLiteral(Token literal) => new NullLiteralImpl(literal);
+
+  @override
+  ParenthesizedExpression parenthesizedExpression(Token leftParenthesis,
+          Expression expression, Token rightParenthesis) =>
+      new ParenthesizedExpressionImpl(
+          leftParenthesis, expression, rightParenthesis);
+
+  @override
+  PartDirective partDirective(Comment comment, List<Annotation> metadata,
+          Token partKeyword, StringLiteral partUri, Token semicolon) =>
+      new PartDirectiveImpl(comment, metadata, partKeyword, partUri, semicolon);
+
+  @override
+  PartOfDirective partOfDirective(
+          Comment comment,
+          List<Annotation> metadata,
+          Token partKeyword,
+          Token ofKeyword,
+          StringLiteral uri,
+          LibraryIdentifier libraryName,
+          Token semicolon) =>
+      new PartOfDirectiveImpl(comment, metadata, partKeyword, ofKeyword, uri,
+          libraryName, semicolon);
+
+  @override
+  PostfixExpression postfixExpression(Expression operand, Token operator) =>
+      new PostfixExpressionImpl(operand, operator);
+
+  @override
+  PrefixedIdentifier prefixedIdentifier(
+          SimpleIdentifier prefix, Token period, SimpleIdentifier identifier) =>
+      new PrefixedIdentifierImpl(prefix, period, identifier);
+
+  @override
+  PrefixExpression prefixExpression(Token operator, Expression operand) =>
+      new PrefixExpressionImpl(operator, operand);
+
+  @override
+  PropertyAccess propertyAccess(
+          Expression target, Token operator, SimpleIdentifier propertyName) =>
+      new PropertyAccessImpl(target, operator, propertyName);
+
+  @override
+  RedirectingConstructorInvocation redirectingConstructorInvocation(
+          Token thisKeyword,
+          Token period,
+          SimpleIdentifier constructorName,
+          ArgumentList argumentList) =>
+      new RedirectingConstructorInvocationImpl(
+          thisKeyword, period, constructorName, argumentList);
+
+  @override
+  RethrowExpression rethrowExpression(Token rethrowKeyword) =>
+      new RethrowExpressionImpl(rethrowKeyword);
+
+  @override
+  ReturnStatement returnStatement(
+          Token returnKeyword, Expression expression, Token semicolon) =>
+      new ReturnStatementImpl(returnKeyword, expression, semicolon);
+
+  @override
+  ScriptTag scriptTag(Token scriptTag) => new ScriptTagImpl(scriptTag);
+
+  @override
+  ShowCombinator showCombinator(
+          Token keyword, List<SimpleIdentifier> shownNames) =>
+      new ShowCombinatorImpl(keyword, shownNames);
+
+  @override
+  SimpleFormalParameter simpleFormalParameter(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          TypeName type,
+          SimpleIdentifier identifier) =>
+      new SimpleFormalParameterImpl(
+          comment, metadata, keyword, type, identifier);
+
+  @override
+  SimpleIdentifier simpleIdentifier(Token token, {bool isDeclaration: false}) {
+    if (isDeclaration) {
+      return new DeclaredSimpleIdentifier(token);
+    }
+    return new SimpleIdentifierImpl(token);
+  }
+
+  @override
+  SimpleStringLiteral simpleStringLiteral(Token literal, String value) =>
+      new SimpleStringLiteralImpl(literal, value);
+
+  @override
+  StringInterpolation stringInterpolation(
+          List<InterpolationElement> elements) =>
+      new StringInterpolationImpl(elements);
+
+  @override
+  SuperConstructorInvocation superConstructorInvocation(
+          Token superKeyword,
+          Token period,
+          SimpleIdentifier constructorName,
+          ArgumentList argumentList) =>
+      new SuperConstructorInvocationImpl(
+          superKeyword, period, constructorName, argumentList);
+
+  @override
+  SuperExpression superExpression(Token superKeyword) =>
+      new SuperExpressionImpl(superKeyword);
+
+  @override
+  SwitchCase switchCase(List<Label> labels, Token keyword,
+          Expression expression, Token colon, List<Statement> statements) =>
+      new SwitchCaseImpl(labels, keyword, expression, colon, statements);
+
+  @override
+  SwitchDefault switchDefault(List<Label> labels, Token keyword, Token colon,
+          List<Statement> statements) =>
+      new SwitchDefaultImpl(labels, keyword, colon, statements);
+  @override
+  SwitchStatement switchStatement(
+          Token switchKeyword,
+          Token leftParenthesis,
+          Expression expression,
+          Token rightParenthesis,
+          Token leftBracket,
+          List<SwitchMember> members,
+          Token rightBracket) =>
+      new SwitchStatementImpl(switchKeyword, leftParenthesis, expression,
+          rightParenthesis, leftBracket, members, rightBracket);
+
+  @override
+  SymbolLiteral symbolLiteral(Token poundSign, List<Token> components) =>
+      new SymbolLiteralImpl(poundSign, components);
+
+  @override
+  ThisExpression thisExpression(Token thisKeyword) =>
+      new ThisExpressionImpl(thisKeyword);
+
+  @override
+  ThrowExpression throwExpression(Token throwKeyword, Expression expression) =>
+      new ThrowExpressionImpl(throwKeyword, expression);
+
+  @override
+  TopLevelVariableDeclaration topLevelVariableDeclaration(
+          Comment comment,
+          List<Annotation> metadata,
+          VariableDeclarationList variableList,
+          Token semicolon) =>
+      new TopLevelVariableDeclarationImpl(
+          comment, metadata, variableList, semicolon);
+
+  @override
+  TryStatement tryStatement(
+          Token tryKeyword,
+          Block body,
+          List<CatchClause> catchClauses,
+          Token finallyKeyword,
+          Block finallyBlock) =>
+      new TryStatementImpl(
+          tryKeyword, body, catchClauses, finallyKeyword, finallyBlock);
+
+  @override
+  TypeArgumentList typeArgumentList(
+          Token leftBracket, List<TypeName> arguments, Token rightBracket) =>
+      new TypeArgumentListImpl(leftBracket, arguments, rightBracket);
+
+  @override
+  TypeName typeName(Identifier name, TypeArgumentList typeArguments,
+          {Token question: null}) =>
+      new TypeNameImpl(name, typeArguments, question);
+
+  @override
+  TypeParameter typeParameter(Comment comment, List<Annotation> metadata,
+          SimpleIdentifier name, Token extendsKeyword, TypeName bound) =>
+      new TypeParameterImpl(comment, metadata, name, extendsKeyword, bound);
+
+  @override
+  TypeParameterList typeParameterList(Token leftBracket,
+          List<TypeParameter> typeParameters, Token rightBracket) =>
+      new TypeParameterListImpl(leftBracket, typeParameters, rightBracket);
+
+  @override
+  VariableDeclaration variableDeclaration(
+          SimpleIdentifier name, Token equals, Expression initializer) =>
+      new VariableDeclarationImpl(name, equals, initializer);
+
+  @override
+  VariableDeclarationList variableDeclarationList(
+          Comment comment,
+          List<Annotation> metadata,
+          Token keyword,
+          TypeName type,
+          List<VariableDeclaration> variables) =>
+      new VariableDeclarationListImpl(
+          comment, metadata, keyword, type, variables);
+
+  @override
+  VariableDeclarationStatement variableDeclarationStatement(
+          VariableDeclarationList variableList, Token semicolon) =>
+      new VariableDeclarationStatementImpl(variableList, semicolon);
+
+  @override
+  WhileStatement whileStatement(Token whileKeyword, Token leftParenthesis,
+          Expression condition, Token rightParenthesis, Statement body) =>
+      new WhileStatementImpl(
+          whileKeyword, leftParenthesis, condition, rightParenthesis, body);
+
+  @override
+  WithClause withClause(Token withKeyword, List<TypeName> mixinTypes) =>
+      new WithClauseImpl(withKeyword, mixinTypes);
+
+  @override
+  YieldStatement yieldStatement(Token yieldKeyword, Token star,
+          Expression expression, Token semicolon) =>
+      new YieldStatementImpl(yieldKeyword, star, expression, semicolon);
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 8e45f3c..7dd0e48 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -740,6 +740,7 @@
           cloneNodeList(node.metadata),
           cloneToken(node.partKeyword),
           cloneToken(node.ofKeyword),
+          cloneNode(node.uri),
           cloneNode(node.libraryName),
           cloneToken(node.semicolon));
 
@@ -3480,6 +3481,7 @@
         _cloneNodeList(node.metadata),
         _mapToken(node.partKeyword),
         _mapToken(node.ofKeyword),
+        _cloneNode(node.uri),
         _cloneNode(node.libraryName),
         _mapToken(node.semicolon));
     copy.element = node.element;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 3ec4819..22f961b 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -25,7 +25,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
@@ -1049,9 +1049,9 @@
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
-    safelyVisitChildren(_constructors, visitor);
+    safelyVisitChildren(constructors, visitor);
     safelyVisitChildren(methods, visitor);
-    safelyVisitChildren(_typeParameters, visitor);
+    safelyVisitChildren(typeParameters, visitor);
   }
 
   void _collectAllSupertypes(List<InterfaceType> supertypes) {
@@ -2217,7 +2217,7 @@
             .buildExpression(this, serialized.arguments[i]);
         int nameIndex = numNames + i - numArguments;
         if (nameIndex >= 0) {
-          expression = AstFactory.namedExpression2(
+          expression = AstTestFactory.namedExpression2(
               serialized.argumentNames[nameIndex], expression);
         }
         arguments.add(expression);
@@ -2226,7 +2226,7 @@
     switch (kind) {
       case UnlinkedConstructorInitializerKind.field:
         ConstructorFieldInitializer initializer =
-            AstFactory.constructorFieldInitializer(
+            AstTestFactory.constructorFieldInitializer(
                 false,
                 name,
                 enclosingUnit.resynthesizerContext
@@ -2235,7 +2235,7 @@
         return initializer;
       case UnlinkedConstructorInitializerKind.superInvocation:
         SuperConstructorInvocation initializer =
-            AstFactory.superConstructorInvocation2(
+            AstTestFactory.superConstructorInvocation2(
                 name.isNotEmpty ? name : null, arguments);
         ClassElement superElement = enclosingElement.supertype.element;
         ConstructorElement element = name.isEmpty
@@ -2246,7 +2246,7 @@
         return initializer;
       case UnlinkedConstructorInitializerKind.thisInvocation:
         RedirectingConstructorInvocation initializer =
-            AstFactory.redirectingConstructorInvocation2(
+            AstTestFactory.redirectingConstructorInvocation2(
                 name.isNotEmpty ? name : null, arguments);
         ConstructorElement element = name.isEmpty
             ? enclosingElement.unnamedConstructor
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 9576b15..0301ed0 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
 import 'package:analyzer/src/context/cache.dart';
@@ -26,6 +27,7 @@
 import 'package:analyzer/src/plugin/command_line_plugin.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/src/plugin/options_plugin.dart';
+import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/model.dart';
@@ -357,6 +359,7 @@
    *
    * See [setConfigurationData].
    */
+  @deprecated
   Object/*=V*/ getConfigurationData/*<V>*/(ResultDescriptor/*<V>*/ key);
 
   /**
@@ -624,6 +627,7 @@
    *
    * See [getConfigurationData].
    */
+  @deprecated
   void setConfigurationData(ResultDescriptor key, Object data);
 
   /**
@@ -1118,6 +1122,7 @@
   /**
    * Return `true` to enable generic methods (DEP 22).
    */
+  @deprecated
   bool get enableGenericMethods => null;
 
   /**
@@ -1150,6 +1155,23 @@
   bool get enableTiming;
 
   /**
+   * Return `true` to enable the use of URIs in part-of directives.
+   */
+  bool get enableUriInPartOf;
+
+  /**
+   * Return a list of error processors that are to be used when reporting
+   * errors in some analysis context.
+   */
+  List<ErrorProcessor> get errorProcessors;
+
+  /**
+   * Return a list of exclude patterns used to exclude some sources from
+   * analysis.
+   */
+  List<String> get excludePatterns;
+
+  /**
    * A flag indicating whether finer grained dependencies should be used
    * instead of just source level dependencies.
    *
@@ -1198,6 +1220,12 @@
   bool get lint;
 
   /**
+   * Return a list of the lint rules that are to be run in an analysis context
+   * if [lint] returns `true`.
+   */
+  List<Linter> get lintRules;
+
+  /**
    * Return the "platform" bit mask which should be used to apply patch files,
    * or `0` if no patch files should be applied.
    */
@@ -1261,7 +1289,8 @@
  */
 class AnalysisOptionsImpl implements AnalysisOptions {
   /**
-   * DEPRECATED: The maximum number of sources for which data should be kept in the cache.
+   * DEPRECATED: The maximum number of sources for which data should be kept in
+   * the cache.
    *
    * This constant no longer has any effect.
    */
@@ -1269,12 +1298,11 @@
   static const int DEFAULT_CACHE_SIZE = 64;
 
   static const int ENABLE_ASSERT_FLAG = 0x01;
-  static const int ENABLE_GENERIC_METHODS_FLAG = 0x02;
-  static const int ENABLE_LAZY_ASSIGNMENT_OPERATORS = 0x04;
-  static const int ENABLE_STRICT_CALL_CHECKS_FLAG = 0x08;
-  static const int ENABLE_STRONG_MODE_FLAG = 0x10;
-  static const int ENABLE_STRONG_MODE_HINTS_FLAG = 0x20;
-  static const int ENABLE_SUPER_MIXINS_FLAG = 0x40;
+  static const int ENABLE_LAZY_ASSIGNMENT_OPERATORS = 0x02;
+  static const int ENABLE_STRICT_CALL_CHECKS_FLAG = 0x04;
+  static const int ENABLE_STRONG_MODE_FLAG = 0x08;
+  static const int ENABLE_STRONG_MODE_HINTS_FLAG = 0x10;
+  static const int ENABLE_SUPER_MIXINS_FLAG = 0x20;
 
   /**
    * The default list of non-nullable type names.
@@ -1302,9 +1330,6 @@
   bool enableAssertMessage = false;
 
   @override
-  bool enableGenericMethods = false;
-
-  @override
   bool enableInitializingFormalAccess = false;
 
   @override
@@ -1319,6 +1344,20 @@
   @override
   bool enableTiming = false;
 
+  /**
+   * A list of error processors that are to be used when reporting errors in
+   * some analysis context.
+   */
+  List<ErrorProcessor> _errorProcessors;
+
+  /**
+   * A list of exclude patterns used to exclude some sources from analysis.
+   */
+  List<String> _excludePatterns;
+
+  @override
+  bool enableUriInPartOf = false;
+
   @override
   bool generateImplicitErrors = true;
 
@@ -1340,6 +1379,12 @@
   @override
   bool lint = false;
 
+  /**
+   * The lint rules that are to be run in an analysis context if [lint] returns
+   * `true`.
+   */
+  List<Linter> _lintRules;
+
   @override
   int patchPlatform = 0;
 
@@ -1408,11 +1453,12 @@
     enableAssertInitializer = options.enableAssertInitializer;
     enableAssertMessage = options.enableAssertMessage;
     enableStrictCallChecks = options.enableStrictCallChecks;
-    enableGenericMethods = options.enableGenericMethods;
     enableInitializingFormalAccess = options.enableInitializingFormalAccess;
     enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
     enableSuperMixins = options.enableSuperMixins;
     enableTiming = options.enableTiming;
+    errorProcessors = options.errorProcessors;
+    excludePatterns = options.excludePatterns;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
@@ -1420,6 +1466,7 @@
     incrementalApi = options.incrementalApi;
     incrementalValidation = options.incrementalValidation;
     lint = options.lint;
+    lintRules = options.lintRules;
     preserveComments = options.preserveComments;
     strongMode = options.strongMode;
     if (options is AnalysisOptionsImpl) {
@@ -1480,9 +1527,49 @@
   void set enableConditionalDirectives(_) {}
 
   @override
+  @deprecated
+  bool get enableGenericMethods => true;
+
+  @deprecated
+  void set enableGenericMethods(bool enable) {}
+
+  @override
+  List<ErrorProcessor> get errorProcessors =>
+      _errorProcessors ??= const <ErrorProcessor>[];
+
+  /**
+   * Set the list of error [processors] that are to be used when reporting
+   * errors in some analysis context.
+   */
+  void set errorProcessors(List<ErrorProcessor> processors) {
+    _errorProcessors = processors;
+  }
+
+  @override
+  List<String> get excludePatterns => _excludePatterns ??= const <String>[];
+
+  /**
+   * Set the exclude patterns used to exclude some sources from analysis to
+   * those in the given list of [patterns].
+   */
+  void set excludePatterns(List<String> patterns) {
+    _excludePatterns = patterns;
+  }
+
+  @override
+  List<Linter> get lintRules => _lintRules ??= const <Linter>[];
+
+  /**
+   * Set the lint rules that are to be run in an analysis context if [lint]
+   * returns `true`.
+   */
+  void set lintRules(List<Linter> rules) {
+    _lintRules = rules;
+  }
+
+  @override
   List<int> encodeCrossContextOptions() {
     int flags = (enableAssertMessage ? ENABLE_ASSERT_FLAG : 0) |
-        (enableGenericMethods ? ENABLE_GENERIC_METHODS_FLAG : 0) |
         (enableLazyAssignmentOperators ? ENABLE_LAZY_ASSIGNMENT_OPERATORS : 0) |
         (enableStrictCallChecks ? ENABLE_STRICT_CALL_CHECKS_FLAG : 0) |
         (enableSuperMixins ? ENABLE_SUPER_MIXINS_FLAG : 0) |
@@ -1494,7 +1581,6 @@
   @override
   void setCrossContextOptionsFrom(AnalysisOptions options) {
     enableAssertMessage = options.enableAssertMessage;
-    enableGenericMethods = options.enableGenericMethods;
     enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
     enableStrictCallChecks = options.enableStrictCallChecks;
     enableSuperMixins = options.enableSuperMixins;
@@ -1516,9 +1602,6 @@
     if (flags & ENABLE_ASSERT_FLAG > 0) {
       parts.add('assert');
     }
-    if (flags & ENABLE_GENERIC_METHODS_FLAG > 0) {
-      parts.add('genericMethods');
-    }
     if (flags & ENABLE_LAZY_ASSIGNMENT_OPERATORS > 0) {
       parts.add('lazyAssignmentOperators');
     }
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index b04e50b..3d71368 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -8,5 +8,3 @@
 export 'package:analyzer/error/error.dart';
 export 'package:analyzer/error/listener.dart';
 export 'package:analyzer/src/error/codes.dart';
-export 'package:analyzer/src/task/options.dart'
-    show CONFIGURED_ERROR_PROCESSORS;
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index b718661..1787b4a 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -751,7 +751,6 @@
       Parser parser = new Parser(_unitSource, errorListener);
       AnalysisOptions options = _unitElement.context.analysisOptions;
       parser.parseGenericMethodComments = options.strongMode;
-      parser.parseGenericMethods = options.enableGenericMethods;
       CompilationUnit unit = parser.parseCompilationUnit(token);
       _newParseErrors = errorListener.errors;
       return unit;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 0291fde..409960d 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -198,6 +198,12 @@
   bool _enableNnbd = false;
 
   /**
+   * A flag indicating whether the parser is to allow URI's in part-of
+   * directives.
+   */
+  bool _enableUriInPartOf = false;
+
+  /**
    * A flag indicating whether parser is to parse function bodies.
    */
   bool _parseFunctionBodies = true;
@@ -238,6 +244,7 @@
   /**
    * A flag indicating whether the parser is to parse generic method syntax.
    */
+  @deprecated
   bool parseGenericMethods = false;
 
   /**
@@ -293,6 +300,19 @@
   }
 
   /**
+   * Return `true` if the parser is to allow URI's in part-of directives.
+   */
+  bool get enableUriInPartOf => _enableUriInPartOf;
+
+  /**
+   * Set whether the parser is to allow URI's in part-of directives to the given
+   * [enable] flag.
+   */
+  void set enableUriInPartOf(bool enable) {
+    _enableUriInPartOf = enable;
+  }
+
+  /**
    * Return `true` if the current token is the first token of a return type that
    * is followed by an identifier, possibly followed by a list of type
    * parameters, followed by a left-parenthesis. This is used by
@@ -1401,7 +1421,7 @@
       // function type alias that was parsed.
       _parseFunctionTypeAlias(commentAndMetadata, getAndAdvance());
       return null;
-    } else if (parseGenericMethods) {
+    } else {
       Token token = _skipTypeParameterList(_peek());
       if (token != null && _tokenMatches(token, TokenType.OPEN_PAREN)) {
         return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
@@ -1490,7 +1510,7 @@
           methodName,
           typeParameters,
           parameters);
-    } else if (parseGenericMethods && _tokenMatches(next, TokenType.LT)) {
+    } else if (_tokenMatches(next, TokenType.LT)) {
       return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
           modifiers.externalKeyword, modifiers.staticKeyword, type);
     } else if (_tokenMatches(next, TokenType.OPEN_CURLY_BRACKET)) {
@@ -4119,7 +4139,7 @@
         type == TokenType.PERIOD ||
         type == TokenType.QUESTION_PERIOD ||
         type == TokenType.OPEN_PAREN ||
-        (parseGenericMethods && type == TokenType.LT) ||
+        type == TokenType.LT ||
         type == TokenType.INDEX) {
       do {
         if (_isLikelyArgumentList()) {
@@ -5764,9 +5784,6 @@
     if (_matches(TokenType.OPEN_PAREN)) {
       return true;
     }
-    if (!parseGenericMethods) {
-      return false;
-    }
     Token token = skipTypeArgumentList(_currentToken);
     return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
   }
@@ -5825,9 +5842,6 @@
   }
 
   bool _isPeekGenericTypeParametersAndOpenParen() {
-    if (!parseGenericMethods) {
-      return false;
-    }
     Token token = _skipTypeParameterList(_peek());
     return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
   }
@@ -6617,8 +6631,7 @@
    * See [parseGenericMethodComments].
    */
   TypeParameterList _parseGenericMethodTypeParameters() {
-    if (parseGenericMethods && _matches(TokenType.LT) ||
-        _injectGenericCommentTypeList()) {
+    if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
       return parseTypeParameterList();
     }
     return null;
@@ -6897,6 +6910,18 @@
   Directive _parsePartOfDirective(CommentAndMetadata commentAndMetadata) {
     Token partKeyword = getAndAdvance();
     Token ofKeyword = getAndAdvance();
+    if (enableUriInPartOf && _matches(TokenType.STRING)) {
+      StringLiteral libraryUri = _parseUri();
+      Token semicolon = _expect(TokenType.SEMICOLON);
+      return new PartOfDirective(
+          commentAndMetadata.comment,
+          commentAndMetadata.metadata,
+          partKeyword,
+          ofKeyword,
+          libraryUri,
+          null,
+          semicolon);
+    }
     LibraryIdentifier libraryName = _parseLibraryName(
         ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE, ofKeyword);
     Token semicolon = _expect(TokenType.SEMICOLON);
@@ -6905,6 +6930,7 @@
         commentAndMetadata.metadata,
         partKeyword,
         ofKeyword,
+        null,
         libraryName,
         semicolon);
   }
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
similarity index 99%
rename from pkg/analyzer/lib/src/generated/testing/ast_factory.dart
rename to pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 6983cc8..4cb8cb6 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.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 analyzer.src.generated.testing.ast_factory;
+library analyzer.src.generated.testing.ast_test_factory;
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -12,7 +12,7 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
- * The class `AstFactory` defines utility methods that can be used to create AST nodes. The
+ * The class `AstTestFactory` defines utility methods that can be used to create AST nodes. The
  * nodes that are created are complete in the sense that all of the tokens that would have been
  * associated with the nodes by a parser are also created, but the token stream is not constructed.
  * None of the nodes are resolved.
@@ -23,7 +23,7 @@
  * second is places where a shorter name seemed unambiguous and easier to read, such as using
  * 'identifier' rather than 'prefixedIdentifier', or 'integer' rather than 'integerLiteral'.
  */
-class AstFactory {
+class AstTestFactory {
   static AdjacentStrings adjacentStrings(List<StringLiteral> strings) =>
       new AdjacentStrings(strings);
 
@@ -269,7 +269,7 @@
           List<CompilationUnitMember> declarations) =>
       new CompilationUnit(
           TokenFactory.tokenFromType(TokenType.EOF),
-          scriptTag == null ? null : AstFactory.scriptTag(scriptTag),
+          scriptTag == null ? null : AstTestFactory.scriptTag(scriptTag),
           directives == null ? new List<Directive>() : directives,
           declarations == null
               ? new List<CompilationUnitMember>()
@@ -742,7 +742,7 @@
   static Label label(SimpleIdentifier label) =>
       new Label(label, TokenFactory.tokenFromType(TokenType.COLON));
 
-  static Label label2(String label) => AstFactory.label(identifier3(label));
+  static Label label2(String label) => AstTestFactory.label(identifier3(label));
 
   static LabeledStatement labeledStatement(
           List<Label> labels, Statement statement) =>
@@ -973,6 +973,7 @@
           metadata,
           TokenFactory.tokenFromKeyword(Keyword.PART),
           TokenFactory.tokenFromString("of"),
+          null,
           libraryName,
           TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 4147e5a..9069137 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -16,7 +16,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:path/path.dart';
 
@@ -562,10 +562,10 @@
     if (isConst) {
       ConstTopLevelVariableElementImpl constant =
           new ConstTopLevelVariableElementImpl.forNode(
-              AstFactory.identifier3(name));
+              AstTestFactory.identifier3(name));
       InstanceCreationExpression initializer =
-          AstFactory.instanceCreationExpression2(
-              Keyword.CONST, AstFactory.typeName(type.element));
+          AstTestFactory.instanceCreationExpression2(
+              Keyword.CONST, AstTestFactory.typeName(type.element));
       if (type is InterfaceType) {
         ConstructorElement element = type.element.unnamedConstructor;
         initializer.staticElement = element;
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 5e4e43d..953dcee 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -15,7 +15,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source.dart' show Source;
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 
 /**
@@ -172,7 +172,7 @@
         ElementFactory.requiredParameter2("name", stringType),
         ElementFactory.namedParameter3("defaultValue",
             type: _boolType,
-            initializer: AstFactory.booleanLiteral(false),
+            initializer: AstTestFactory.booleanLiteral(false),
             initializerCode: 'false')
       ];
       fromEnvironment.factory = true;
@@ -205,8 +205,8 @@
           .constructorElement(deprecatedElement, '', true, [stringType]);
       (constructor.parameters[0] as ParameterElementImpl).name = 'expires';
       ConstructorFieldInitializer expiresInit =
-          AstFactory.constructorFieldInitializer(
-              true, 'expires', AstFactory.identifier3('expires'));
+          AstTestFactory.constructorFieldInitializer(
+              true, 'expires', AstTestFactory.identifier3('expires'));
       expiresInit.fieldName.staticElement = expiresField;
       (expiresInit.expression as SimpleIdentifier).staticElement =
           constructor.parameters[0];
@@ -269,7 +269,7 @@
       CompilationUnitElementImpl asyncUnit =
           new CompilationUnitElementImpl("async.dart");
       LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
-          _context, AstFactory.libraryIdentifier2(["dart.async"]));
+          _context, AstTestFactory.libraryIdentifier2(["dart.async"]));
       asyncLibrary.definingCompilationUnit = asyncUnit;
       asyncUnit.librarySource = asyncUnit.source = asyncSource;
 
@@ -620,21 +620,21 @@
     ];
     ConstFieldElementImpl varINFINITY = ElementFactory.fieldElement(
         "INFINITY", true, false, true, _doubleType,
-        initializer: AstFactory.doubleLiteral(double.INFINITY));
-    varINFINITY.constantInitializer = AstFactory.binaryExpression(
-        AstFactory.integer(1), TokenType.SLASH, AstFactory.integer(0));
+        initializer: AstTestFactory.doubleLiteral(double.INFINITY));
+    varINFINITY.constantInitializer = AstTestFactory.binaryExpression(
+        AstTestFactory.integer(1), TokenType.SLASH, AstTestFactory.integer(0));
     List<FieldElement> fields = <FieldElement>[
       ElementFactory.fieldElement("NAN", true, false, true, _doubleType,
-          initializer: AstFactory.doubleLiteral(double.NAN)),
+          initializer: AstTestFactory.doubleLiteral(double.NAN)),
       varINFINITY,
       ElementFactory.fieldElement(
           "NEGATIVE_INFINITY", true, false, true, _doubleType,
-          initializer: AstFactory.doubleLiteral(double.NEGATIVE_INFINITY)),
+          initializer: AstTestFactory.doubleLiteral(double.NEGATIVE_INFINITY)),
       ElementFactory.fieldElement(
           "MIN_POSITIVE", true, false, true, _doubleType,
-          initializer: AstFactory.doubleLiteral(double.MIN_POSITIVE)),
+          initializer: AstTestFactory.doubleLiteral(double.MIN_POSITIVE)),
       ElementFactory.fieldElement("MAX_FINITE", true, false, true, _doubleType,
-          initializer: AstFactory.doubleLiteral(double.MAX_FINITE))
+          initializer: AstTestFactory.doubleLiteral(double.MAX_FINITE))
     ];
     doubleElement.fields = fields;
     int fieldCount = fields.length;
diff --git a/pkg/analyzer/lib/src/services/lint.dart b/pkg/analyzer/lib/src/services/lint.dart
index 795b032..097a8df 100644
--- a/pkg/analyzer/lib/src/services/lint.dart
+++ b/pkg/analyzer/lib/src/services/lint.dart
@@ -9,15 +9,6 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
-
-const List<Linter> _noLints = const <Linter>[];
-
-/// The descriptor used to associate lints with analysis contexts in
-/// configuration data.
-final ResultDescriptor<List<Linter>> CONFIGURED_LINTS_KEY =
-    new ResultDescriptorImpl('configured.lints', _noLints);
 
 /// Shared lint registry.
 LintRegistry lintRegistry = new LintRegistry();
@@ -25,11 +16,14 @@
 /// Return lints associated with this [context], or an empty list if there are
 /// none.
 List<Linter> getLints(AnalysisContext context) =>
-    context.getConfigurationData(CONFIGURED_LINTS_KEY) ?? _noLints;
+    context.analysisOptions.lintRules;
 
 /// Associate these [lints] with the given [context].
 void setLints(AnalysisContext context, List<Linter> lints) {
-  context.setConfigurationData(CONFIGURED_LINTS_KEY, lints);
+  AnalysisOptionsImpl options =
+      new AnalysisOptionsImpl.from(context.analysisOptions);
+  options.lintRules = lints;
+  context.analysisOptions = options;
 }
 
 /// Implementers contribute lint warnings via the provided error [reporter].
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 655f5fd..c38e50b 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -2027,7 +2027,6 @@
   List<LinkedDependencyBuilder> _dependencies;
   List<int> _exportDependencies;
   List<LinkedExportNameBuilder> _exportNames;
-  bool _fallbackMode;
   List<int> _importDependencies;
   int _numPrelinkedDependencies;
   List<LinkedUnitBuilder> _units;
@@ -2082,15 +2081,7 @@
   }
 
   @override
-  bool get fallbackMode => _fallbackMode ??= false;
-
-  /**
-   * Indicates whether this library was summarized in "fallback mode".  If
-   * true, all other fields in the data structure have their default values.
-   */
-  void set fallbackMode(bool value) {
-    this._fallbackMode = value;
-  }
+  bool get fallbackMode => throw new UnimplementedError('attempt to access deprecated field');
 
   @override
   List<int> get importDependencies => _importDependencies ??= <int>[];
@@ -2130,11 +2121,10 @@
     this._units = value;
   }
 
-  LinkedLibraryBuilder({List<LinkedDependencyBuilder> dependencies, List<int> exportDependencies, List<LinkedExportNameBuilder> exportNames, bool fallbackMode, List<int> importDependencies, int numPrelinkedDependencies, List<LinkedUnitBuilder> units})
+  LinkedLibraryBuilder({List<LinkedDependencyBuilder> dependencies, List<int> exportDependencies, List<LinkedExportNameBuilder> exportNames, List<int> importDependencies, int numPrelinkedDependencies, List<LinkedUnitBuilder> units})
     : _dependencies = dependencies,
       _exportDependencies = exportDependencies,
       _exportNames = exportNames,
-      _fallbackMode = fallbackMode,
       _importDependencies = importDependencies,
       _numPrelinkedDependencies = numPrelinkedDependencies,
       _units = units;
@@ -2185,7 +2175,6 @@
         x?.collectApiSignature(signature);
       }
     }
-    signature.addBool(this._fallbackMode == true);
     if (this._exportDependencies == null) {
       signature.addInt(0);
     } else {
@@ -2232,9 +2221,6 @@
     if (offset_exportNames != null) {
       fbBuilder.addOffset(4, offset_exportNames);
     }
-    if (_fallbackMode == true) {
-      fbBuilder.addBool(5, true);
-    }
     if (offset_importDependencies != null) {
       fbBuilder.addOffset(1, offset_importDependencies);
     }
@@ -2269,7 +2255,6 @@
   List<idl.LinkedDependency> _dependencies;
   List<int> _exportDependencies;
   List<idl.LinkedExportName> _exportNames;
-  bool _fallbackMode;
   List<int> _importDependencies;
   int _numPrelinkedDependencies;
   List<idl.LinkedUnit> _units;
@@ -2293,10 +2278,7 @@
   }
 
   @override
-  bool get fallbackMode {
-    _fallbackMode ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
-    return _fallbackMode;
-  }
+  bool get fallbackMode => throw new UnimplementedError('attempt to access deprecated field');
 
   @override
   List<int> get importDependencies {
@@ -2324,7 +2306,6 @@
     if (dependencies.isNotEmpty) _result["dependencies"] = dependencies.map((_value) => _value.toJson()).toList();
     if (exportDependencies.isNotEmpty) _result["exportDependencies"] = exportDependencies;
     if (exportNames.isNotEmpty) _result["exportNames"] = exportNames.map((_value) => _value.toJson()).toList();
-    if (fallbackMode != false) _result["fallbackMode"] = fallbackMode;
     if (importDependencies.isNotEmpty) _result["importDependencies"] = importDependencies;
     if (numPrelinkedDependencies != 0) _result["numPrelinkedDependencies"] = numPrelinkedDependencies;
     if (units.isNotEmpty) _result["units"] = units.map((_value) => _value.toJson()).toList();
@@ -2336,7 +2317,6 @@
     "dependencies": dependencies,
     "exportDependencies": exportDependencies,
     "exportNames": exportNames,
-    "fallbackMode": fallbackMode,
     "importDependencies": importDependencies,
     "numPrelinkedDependencies": numPrelinkedDependencies,
     "units": units,
@@ -9563,7 +9543,6 @@
   List<UnlinkedEnumBuilder> _enums;
   List<UnlinkedExecutableBuilder> _executables;
   List<UnlinkedExportNonPublicBuilder> _exports;
-  String _fallbackModePath;
   List<UnlinkedImportBuilder> _imports;
   bool _isPartOf;
   List<UnlinkedExprBuilder> _libraryAnnotations;
@@ -9643,18 +9622,7 @@
   }
 
   @override
-  String get fallbackModePath => _fallbackModePath ??= '';
-
-  /**
-   * If this compilation unit was summarized in fallback mode, the path where
-   * the compilation unit may be found on disk.  Otherwise empty.
-   *
-   * When this field is non-empty, all other fields in the data structure have
-   * their default values.
-   */
-  void set fallbackModePath(String value) {
-    this._fallbackModePath = value;
-  }
+  String get fallbackModePath => throw new UnimplementedError('attempt to access deprecated field');
 
   @override
   List<UnlinkedImportBuilder> get imports => _imports ??= <UnlinkedImportBuilder>[];
@@ -9797,14 +9765,13 @@
     this._variables = value;
   }
 
-  UnlinkedUnitBuilder({List<int> apiSignature, List<UnlinkedClassBuilder> classes, CodeRangeBuilder codeRange, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, String fallbackModePath, List<UnlinkedImportBuilder> imports, bool isPartOf, List<UnlinkedExprBuilder> libraryAnnotations, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, String libraryName, int libraryNameLength, int libraryNameOffset, List<int> lineStarts, List<UnlinkedPartBuilder> parts, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables})
+  UnlinkedUnitBuilder({List<int> apiSignature, List<UnlinkedClassBuilder> classes, CodeRangeBuilder codeRange, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, List<UnlinkedImportBuilder> imports, bool isPartOf, List<UnlinkedExprBuilder> libraryAnnotations, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, String libraryName, int libraryNameLength, int libraryNameOffset, List<int> lineStarts, List<UnlinkedPartBuilder> parts, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables})
     : _apiSignature = apiSignature,
       _classes = classes,
       _codeRange = codeRange,
       _enums = enums,
       _executables = executables,
       _exports = exports,
-      _fallbackModePath = fallbackModePath,
       _imports = imports,
       _isPartOf = isPartOf,
       _libraryAnnotations = libraryAnnotations,
@@ -9928,7 +9895,6 @@
         x?.collectApiSignature(signature);
       }
     }
-    signature.addString(this._fallbackModePath ?? '');
     signature.addBool(this._isPartOf == true);
     if (this._apiSignature == null) {
       signature.addInt(0);
@@ -9952,7 +9918,6 @@
     fb.Offset offset_enums;
     fb.Offset offset_executables;
     fb.Offset offset_exports;
-    fb.Offset offset_fallbackModePath;
     fb.Offset offset_imports;
     fb.Offset offset_libraryAnnotations;
     fb.Offset offset_libraryDocumentationComment;
@@ -9981,9 +9946,6 @@
     if (!(_exports == null || _exports.isEmpty)) {
       offset_exports = fbBuilder.writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
     }
-    if (_fallbackModePath != null) {
-      offset_fallbackModePath = fbBuilder.writeString(_fallbackModePath);
-    }
     if (!(_imports == null || _imports.isEmpty)) {
       offset_imports = fbBuilder.writeList(_imports.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -10033,9 +9995,6 @@
     if (offset_exports != null) {
       fbBuilder.addOffset(13, offset_exports);
     }
-    if (offset_fallbackModePath != null) {
-      fbBuilder.addOffset(16, offset_fallbackModePath);
-    }
     if (offset_imports != null) {
       fbBuilder.addOffset(5, offset_imports);
     }
@@ -10103,7 +10062,6 @@
   List<idl.UnlinkedEnum> _enums;
   List<idl.UnlinkedExecutable> _executables;
   List<idl.UnlinkedExportNonPublic> _exports;
-  String _fallbackModePath;
   List<idl.UnlinkedImport> _imports;
   bool _isPartOf;
   List<idl.UnlinkedExpr> _libraryAnnotations;
@@ -10155,10 +10113,7 @@
   }
 
   @override
-  String get fallbackModePath {
-    _fallbackModePath ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 16, '');
-    return _fallbackModePath;
-  }
+  String get fallbackModePath => throw new UnimplementedError('attempt to access deprecated field');
 
   @override
   List<idl.UnlinkedImport> get imports {
@@ -10249,7 +10204,6 @@
     if (enums.isNotEmpty) _result["enums"] = enums.map((_value) => _value.toJson()).toList();
     if (executables.isNotEmpty) _result["executables"] = executables.map((_value) => _value.toJson()).toList();
     if (exports.isNotEmpty) _result["exports"] = exports.map((_value) => _value.toJson()).toList();
-    if (fallbackModePath != '') _result["fallbackModePath"] = fallbackModePath;
     if (imports.isNotEmpty) _result["imports"] = imports.map((_value) => _value.toJson()).toList();
     if (isPartOf != false) _result["isPartOf"] = isPartOf;
     if (libraryAnnotations.isNotEmpty) _result["libraryAnnotations"] = libraryAnnotations.map((_value) => _value.toJson()).toList();
@@ -10274,7 +10228,6 @@
     "enums": enums,
     "executables": executables,
     "exports": exports,
-    "fallbackModePath": fallbackModePath,
     "imports": imports,
     "isPartOf": isPartOf,
     "libraryAnnotations": libraryAnnotations,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index baf782a..d3df9c0 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -758,7 +758,14 @@
    * the nth enclosing function element.  Then, push the mth local function of
    * that element onto the stack.
    */
-  pushLocalFunctionReference
+  pushLocalFunctionReference,
+
+  /**
+   * Pop the top two values from the stack.  If the first value is non-null,
+   * keep it and discard the second.  Otherwise, keep the second and discard the
+   * first.
+   */
+  ifNull
 }
 
 /**
@@ -1157,7 +1164,7 @@
    * Indicates whether this library was summarized in "fallback mode".  If
    * true, all other fields in the data structure have their default values.
    */
-  fallbackMode:bool (id: 5);
+  fallbackMode:bool (id: 5, deprecated);
 
   /**
    * For each import in [UnlinkedUnit.imports], an index into [dependencies]
@@ -2493,7 +2500,7 @@
    * When this field is non-empty, all other fields in the data structure have
    * their default values.
    */
-  fallbackModePath:string (id: 16);
+  fallbackModePath:string (id: 16, deprecated);
 
   /**
    * Import declarations in the compilation unit.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index d960c4b..53102b1 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -634,6 +634,7 @@
    * Indicates whether this library was summarized in "fallback mode".  If
    * true, all other fields in the data structure have their default values.
    */
+  @deprecated
   @Id(5)
   bool get fallbackMode;
 
@@ -2333,6 +2334,13 @@
    * that element onto the stack.
    */
   pushLocalFunctionReference,
+
+  /**
+   * Pop the top two values from the stack.  If the first value is non-null,
+   * keep it and discard the second.  Otherwise, keep the second and discard the
+   * first.
+   */
+  ifNull,
 }
 
 /**
@@ -2861,6 +2869,7 @@
    * When this field is non-empty, all other fields in the data structure have
    * their default values.
    */
+  @deprecated
   @Id(16)
   String get fallbackModePath;
 
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 6b2e1d7..7bfbed1 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -2265,6 +2265,9 @@
         case UnlinkedExprOperation.pushParameter:
           stack.add(_findParameterType(_getNextString()));
           break;
+        case UnlinkedExprOperation.ifNull:
+          _doIfNull();
+          break;
         default:
           // TODO(paulberry): implement.
           throw new UnimplementedError('$operation');
@@ -2404,6 +2407,14 @@
     }());
   }
 
+  void _doIfNull() {
+    DartType secondType = stack.removeLast();
+    DartType firstType = stack.removeLast();
+    DartType type = _leastUpperBound(firstType, secondType);
+    type = _dynamicIfNull(type);
+    stack.add(type);
+  }
+
   void _doInvokeConstructor() {
     int numNamed = _getNextInt();
     int numPositional = _getNextInt();
@@ -4340,6 +4351,9 @@
   TypeInferenceNode get asTypeInferenceNode => variable._typeInferenceNode;
 
   @override
+  String get displayName => variable.displayName;
+
+  @override
   Element get enclosingElement => variable.enclosingElement;
 
   @override
@@ -4990,6 +5004,9 @@
   }
 
   @override
+  String get displayName => unlinkedVariable.name;
+
+  @override
   PropertyAccessorElementForLink_Variable get getter =>
       _getter ??= new PropertyAccessorElementForLink_Variable(this, false);
 
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 23645da..d178797 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -6,12 +6,10 @@
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/source/source_resource.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
@@ -57,12 +55,7 @@
     UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
     if (unit != null) {
       String summaryPath = _dataStore.uriToSummaryPath[uriString];
-      if (unit.fallbackModePath.isNotEmpty) {
-        return new _InSummaryFallbackSource(
-            new JavaFile(unit.fallbackModePath), actualUri, summaryPath);
-      } else {
-        return new InSummarySource(actualUri, summaryPath);
-      }
+      return new InSummarySource(actualUri, summaryPath);
     }
     return null;
   }
@@ -134,14 +127,7 @@
     UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
     if (unit != null) {
       String summaryPath = _dataStore.uriToSummaryPath[uriString];
-      if (unit.fallbackModePath.isNotEmpty) {
-        return new _InSummaryFallbackFileSource(
-            resourceProvider.getFile(unit.fallbackModePath),
-            actualUri,
-            summaryPath);
-      } else {
-        return new InSummarySource(actualUri, summaryPath);
-      }
+      return new InSummarySource(actualUri, summaryPath);
     }
     return null;
   }
@@ -472,35 +458,6 @@
   @override
   bool hasLibrarySummary(String uri) {
     LinkedLibrary linkedLibrary = _dataStore.linkedMap[uri];
-    return linkedLibrary != null && !linkedLibrary.fallbackMode;
+    return linkedLibrary != null;
   }
 }
-
-/**
- * A source that is part of a package whose summary was generated in fallback
- * mode. This source behaves identically to a [FileSource] except that it also
- * provides [summaryPath].
- */
-class _InSummaryFallbackFileSource extends FileSource
-    implements InSummarySource {
-  @override
-  final String summaryPath;
-
-  _InSummaryFallbackFileSource(File file, Uri uri, this.summaryPath)
-      : super(file, uri);
-}
-
-/**
- * A source that is part of a package whose summary was generated in fallback
- * mode. This source behaves identically to a [FileBasedSource] except that it
- * also provides [summaryPath].
- */
-@deprecated
-class _InSummaryFallbackSource extends FileBasedSource
-    implements InSummarySource {
-  @override
-  final String summaryPath;
-
-  _InSummaryFallbackSource(JavaFile file, Uri uri, this.summaryPath)
-      : super(file, uri);
-}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 30f0aec..f8f2060 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -17,7 +17,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
@@ -331,24 +331,24 @@
 
   Expression build() {
     if (!uc.isValidConst) {
-      return AstFactory.identifier3(r'$$invalidConstExpr$$');
+      return AstTestFactory.identifier3(r'$$invalidConstExpr$$');
     }
     for (UnlinkedExprOperation operation in uc.operations) {
       switch (operation) {
         case UnlinkedExprOperation.pushNull:
-          _push(AstFactory.nullLiteral());
+          _push(AstTestFactory.nullLiteral());
           break;
         // bool
         case UnlinkedExprOperation.pushFalse:
-          _push(AstFactory.booleanLiteral(false));
+          _push(AstTestFactory.booleanLiteral(false));
           break;
         case UnlinkedExprOperation.pushTrue:
-          _push(AstFactory.booleanLiteral(true));
+          _push(AstTestFactory.booleanLiteral(true));
           break;
         // literals
         case UnlinkedExprOperation.pushInt:
           int value = uc.ints[intPtr++];
-          _push(AstFactory.integer(value));
+          _push(AstTestFactory.integer(value));
           break;
         case UnlinkedExprOperation.pushLongInt:
           int value = 0;
@@ -357,20 +357,20 @@
             int next = uc.ints[intPtr++];
             value = value << 32 | next;
           }
-          _push(AstFactory.integer(value));
+          _push(AstTestFactory.integer(value));
           break;
         case UnlinkedExprOperation.pushDouble:
           double value = uc.doubles[doublePtr++];
-          _push(AstFactory.doubleLiteral(value));
+          _push(AstTestFactory.doubleLiteral(value));
           break;
         case UnlinkedExprOperation.makeSymbol:
           String component = uc.strings[stringPtr++];
-          _push(AstFactory.symbolLiteral([component]));
+          _push(AstTestFactory.symbolLiteral([component]));
           break;
         // String
         case UnlinkedExprOperation.pushString:
           String value = uc.strings[stringPtr++];
-          _push(AstFactory.string2(value));
+          _push(AstTestFactory.string2(value));
           break;
         case UnlinkedExprOperation.concatenate:
           int count = uc.ints[intPtr++];
@@ -380,7 +380,7 @@
             InterpolationElement element = _newInterpolationElement(expr);
             elements.insert(0, element);
           }
-          _push(AstFactory.string(elements));
+          _push(AstTestFactory.string(elements));
           break;
         // binary
         case UnlinkedExprOperation.equal:
@@ -455,8 +455,8 @@
           Expression elseExpr = _pop();
           Expression thenExpr = _pop();
           Expression condition = _pop();
-          _push(
-              AstFactory.conditionalExpression(condition, thenExpr, elseExpr));
+          _push(AstTestFactory.conditionalExpression(
+              condition, thenExpr, elseExpr));
           break;
         // invokeMethodRef
         case UnlinkedExprOperation.invokeMethodRef:
@@ -468,7 +468,7 @@
           break;
         case UnlinkedExprOperation.makeTypedList:
           TypeName itemType = _newTypeName();
-          _pushList(AstFactory.typeArgumentList(<TypeName>[itemType]));
+          _pushList(AstTestFactory.typeArgumentList(<TypeName>[itemType]));
           break;
         case UnlinkedExprOperation.makeUntypedMap:
           _pushMap(null);
@@ -476,7 +476,8 @@
         case UnlinkedExprOperation.makeTypedMap:
           TypeName keyType = _newTypeName();
           TypeName valueType = _newTypeName();
-          _pushMap(AstFactory.typeArgumentList(<TypeName>[keyType, valueType]));
+          _pushMap(
+              AstTestFactory.typeArgumentList(<TypeName>[keyType, valueType]));
           break;
         case UnlinkedExprOperation.pushReference:
           _pushReference();
@@ -489,13 +490,16 @@
           break;
         case UnlinkedExprOperation.pushParameter:
           String name = uc.strings[stringPtr++];
-          SimpleIdentifier identifier = AstFactory.identifier3(name);
+          SimpleIdentifier identifier = AstTestFactory.identifier3(name);
           identifier.staticElement = _enclosingConstructor.parameters
               .firstWhere((parameter) => parameter.name == name,
                   orElse: () => throw new StateError(
                       'Unable to resolve constructor parameter: $name'));
           _push(identifier);
           break;
+        case UnlinkedExprOperation.ifNull:
+          _pushBinary(TokenType.QUESTION_QUESTION);
+          break;
         case UnlinkedExprOperation.assignToRef:
         case UnlinkedExprOperation.assignToProperty:
         case UnlinkedExprOperation.assignToIndex:
@@ -525,7 +529,8 @@
       for (int i = 0; i < numNamedArgs; i++) {
         String name = uc.strings[stringPtr++];
         int index = numPositionalArgs + i;
-        arguments[index] = AstFactory.namedExpression2(name, arguments[index]);
+        arguments[index] =
+            AstTestFactory.namedExpression2(name, arguments[index]);
       }
     }
     return arguments;
@@ -545,16 +550,16 @@
       element = _getStringLengthElement();
     }
     if (enclosing == null) {
-      return AstFactory.identifier3(info.name)..staticElement = element;
+      return AstTestFactory.identifier3(info.name)..staticElement = element;
     }
     if (enclosing is SimpleIdentifier) {
-      SimpleIdentifier identifier = AstFactory.identifier3(info.name)
+      SimpleIdentifier identifier = AstTestFactory.identifier3(info.name)
         ..staticElement = element;
-      return AstFactory.identifier(enclosing, identifier);
+      return AstTestFactory.identifier(enclosing, identifier);
     }
-    SimpleIdentifier property = AstFactory.identifier3(info.name)
+    SimpleIdentifier property = AstTestFactory.identifier3(info.name)
       ..staticElement = element;
-    return AstFactory.propertyAccess(enclosing, property);
+    return AstTestFactory.propertyAccess(enclosing, property);
   }
 
   TypeName _buildTypeAst(DartType type) {
@@ -568,7 +573,7 @@
             : typeArguments.map(_buildTypeAst).toList();
       }
     }
-    TypeName node = AstFactory.typeName4(type.name, argumentNodes);
+    TypeName node = AstTestFactory.typeName4(type.name, argumentNodes);
     node.type = type;
     (node.name as SimpleIdentifier).staticElement = type.element;
     return node;
@@ -608,18 +613,18 @@
   void _pushBinary(TokenType operator) {
     Expression right = _pop();
     Expression left = _pop();
-    _push(AstFactory.binaryExpression(left, operator, right));
+    _push(AstTestFactory.binaryExpression(left, operator, right));
   }
 
   void _pushExtractProperty() {
     Expression target = _pop();
     String name = uc.strings[stringPtr++];
-    SimpleIdentifier propertyNode = AstFactory.identifier3(name);
+    SimpleIdentifier propertyNode = AstTestFactory.identifier3(name);
     // Only String.length property access can be potentially resolved.
     if (name == 'length') {
       propertyNode.staticElement = _getStringLengthElement();
     }
-    _push(AstFactory.propertyAccess(target, propertyNode));
+    _push(AstTestFactory.propertyAccess(target, propertyNode));
   }
 
   void _pushInstanceCreation() {
@@ -646,29 +651,29 @@
     } else {
       if (info.enclosing != null) {
         if (info.enclosing.enclosing != null) {
-          PrefixedIdentifier typeName = AstFactory.identifier5(
+          PrefixedIdentifier typeName = AstTestFactory.identifier5(
               info.enclosing.enclosing.name, info.enclosing.name);
           typeName.prefix.staticElement = info.enclosing.enclosing.element;
           typeName.identifier.staticElement = info.enclosing.element;
           typeName.identifier.staticType = info.enclosing.type;
-          typeNode = AstFactory.typeName3(typeName);
+          typeNode = AstTestFactory.typeName3(typeName);
           typeNode.type = info.enclosing.type;
           constructorName = info.name;
         } else if (info.enclosing.element != null) {
           SimpleIdentifier typeName =
-              AstFactory.identifier3(info.enclosing.name);
+              AstTestFactory.identifier3(info.enclosing.name);
           typeName.staticElement = info.enclosing.element;
           typeName.staticType = info.enclosing.type;
-          typeNode = AstFactory.typeName3(typeName);
+          typeNode = AstTestFactory.typeName3(typeName);
           typeNode.type = info.enclosing.type;
           constructorName = info.name;
         } else {
-          typeNode = AstFactory.typeName3(
-              AstFactory.identifier5(info.enclosing.name, info.name));
+          typeNode = AstTestFactory.typeName3(
+              AstTestFactory.identifier5(info.enclosing.name, info.name));
           constructorName = null;
         }
       } else {
-        typeNode = AstFactory.typeName4(info.name);
+        typeNode = AstTestFactory.typeName4(info.name);
       }
     }
     // prepare arguments
@@ -676,14 +681,15 @@
     // create ConstructorName
     ConstructorName constructorNode;
     if (constructorName != null) {
-      constructorNode = AstFactory.constructorName(typeNode, constructorName);
+      constructorNode =
+          AstTestFactory.constructorName(typeNode, constructorName);
       constructorNode.name.staticElement = constructorElement;
     } else {
-      constructorNode = AstFactory.constructorName(typeNode, null);
+      constructorNode = AstTestFactory.constructorName(typeNode, null);
     }
     constructorNode.staticElement = constructorElement;
     // create InstanceCreationExpression
-    InstanceCreationExpression instanceCreation = AstFactory
+    InstanceCreationExpression instanceCreation = AstTestFactory
         .instanceCreationExpression(Keyword.CONST, constructorNode, arguments);
     instanceCreation.staticElement = constructorElement;
     _push(instanceCreation);
@@ -701,7 +707,7 @@
       for (int i = 0; i < numTypeArguments; i++) {
         typeNames[i] = _newTypeName();
       }
-      typeArguments = AstFactory.typeArgumentList(typeNames);
+      typeArguments = AstTestFactory.typeArgumentList(typeNames);
     }
     if (node is SimpleIdentifier) {
       _push(new MethodInvocation(
@@ -709,7 +715,7 @@
           TokenFactory.tokenFromType(TokenType.PERIOD),
           node,
           typeArguments,
-          AstFactory.argumentList(arguments)));
+          AstTestFactory.argumentList(arguments)));
     } else {
       throw new UnimplementedError('For ${node?.runtimeType}: $node');
     }
@@ -721,7 +727,7 @@
     for (int i = 0; i < count; i++) {
       elements.insert(0, _pop());
     }
-    _push(AstFactory.listLiteral2(Keyword.CONST, typeArguments, elements));
+    _push(AstTestFactory.listLiteral2(Keyword.CONST, typeArguments, elements));
   }
 
   void _pushMap(TypeArgumentList typeArguments) {
@@ -730,14 +736,14 @@
     for (int i = 0; i < count; i++) {
       Expression value = _pop();
       Expression key = _pop();
-      entries.insert(0, AstFactory.mapLiteralEntry2(key, value));
+      entries.insert(0, AstTestFactory.mapLiteralEntry2(key, value));
     }
-    _push(AstFactory.mapLiteral(Keyword.CONST, typeArguments, entries));
+    _push(AstTestFactory.mapLiteral(Keyword.CONST, typeArguments, entries));
   }
 
   void _pushPrefix(TokenType operator) {
     Expression operand = _pop();
-    _push(AstFactory.prefixExpression(operator, operand));
+    _push(AstTestFactory.prefixExpression(operator, operand));
   }
 
   void _pushReference() {
@@ -1514,7 +1520,7 @@
     Expression constExpr = _buildConstExpression(context, uc);
     if (constExpr is Identifier) {
       elementAnnotation.element = constExpr.staticElement;
-      elementAnnotation.annotationAst = AstFactory.annotation(constExpr);
+      elementAnnotation.annotationAst = AstTestFactory.annotation(constExpr);
     } else if (constExpr is InstanceCreationExpression) {
       elementAnnotation.element = constExpr.staticElement;
       Identifier typeName = constExpr.constructorName.type.name;
@@ -1522,10 +1528,10 @@
       if (typeName is SimpleIdentifier && constructorName != null) {
         // E.g. `@cls.ctor()`.  Since `cls.ctor` would have been parsed as
         // a PrefixedIdentifier, we need to resynthesize it as one.
-        typeName = AstFactory.identifier(typeName, constructorName);
+        typeName = AstTestFactory.identifier(typeName, constructorName);
         constructorName = null;
       }
-      elementAnnotation.annotationAst = AstFactory.annotation2(
+      elementAnnotation.annotationAst = AstTestFactory.annotation2(
           typeName, constructorName, constExpr.argumentList)
         ..element = constExpr.staticElement;
     } else {
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 4662be8..f7e6911 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -486,6 +486,8 @@
       operations.add(UnlinkedExprOperation.lessEqual);
     } else if (operator == TokenType.PERCENT) {
       operations.add(UnlinkedExprOperation.modulo);
+    } else if (operator == TokenType.QUESTION_QUESTION) {
+      operations.add(UnlinkedExprOperation.ifNull);
     } else {
       throw new StateError('Unknown operator: $operator');
     }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index dbbd1a6..9e3b31e 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -16,7 +16,7 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/dart/ast/ast.dart'
-    show NamespaceDirectiveImpl, UriBasedDirectiveImpl;
+    show NamespaceDirectiveImpl, UriBasedDirectiveImpl, UriValidationCode;
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -1551,28 +1551,43 @@
           // name as the library.
           //
           if (context.exists(partSource)) {
-            String partLibraryName =
-                _getPartLibraryName(partSource, partUnit, directivesToResolve);
-            if (partLibraryName == null) {
+            _NameOrSource nameOrSource = _getPartLibraryNameOrUri(
+                context, partSource, partUnit, directivesToResolve);
+            if (nameOrSource == null) {
               errors.add(new AnalysisError(
                   librarySource,
                   partUri.offset,
                   partUri.length,
                   CompileTimeErrorCode.PART_OF_NON_PART,
                   [partUri.toSource()]));
-            } else if (libraryNameNode == null) {
-              if (partsLibraryName == _UNKNOWN_LIBRARY_NAME) {
-                partsLibraryName = partLibraryName;
-              } else if (partsLibraryName != partLibraryName) {
-                partsLibraryName = null;
+            } else {
+              String name = nameOrSource.name;
+              if (name != null) {
+                if (libraryNameNode == null) {
+                  if (partsLibraryName == _UNKNOWN_LIBRARY_NAME) {
+                    partsLibraryName = name;
+                  } else if (partsLibraryName != name) {
+                    partsLibraryName = null;
+                  }
+                } else if (libraryNameNode.name != name) {
+                  errors.add(new AnalysisError(
+                      librarySource,
+                      partUri.offset,
+                      partUri.length,
+                      StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+                      [libraryNameNode.name, name]));
+                }
+              } else {
+                Source source = nameOrSource.source;
+                if (source != librarySource) {
+                  errors.add(new AnalysisError(
+                      librarySource,
+                      partUri.offset,
+                      partUri.length,
+                      StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+                      [librarySource.uri.toString(), source.uri.toString()]));
+                }
               }
-            } else if (libraryNameNode.name != partLibraryName) {
-              errors.add(new AnalysisError(
-                  librarySource,
-                  partUri.offset,
-                  partUri.length,
-                  StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
-                  [libraryNameNode.name, partLibraryName]));
             }
           }
           if (entryPoint == null) {
@@ -1679,7 +1694,10 @@
    * Return the name of the library that the given part is declared to be a
    * part of, or `null` if the part does not contain a part-of directive.
    */
-  String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
+  _NameOrSource _getPartLibraryNameOrUri(
+      AnalysisContext context,
+      Source partSource,
+      CompilationUnit partUnit,
       List<Directive> directivesToResolve) {
     NodeList<Directive> directives = partUnit.directives;
     int length = directives.length;
@@ -1689,7 +1707,15 @@
         directivesToResolve.add(directive);
         LibraryIdentifier libraryName = directive.libraryName;
         if (libraryName != null) {
-          return libraryName.name;
+          return new _NameOrSource(libraryName.name, null);
+        }
+        String uri = directive.uri?.stringValue;
+        if (uri != null) {
+          Source librarySource =
+              context.sourceFactory.resolveUri(partSource, uri);
+          if (librarySource != null) {
+            return new _NameOrSource(null, librarySource);
+          }
         }
       }
     }
@@ -4020,8 +4046,8 @@
     parser.enableAssertInitializer = options.enableAssertInitializer;
     parser.parseFunctionBodies =
         options.analyzeFunctionBodiesPredicate(_source);
-    parser.parseGenericMethods = options.enableGenericMethods;
     parser.parseGenericMethodComments = options.strongMode;
+    parser.enableUriInPartOf = options.enableUriInPartOf;
     CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
     unit.lineInfo = lineInfo;
 
@@ -6240,8 +6266,8 @@
    * Check the given [directive] to see if the referenced source exists and
    * report an error if it does not.
    */
-  void validateReferencedSource(UriBasedDirective directive) {
-    if (directive is NamespaceDirective) {
+  void validateReferencedSource(UriBasedDirectiveImpl directive) {
+    if (directive is NamespaceDirectiveImpl) {
       for (Configuration configuration in directive.configurations) {
         Source source = configuration.uriSource;
         StringLiteral uriLiteral = configuration.uri;
@@ -6381,6 +6407,18 @@
 }
 
 /**
+ * An object holding either the name or the source associated with a part-of
+ * directive.
+ */
+class _NameOrSource {
+  final String name;
+
+  final Source source;
+
+  _NameOrSource(this.name, this.source);
+}
+
+/**
  * The kind of the source closure to build.
  */
 enum _SourceClosureKind { IMPORT, EXPORT, IMPORT_EXPORT }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index eb7455d..5dfe1dc 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -29,14 +28,6 @@
     new ListResultDescriptor<AnalysisError>(
         'ANALYSIS_OPTIONS_ERRORS', AnalysisError.NO_ERRORS);
 
-/**
- * The descriptor used to associate error processors with analysis contexts in
- * configuration data.
- */
-final ListResultDescriptor<ErrorProcessor> CONFIGURED_ERROR_PROCESSORS =
-    new ListResultDescriptor<ErrorProcessor>(
-        'configured.errors', const <ErrorProcessor>[]);
-
 final _OptionsProcessor _processor = new _OptionsProcessor();
 
 void applyToAnalysisOptions(
@@ -510,9 +501,17 @@
       var strongMode = analyzer[AnalyzerOptions.strong_mode];
       _applyStrongOptions(options, strongMode);
 
+      // Set filters.
+      var filters = analyzer[AnalyzerOptions.errors];
+      _applyProcessors(options, filters);
+
       // Process language options.
       var language = analyzer[AnalyzerOptions.language];
       _applyLanguageOptions(options, language);
+
+      // Process excludes.
+      var excludes = analyzer[AnalyzerOptions.exclude];
+      _applyExcludes(options, excludes);
     }
   }
 
@@ -547,7 +546,10 @@
     if (excludes is YamlList) {
       List<String> excludeList = toStringList(excludes);
       if (excludeList != null) {
-        context.setConfigurationData(CONTEXT_EXCLUDES, excludeList);
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.excludePatterns = excludeList;
+        context.analysisOptions = options;
       }
     }
   }
@@ -578,14 +580,6 @@
         context.analysisOptions = options;
       }
     }
-    if (feature == AnalyzerOptions.enableGenericMethods) {
-      if (isTrue(value)) {
-        AnalysisOptionsImpl options =
-            new AnalysisOptionsImpl.from(context.analysisOptions);
-        options.enableGenericMethods = true;
-        context.analysisOptions = options;
-      }
-    }
   }
 
   void setLanguageOptions(AnalysisContext context, Object configs) {
@@ -603,8 +597,10 @@
 
   void setProcessors(AnalysisContext context, Object codes) {
     ErrorConfig config = new ErrorConfig(codes);
-    context.setConfigurationData(
-        CONFIGURED_ERROR_PROCESSORS, config.processors);
+    AnalysisOptionsImpl options =
+        new AnalysisOptionsImpl.from(context.analysisOptions);
+    options.errorProcessors = config.processors;
+    context.analysisOptions = options;
   }
 
   void setStrongMode(AnalysisContext context, Object strongMode) {
@@ -624,6 +620,15 @@
     }
   }
 
+  void _applyExcludes(AnalysisOptionsImpl options, Object excludes) {
+    if (excludes is YamlList) {
+      List<String> excludeList = toStringList(excludes);
+      if (excludeList != null) {
+        options.excludePatterns = excludeList;
+      }
+    }
+  }
+
   void _applyLanguageOption(
       AnalysisOptionsImpl options, Object feature, Object value) {
     bool boolValue = toBool(value);
@@ -634,8 +639,6 @@
         options.enableInitializingFormalAccess = boolValue;
       } else if (feature == AnalyzerOptions.enableSuperMixins) {
         options.enableSuperMixins = boolValue;
-      } else if (feature == AnalyzerOptions.enableGenericMethods) {
-        options.enableGenericMethods = boolValue;
       }
     }
   }
@@ -654,6 +657,11 @@
     }
   }
 
+  void _applyProcessors(AnalysisOptionsImpl options, Object codes) {
+    ErrorConfig config = new ErrorConfig(codes);
+    options.errorProcessors = config.processors;
+  }
+
   void _applyStrongModeOption(
       AnalysisOptionsImpl options, Object feature, Object value) {
     bool boolValue = toBool(value);
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index ffc0d21..3a887f8 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -7,7 +7,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -37,19 +37,22 @@
     List<ConstructorInitializer> initializers =
         new List<ConstructorInitializer>();
     ConstructorDeclaration defaultConstructor =
-        AstFactory.constructorDeclaration(AstFactory.identifier3("Test"), null,
-            AstFactory.formalParameterList(), initializers);
-    ConstructorDeclaration aConstructor = AstFactory.constructorDeclaration(
-        AstFactory.identifier3("Test"),
+        AstTestFactory.constructorDeclaration(
+            AstTestFactory.identifier3("Test"),
+            null,
+            AstTestFactory.formalParameterList(),
+            initializers);
+    ConstructorDeclaration aConstructor = AstTestFactory.constructorDeclaration(
+        AstTestFactory.identifier3("Test"),
         "a",
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         initializers);
-    ConstructorDeclaration bConstructor = AstFactory.constructorDeclaration(
-        AstFactory.identifier3("Test"),
+    ConstructorDeclaration bConstructor = AstTestFactory.constructorDeclaration(
+        AstTestFactory.identifier3("Test"),
         "b",
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         initializers);
-    ClassDeclaration clazz = AstFactory.classDeclaration(null, "Test", null,
+    ClassDeclaration clazz = AstTestFactory.classDeclaration(null, "Test", null,
         null, null, null, [defaultConstructor, aConstructor, bConstructor]);
     expect(clazz.getConstructor(null), same(defaultConstructor));
     expect(clazz.getConstructor("a"), same(aConstructor));
@@ -58,13 +61,13 @@
   }
 
   void test_getField() {
-    VariableDeclaration aVar = AstFactory.variableDeclaration("a");
-    VariableDeclaration bVar = AstFactory.variableDeclaration("b");
-    VariableDeclaration cVar = AstFactory.variableDeclaration("c");
+    VariableDeclaration aVar = AstTestFactory.variableDeclaration("a");
+    VariableDeclaration bVar = AstTestFactory.variableDeclaration("b");
+    VariableDeclaration cVar = AstTestFactory.variableDeclaration("c");
     ClassDeclaration clazz =
-        AstFactory.classDeclaration(null, "Test", null, null, null, null, [
-      AstFactory.fieldDeclaration2(false, null, [aVar]),
-      AstFactory.fieldDeclaration2(false, null, [bVar, cVar])
+        AstTestFactory.classDeclaration(null, "Test", null, null, null, null, [
+      AstTestFactory.fieldDeclaration2(false, null, [aVar]),
+      AstTestFactory.fieldDeclaration2(false, null, [bVar, cVar])
     ]);
     expect(clazz.getField("a"), same(aVar));
     expect(clazz.getField("b"), same(bVar));
@@ -73,11 +76,21 @@
   }
 
   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(
+    MethodDeclaration aMethod = AstTestFactory.methodDeclaration(
+        null,
+        null,
+        null,
+        null,
+        AstTestFactory.identifier3("a"),
+        AstTestFactory.formalParameterList());
+    MethodDeclaration bMethod = AstTestFactory.methodDeclaration(
+        null,
+        null,
+        null,
+        null,
+        AstTestFactory.identifier3("b"),
+        AstTestFactory.formalParameterList());
+    ClassDeclaration clazz = AstTestFactory.classDeclaration(
         null, "Test", null, null, null, null, [aMethod, bMethod]);
     expect(clazz.getMethod("a"), same(aMethod));
     expect(clazz.getMethod("b"), same(bMethod));
@@ -86,12 +99,12 @@
 
   void test_isAbstract() {
     expect(
-        AstFactory
+        AstTestFactory
             .classDeclaration(null, "A", null, null, null, null)
             .isAbstract,
         isFalse);
     expect(
-        AstFactory
+        AstTestFactory
             .classDeclaration(Keyword.ABSTRACT, "B", null, null, null, null)
             .isAbstract,
         isTrue);
@@ -102,10 +115,12 @@
 class ClassTypeAliasTest extends ParserTestCase {
   void test_isAbstract() {
     expect(
-        AstFactory.classTypeAlias("A", null, null, null, null, null).isAbstract,
+        AstTestFactory
+            .classTypeAlias("A", null, null, null, null, null)
+            .isAbstract,
         isFalse);
     expect(
-        AstFactory
+        AstTestFactory
             .classTypeAlias("B", null, Keyword.ABSTRACT, null, null, null)
             .isAbstract,
         isTrue);
@@ -117,10 +132,10 @@
   void test_firstTokenAfterCommentAndMetadata_all_inverted() {
     Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
     externalKeyword.offset = 14;
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
         Keyword.CONST,
         Keyword.FACTORY,
-        AstFactory.identifier3('int'),
+        AstTestFactory.identifier3('int'),
         null,
         null,
         null,
@@ -135,10 +150,10 @@
   void test_firstTokenAfterCommentAndMetadata_all_normal() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
     token.offset = 0;
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
         Keyword.CONST,
         Keyword.FACTORY,
-        AstFactory.identifier3('int'),
+        AstTestFactory.identifier3('int'),
         null,
         null,
         null,
@@ -150,10 +165,10 @@
   }
 
   void test_firstTokenAfterCommentAndMetadata_constOnly() {
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
         Keyword.CONST,
         null,
-        AstFactory.identifier3('int'),
+        AstTestFactory.identifier3('int'),
         null,
         null,
         null,
@@ -164,17 +179,17 @@
 
   void test_firstTokenAfterCommentAndMetadata_externalOnly() {
     Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
-        null, null, AstFactory.identifier3('int'), null, null, null, null);
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
+        null, null, AstTestFactory.identifier3('int'), null, null, null, null);
     declaration.externalKeyword = externalKeyword;
     expect(declaration.firstTokenAfterCommentAndMetadata, externalKeyword);
   }
 
   void test_firstTokenAfterCommentAndMetadata_factoryOnly() {
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
         null,
         Keyword.FACTORY,
-        AstFactory.identifier3('int'),
+        AstTestFactory.identifier3('int'),
         null,
         null,
         null,
@@ -187,13 +202,14 @@
 @reflectiveTest
 class FieldFormalParameterTest extends EngineTestCase {
   void test_endToken_noParameters() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('field');
+    FieldFormalParameter parameter =
+        AstTestFactory.fieldFormalParameter2('field');
     expect(parameter.endToken, parameter.identifier.endToken);
   }
 
   void test_endToken_parameters() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter(
-        null, null, 'field', AstFactory.formalParameterList([]));
+    FieldFormalParameter parameter = AstTestFactory.fieldFormalParameter(
+        null, null, 'field', AstTestFactory.formalParameterList([]));
     expect(parameter.endToken, parameter.parameters.endToken);
   }
 }
@@ -201,106 +217,106 @@
 @reflectiveTest
 class IndexExpressionTest extends EngineTestCase {
   void test_inGetterContext_assignment_compound_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // a[b] += c
-    AstFactory.assignmentExpression(
-        expression, TokenType.PLUS_EQ, AstFactory.identifier3("c"));
+    AstTestFactory.assignmentExpression(
+        expression, TokenType.PLUS_EQ, AstTestFactory.identifier3("c"));
     expect(expression.inGetterContext(), isTrue);
   }
 
   void test_inGetterContext_assignment_simple_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // a[b] = c
-    AstFactory.assignmentExpression(
-        expression, TokenType.EQ, AstFactory.identifier3("c"));
+    AstTestFactory.assignmentExpression(
+        expression, TokenType.EQ, AstTestFactory.identifier3("c"));
     expect(expression.inGetterContext(), isFalse);
   }
 
   void test_inGetterContext_nonAssignment() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // a[b] + c
-    AstFactory.binaryExpression(
-        expression, TokenType.PLUS, AstFactory.identifier3("c"));
+    AstTestFactory.binaryExpression(
+        expression, TokenType.PLUS, AstTestFactory.identifier3("c"));
     expect(expression.inGetterContext(), isTrue);
   }
 
   void test_inSetterContext_assignment_compound_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // a[b] += c
-    AstFactory.assignmentExpression(
-        expression, TokenType.PLUS_EQ, AstFactory.identifier3("c"));
+    AstTestFactory.assignmentExpression(
+        expression, TokenType.PLUS_EQ, AstTestFactory.identifier3("c"));
     expect(expression.inSetterContext(), isTrue);
   }
 
   void test_inSetterContext_assignment_compound_right() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // c += a[b]
-    AstFactory.assignmentExpression(
-        AstFactory.identifier3("c"), TokenType.PLUS_EQ, expression);
+    AstTestFactory.assignmentExpression(
+        AstTestFactory.identifier3("c"), TokenType.PLUS_EQ, expression);
     expect(expression.inSetterContext(), isFalse);
   }
 
   void test_inSetterContext_assignment_simple_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // a[b] = c
-    AstFactory.assignmentExpression(
-        expression, TokenType.EQ, AstFactory.identifier3("c"));
+    AstTestFactory.assignmentExpression(
+        expression, TokenType.EQ, AstTestFactory.identifier3("c"));
     expect(expression.inSetterContext(), isTrue);
   }
 
   void test_inSetterContext_assignment_simple_right() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // c = a[b]
-    AstFactory.assignmentExpression(
-        AstFactory.identifier3("c"), TokenType.EQ, expression);
+    AstTestFactory.assignmentExpression(
+        AstTestFactory.identifier3("c"), TokenType.EQ, expression);
     expect(expression.inSetterContext(), isFalse);
   }
 
   void test_inSetterContext_nonAssignment() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    AstFactory.binaryExpression(
-        expression, TokenType.PLUS, AstFactory.identifier3("c"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
+    AstTestFactory.binaryExpression(
+        expression, TokenType.PLUS, AstTestFactory.identifier3("c"));
     // a[b] + cc
     expect(expression.inSetterContext(), isFalse);
   }
 
   void test_inSetterContext_postfix() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    AstFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
+    AstTestFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
     // a[b]++
     expect(expression.inSetterContext(), isTrue);
   }
 
   void test_inSetterContext_prefix_bang() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // !a[b]
-    AstFactory.prefixExpression(TokenType.BANG, expression);
+    AstTestFactory.prefixExpression(TokenType.BANG, expression);
     expect(expression.inSetterContext(), isFalse);
   }
 
   void test_inSetterContext_prefix_minusMinus() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // --a[b]
-    AstFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+    AstTestFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
     expect(expression.inSetterContext(), isTrue);
   }
 
   void test_inSetterContext_prefix_plusPlus() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    IndexExpression expression = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
     // ++a[b]
-    AstFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+    AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
     expect(expression.inSetterContext(), isTrue);
   }
 }
@@ -309,20 +325,20 @@
 class MethodDeclarationTest extends EngineTestCase {
   void test_firstTokenAfterCommentAndMetadata_external() {
     MethodDeclaration declaration =
-        AstFactory.methodDeclaration4(external: true, name: 'm');
+        AstTestFactory.methodDeclaration4(external: true, name: 'm');
     expect(declaration.firstTokenAfterCommentAndMetadata,
         declaration.externalKeyword);
   }
 
   void test_firstTokenAfterCommentAndMetadata_external_getter() {
-    MethodDeclaration declaration = AstFactory.methodDeclaration4(
+    MethodDeclaration declaration = AstTestFactory.methodDeclaration4(
         external: true, property: Keyword.GET, name: 'm');
     expect(declaration.firstTokenAfterCommentAndMetadata,
         declaration.externalKeyword);
   }
 
   void test_firstTokenAfterCommentAndMetadata_external_operator() {
-    MethodDeclaration declaration = AstFactory.methodDeclaration4(
+    MethodDeclaration declaration = AstTestFactory.methodDeclaration4(
         external: true, operator: true, name: 'm');
     expect(declaration.firstTokenAfterCommentAndMetadata,
         declaration.externalKeyword);
@@ -330,14 +346,14 @@
 
   void test_firstTokenAfterCommentAndMetadata_getter() {
     MethodDeclaration declaration =
-        AstFactory.methodDeclaration4(property: Keyword.GET, name: 'm');
+        AstTestFactory.methodDeclaration4(property: Keyword.GET, name: 'm');
     expect(declaration.firstTokenAfterCommentAndMetadata,
         declaration.propertyKeyword);
   }
 
   void test_firstTokenAfterCommentAndMetadata_operator() {
     MethodDeclaration declaration =
-        AstFactory.methodDeclaration4(operator: true, name: 'm');
+        AstTestFactory.methodDeclaration4(operator: true, name: 'm');
     expect(declaration.firstTokenAfterCommentAndMetadata,
         declaration.operatorKeyword);
   }
@@ -346,9 +362,9 @@
 @reflectiveTest
 class NodeListTest extends EngineTestCase {
   void test_add() {
-    AstNode parent = AstFactory.argumentList();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
+    AstNode parent = AstTestFactory.argumentList();
+    AstNode firstNode = AstTestFactory.booleanLiteral(true);
+    AstNode secondNode = AstTestFactory.booleanLiteral(false);
     NodeList<AstNode> list = new NodeList<AstNode>(parent);
     list.insert(0, secondNode);
     list.insert(0, firstNode);
@@ -357,7 +373,7 @@
     expect(list[1], same(secondNode));
     expect(firstNode.parent, same(parent));
     expect(secondNode.parent, same(parent));
-    AstNode thirdNode = AstFactory.booleanLiteral(false);
+    AstNode thirdNode = AstTestFactory.booleanLiteral(false);
     list.insert(1, thirdNode);
     expect(list, hasLength(3));
     expect(list[0], same(firstNode));
@@ -369,9 +385,10 @@
   }
 
   void test_add_negative() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
-      list.insert(-1, AstFactory.booleanLiteral(true));
+      list.insert(-1, AstTestFactory.booleanLiteral(true));
       fail("Expected IndexOutOfBoundsException");
     } on RangeError {
       // Expected
@@ -379,9 +396,10 @@
   }
 
   void test_add_tooBig() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
-      list.insert(1, AstFactory.booleanLiteral(true));
+      list.insert(1, AstTestFactory.booleanLiteral(true));
       fail("Expected IndexOutOfBoundsException");
     } on RangeError {
       // Expected
@@ -389,10 +407,10 @@
   }
 
   void test_addAll() {
-    AstNode parent = AstFactory.argumentList();
+    AstNode parent = AstTestFactory.argumentList();
     List<AstNode> firstNodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
+    AstNode firstNode = AstTestFactory.booleanLiteral(true);
+    AstNode secondNode = AstTestFactory.booleanLiteral(false);
     firstNodes.add(firstNode);
     firstNodes.add(secondNode);
     NodeList<AstNode> list = new NodeList<AstNode>(parent);
@@ -403,8 +421,8 @@
     expect(firstNode.parent, same(parent));
     expect(secondNode.parent, same(parent));
     List<AstNode> secondNodes = new List<AstNode>();
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
-    AstNode fourthNode = AstFactory.booleanLiteral(false);
+    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
+    AstNode fourthNode = AstTestFactory.booleanLiteral(false);
     secondNodes.add(thirdNode);
     secondNodes.add(fourthNode);
     list.addAll(secondNodes);
@@ -420,7 +438,7 @@
   }
 
   void test_creation() {
-    AstNode owner = AstFactory.argumentList();
+    AstNode owner = AstTestFactory.argumentList();
     NodeList<AstNode> list = new NodeList<AstNode>(owner);
     expect(list, isNotNull);
     expect(list, hasLength(0));
@@ -428,7 +446,8 @@
   }
 
   void test_get_negative() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
       list[-1];
       fail("Expected IndexOutOfBoundsException");
@@ -438,7 +457,8 @@
   }
 
   void test_get_tooBig() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
       list[1];
       fail("Expected IndexOutOfBoundsException");
@@ -448,41 +468,46 @@
   }
 
   void test_getBeginToken_empty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     expect(list.beginToken, isNull);
   }
 
   void test_getBeginToken_nonEmpty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    AstNode node =
-        AstFactory.parenthesizedExpression(AstFactory.booleanLiteral(true));
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
+    AstNode node = AstTestFactory
+        .parenthesizedExpression(AstTestFactory.booleanLiteral(true));
     list.add(node);
     expect(list.beginToken, same(node.beginToken));
   }
 
   void test_getEndToken_empty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     expect(list.endToken, isNull);
   }
 
   void test_getEndToken_nonEmpty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    AstNode node =
-        AstFactory.parenthesizedExpression(AstFactory.booleanLiteral(true));
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
+    AstNode node = AstTestFactory
+        .parenthesizedExpression(AstTestFactory.booleanLiteral(true));
     list.add(node);
     expect(list.endToken, same(node.endToken));
   }
 
   void test_indexOf() {
     List<AstNode> nodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
-    AstNode fourthNode = AstFactory.booleanLiteral(false);
+    AstNode firstNode = AstTestFactory.booleanLiteral(true);
+    AstNode secondNode = AstTestFactory.booleanLiteral(false);
+    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
+    AstNode fourthNode = AstTestFactory.booleanLiteral(false);
     nodes.add(firstNode);
     nodes.add(secondNode);
     nodes.add(thirdNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     list.addAll(nodes);
     expect(list, hasLength(3));
     expect(list.indexOf(firstNode), 0);
@@ -494,13 +519,14 @@
 
   void test_remove() {
     List<AstNode> nodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
+    AstNode firstNode = AstTestFactory.booleanLiteral(true);
+    AstNode secondNode = AstTestFactory.booleanLiteral(false);
+    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
     nodes.add(firstNode);
     nodes.add(secondNode);
     nodes.add(thirdNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     list.addAll(nodes);
     expect(list, hasLength(3));
     expect(list.removeAt(1), same(secondNode));
@@ -510,7 +536,8 @@
   }
 
   void test_remove_negative() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
       list.removeAt(-1);
       fail("Expected IndexOutOfBoundsException");
@@ -520,7 +547,8 @@
   }
 
   void test_remove_tooBig() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
       list.removeAt(1);
       fail("Expected IndexOutOfBoundsException");
@@ -531,16 +559,17 @@
 
   void test_set() {
     List<AstNode> nodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
+    AstNode firstNode = AstTestFactory.booleanLiteral(true);
+    AstNode secondNode = AstTestFactory.booleanLiteral(false);
+    AstNode thirdNode = AstTestFactory.booleanLiteral(true);
     nodes.add(firstNode);
     nodes.add(secondNode);
     nodes.add(thirdNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     list.addAll(nodes);
     expect(list, hasLength(3));
-    AstNode fourthNode = AstFactory.integer(0);
+    AstNode fourthNode = AstTestFactory.integer(0);
     list[1] = fourthNode;
     expect(list, hasLength(3));
     expect(list[0], same(firstNode));
@@ -549,8 +578,9 @@
   }
 
   void test_set_negative() {
-    AstNode node = AstFactory.booleanLiteral(true);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    AstNode node = AstTestFactory.booleanLiteral(true);
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
       list[-1] = node;
       fail("Expected IndexOutOfBoundsException");
@@ -560,8 +590,9 @@
   }
 
   void test_set_tooBig() {
-    AstNode node = AstFactory.booleanLiteral(true);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    AstNode node = AstTestFactory.booleanLiteral(true);
+    NodeList<AstNode> list =
+        new NodeList<AstNode>(AstTestFactory.argumentList());
     try {
       list[1] = node;
       fail("Expected IndexOutOfBoundsException");
@@ -593,24 +624,24 @@
   }
 
   void test_inGetterContext_constructorFieldInitializer() {
-    ConstructorFieldInitializer initializer = AstFactory
-        .constructorFieldInitializer(false, 'f', AstFactory.integer(0));
+    ConstructorFieldInitializer initializer = AstTestFactory
+        .constructorFieldInitializer(false, 'f', AstTestFactory.integer(0));
     SimpleIdentifier identifier = initializer.fieldName;
     expect(identifier.inGetterContext(), isFalse);
   }
 
   void test_inGetterContext_forEachLoop() {
-    SimpleIdentifier identifier = AstFactory.identifier3("a");
-    Expression iterator = AstFactory.listLiteral();
-    Statement body = AstFactory.block();
-    AstFactory.forEachStatement2(identifier, iterator, body);
+    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
+    Expression iterator = AstTestFactory.listLiteral();
+    Statement body = AstTestFactory.block();
+    AstTestFactory.forEachStatement2(identifier, iterator, body);
     expect(identifier.inGetterContext(), isFalse);
   }
 
   void test_inReferenceContext() {
-    SimpleIdentifier identifier = AstFactory.identifier3("id");
-    AstFactory.namedExpression(
-        AstFactory.label(identifier), AstFactory.identifier3("_"));
+    SimpleIdentifier identifier = AstTestFactory.identifier3("id");
+    AstTestFactory.namedExpression(
+        AstTestFactory.label(identifier), AstTestFactory.identifier3("_"));
     expect(identifier.inGetterContext(), isFalse);
     expect(identifier.inSetterContext(), isFalse);
   }
@@ -639,102 +670,104 @@
   }
 
   void test_inSetterContext_forEachLoop() {
-    SimpleIdentifier identifier = AstFactory.identifier3("a");
-    Expression iterator = AstFactory.listLiteral();
-    Statement body = AstFactory.block();
-    AstFactory.forEachStatement2(identifier, iterator, body);
+    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
+    Expression iterator = AstTestFactory.listLiteral();
+    Statement body = AstTestFactory.block();
+    AstTestFactory.forEachStatement2(identifier, iterator, body);
     expect(identifier.inSetterContext(), isTrue);
   }
 
   void test_isQualified_inMethodInvocation_noTarget() {
-    MethodInvocation invocation =
-        AstFactory.methodInvocation2("test", [AstFactory.identifier3("arg0")]);
+    MethodInvocation invocation = AstTestFactory
+        .methodInvocation2("test", [AstTestFactory.identifier3("arg0")]);
     SimpleIdentifier identifier = invocation.methodName;
     expect(identifier.isQualified, isFalse);
   }
 
   void test_isQualified_inMethodInvocation_withTarget() {
-    MethodInvocation invocation = AstFactory.methodInvocation(
-        AstFactory.identifier3("target"),
+    MethodInvocation invocation = AstTestFactory.methodInvocation(
+        AstTestFactory.identifier3("target"),
         "test",
-        [AstFactory.identifier3("arg0")]);
+        [AstTestFactory.identifier3("arg0")]);
     SimpleIdentifier identifier = invocation.methodName;
     expect(identifier.isQualified, isTrue);
   }
 
   void test_isQualified_inPrefixedIdentifier_name() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.identifier4("prefix", identifier);
+    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
+    AstTestFactory.identifier4("prefix", identifier);
     expect(identifier.isQualified, isTrue);
   }
 
   void test_isQualified_inPrefixedIdentifier_prefix() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.identifier(identifier, AstFactory.identifier3("name"));
+    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
+    AstTestFactory.identifier(identifier, AstTestFactory.identifier3("name"));
     expect(identifier.isQualified, isFalse);
   }
 
   void test_isQualified_inPropertyAccess_name() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.propertyAccess(AstFactory.identifier3("target"), identifier);
+    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
+    AstTestFactory.propertyAccess(
+        AstTestFactory.identifier3("target"), identifier);
     expect(identifier.isQualified, isTrue);
   }
 
   void test_isQualified_inPropertyAccess_target() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.propertyAccess(identifier, AstFactory.identifier3("name"));
+    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
+    AstTestFactory.propertyAccess(
+        identifier, AstTestFactory.identifier3("name"));
     expect(identifier.isQualified, isFalse);
   }
 
   void test_isQualified_inReturnStatement() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.returnStatement2(identifier);
+    SimpleIdentifier identifier = AstTestFactory.identifier3("test");
+    AstTestFactory.returnStatement2(identifier);
     expect(identifier.isQualified, isFalse);
   }
 
   SimpleIdentifier _createIdentifier(
       _WrapperKind wrapper, _AssignmentKind assignment) {
-    SimpleIdentifier identifier = AstFactory.identifier3("a");
+    SimpleIdentifier identifier = AstTestFactory.identifier3("a");
     Expression expression = identifier;
     while (true) {
       if (wrapper == _WrapperKind.PREFIXED_LEFT) {
-        expression =
-            AstFactory.identifier(identifier, AstFactory.identifier3("_"));
+        expression = AstTestFactory.identifier(
+            identifier, AstTestFactory.identifier3("_"));
       } else if (wrapper == _WrapperKind.PREFIXED_RIGHT) {
-        expression =
-            AstFactory.identifier(AstFactory.identifier3("_"), identifier);
+        expression = AstTestFactory.identifier(
+            AstTestFactory.identifier3("_"), identifier);
       } else if (wrapper == _WrapperKind.PROPERTY_LEFT) {
-        expression = AstFactory.propertyAccess2(expression, "_");
+        expression = AstTestFactory.propertyAccess2(expression, "_");
       } else if (wrapper == _WrapperKind.PROPERTY_RIGHT) {
-        expression =
-            AstFactory.propertyAccess(AstFactory.identifier3("_"), identifier);
+        expression = AstTestFactory.propertyAccess(
+            AstTestFactory.identifier3("_"), identifier);
       } else if (wrapper == _WrapperKind.NONE) {}
       break;
     }
     while (true) {
       if (assignment == _AssignmentKind.BINARY) {
-        AstFactory.binaryExpression(
-            expression, TokenType.PLUS, AstFactory.identifier3("_"));
+        AstTestFactory.binaryExpression(
+            expression, TokenType.PLUS, AstTestFactory.identifier3("_"));
       } else if (assignment == _AssignmentKind.COMPOUND_LEFT) {
-        AstFactory.assignmentExpression(
-            expression, TokenType.PLUS_EQ, AstFactory.identifier3("_"));
+        AstTestFactory.assignmentExpression(
+            expression, TokenType.PLUS_EQ, AstTestFactory.identifier3("_"));
       } else if (assignment == _AssignmentKind.COMPOUND_RIGHT) {
-        AstFactory.assignmentExpression(
-            AstFactory.identifier3("_"), TokenType.PLUS_EQ, expression);
+        AstTestFactory.assignmentExpression(
+            AstTestFactory.identifier3("_"), TokenType.PLUS_EQ, expression);
       } else if (assignment == _AssignmentKind.POSTFIX_INC) {
-        AstFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+        AstTestFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
       } else if (assignment == _AssignmentKind.PREFIX_DEC) {
-        AstFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+        AstTestFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
       } else if (assignment == _AssignmentKind.PREFIX_INC) {
-        AstFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+        AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
       } else if (assignment == _AssignmentKind.PREFIX_NOT) {
-        AstFactory.prefixExpression(TokenType.BANG, expression);
+        AstTestFactory.prefixExpression(TokenType.BANG, expression);
       } else if (assignment == _AssignmentKind.SIMPLE_LEFT) {
-        AstFactory.assignmentExpression(
-            expression, TokenType.EQ, AstFactory.identifier3("_"));
+        AstTestFactory.assignmentExpression(
+            expression, TokenType.EQ, AstTestFactory.identifier3("_"));
       } else if (assignment == _AssignmentKind.SIMPLE_RIGHT) {
-        AstFactory.assignmentExpression(
-            AstFactory.identifier3("_"), TokenType.EQ, expression);
+        AstTestFactory.assignmentExpression(
+            AstTestFactory.identifier3("_"), TokenType.EQ, expression);
       } else if (assignment == _AssignmentKind.NONE) {}
       break;
     }
@@ -996,128 +1029,130 @@
 @reflectiveTest
 class StringInterpolationTest extends ParserTestCase {
   void test_contentsOffsetEnd() {
-    AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
+    AstTestFactory.interpolationExpression(AstTestFactory.identifier3('bb'));
     // 'a${bb}ccc'
     {
-      var ae = AstFactory.interpolationString("'a", "a");
+      var ae = AstTestFactory.interpolationString("'a", "a");
       var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
       var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
       expect(node.contentsOffset, 1);
       expect(node.contentsEnd, 10 + 4 - 1);
     }
     // '''a${bb}ccc'''
     {
-      var ae = AstFactory.interpolationString("'''a", "a");
+      var ae = AstTestFactory.interpolationString("'''a", "a");
       var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
       var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
       expect(node.contentsOffset, 3);
       expect(node.contentsEnd, 10 + 4 - 1);
     }
     // """a${bb}ccc"""
     {
-      var ae = AstFactory.interpolationString('"""a', "a");
+      var ae = AstTestFactory.interpolationString('"""a', "a");
       var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
       var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
       expect(node.contentsOffset, 3);
       expect(node.contentsEnd, 10 + 4 - 1);
     }
     // r'a${bb}ccc'
     {
-      var ae = AstFactory.interpolationString("r'a", "a");
+      var ae = AstTestFactory.interpolationString("r'a", "a");
       var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
       var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
       expect(node.contentsOffset, 2);
       expect(node.contentsEnd, 10 + 4 - 1);
     }
     // r'''a${bb}ccc'''
     {
-      var ae = AstFactory.interpolationString("r'''a", "a");
+      var ae = AstTestFactory.interpolationString("r'''a", "a");
       var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
       var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
       expect(node.contentsOffset, 4);
       expect(node.contentsEnd, 10 + 4 - 1);
     }
     // r"""a${bb}ccc"""
     {
-      var ae = AstFactory.interpolationString('r"""a', "a");
+      var ae = AstTestFactory.interpolationString('r"""a', "a");
       var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
       var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      StringInterpolation node = AstTestFactory.string([ae, ae, cElement]);
       expect(node.contentsOffset, 4);
       expect(node.contentsEnd, 10 + 4 - 1);
     }
   }
 
   void test_isMultiline() {
-    var b = AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
+    var b = AstTestFactory
+        .interpolationExpression(AstTestFactory.identifier3('bb'));
     // '
     {
-      var a = AstFactory.interpolationString("'a", "a");
-      var c = AstFactory.interpolationString("ccc'", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString("'a", "a");
+      var c = AstTestFactory.interpolationString("ccc'", "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isMultiline, isFalse);
     }
     // '''
     {
-      var a = AstFactory.interpolationString("'''a", "a");
-      var c = AstFactory.interpolationString("ccc'''", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString("'''a", "a");
+      var c = AstTestFactory.interpolationString("ccc'''", "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isMultiline, isTrue);
     }
     // "
     {
-      var a = AstFactory.interpolationString('"a', "a");
-      var c = AstFactory.interpolationString('ccc"', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString('"a', "a");
+      var c = AstTestFactory.interpolationString('ccc"', "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isMultiline, isFalse);
     }
     // """
     {
-      var a = AstFactory.interpolationString('"""a', "a");
-      var c = AstFactory.interpolationString('ccc"""', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString('"""a', "a");
+      var c = AstTestFactory.interpolationString('ccc"""', "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isMultiline, isTrue);
     }
   }
 
   void test_isRaw() {
-    StringInterpolation node = AstFactory.string();
+    StringInterpolation node = AstTestFactory.string();
     expect(node.isRaw, isFalse);
   }
 
   void test_isSingleQuoted() {
-    var b = AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
+    var b = AstTestFactory
+        .interpolationExpression(AstTestFactory.identifier3('bb'));
     // "
     {
-      var a = AstFactory.interpolationString('"a', "a");
-      var c = AstFactory.interpolationString('ccc"', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString('"a', "a");
+      var c = AstTestFactory.interpolationString('ccc"', "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isSingleQuoted, isFalse);
     }
     // """
     {
-      var a = AstFactory.interpolationString('"""a', "a");
-      var c = AstFactory.interpolationString('ccc"""', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString('"""a', "a");
+      var c = AstTestFactory.interpolationString('ccc"""', "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isSingleQuoted, isFalse);
     }
     // '
     {
-      var a = AstFactory.interpolationString("'a", "a");
-      var c = AstFactory.interpolationString("ccc'", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString("'a", "a");
+      var c = AstTestFactory.interpolationString("ccc'", "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isSingleQuoted, isTrue);
     }
     // '''
     {
-      var a = AstFactory.interpolationString("'''a", "a");
-      var c = AstFactory.interpolationString("ccc'''", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
+      var a = AstTestFactory.interpolationString("'''a", "a");
+      var c = AstTestFactory.interpolationString("ccc'''", "ccc");
+      StringInterpolation node = AstTestFactory.string([a, b, c]);
       expect(node.isSingleQuoted, isTrue);
     }
   }
@@ -1126,9 +1161,9 @@
 @reflectiveTest
 class VariableDeclarationTest extends ParserTestCase {
   void test_getDocumentationComment_onGrandParent() {
-    VariableDeclaration varDecl = AstFactory.variableDeclaration("a");
+    VariableDeclaration varDecl = AstTestFactory.variableDeclaration("a");
     TopLevelVariableDeclaration decl =
-        AstFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
+        AstTestFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     expect(varDecl.documentationComment, isNull);
     decl.documentationComment = comment;
@@ -1137,7 +1172,7 @@
   }
 
   void test_getDocumentationComment_onNode() {
-    VariableDeclaration decl = AstFactory.variableDeclaration("a");
+    VariableDeclaration decl = AstTestFactory.variableDeclaration("a");
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     decl.documentationComment = comment;
     expect(decl.documentationComment, isNotNull);
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index db35770..c9b22c9 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -248,9 +248,9 @@
   }
 
   void test_visitCompilationUnit_codeRange() {
-    TopLevelVariableDeclaration topLevelVariableDeclaration = AstFactory
-        .topLevelVariableDeclaration(null, AstFactory.typeName4('int'),
-            [AstFactory.variableDeclaration('V')]);
+    TopLevelVariableDeclaration topLevelVariableDeclaration = AstTestFactory
+        .topLevelVariableDeclaration(null, AstTestFactory.typeName4('int'),
+            [AstTestFactory.variableDeclaration('V')]);
     CompilationUnit unit = new CompilationUnit(
         topLevelVariableDeclaration.beginToken,
         null,
@@ -305,9 +305,9 @@
     // p = 0
     String parameterName = 'p';
     DefaultFormalParameter formalParameter =
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter3(parameterName),
-            AstFactory.integer(0));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter3(parameterName),
+            AstTestFactory.integer(0));
     formalParameter.beginToken.offset = 50;
     formalParameter.endToken.offset = 80;
 
@@ -334,10 +334,11 @@
   void test_visitDefaultFormalParameter_type() {
     // E p = 0
     String parameterName = 'p';
-    DefaultFormalParameter formalParameter = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter4(
-            AstFactory.typeName4('E'), parameterName),
-        AstFactory.integer(0));
+    DefaultFormalParameter formalParameter =
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter4(
+                AstTestFactory.typeName4('E'), parameterName),
+            AstTestFactory.integer(0));
 
     ElementHolder holder = buildElementsForAst(formalParameter);
     List<ParameterElement> parameters = holder.parameters;
@@ -361,8 +362,9 @@
   void test_visitFunctionExpression() {
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = _makeBuilder(holder);
-    FunctionExpression expression = AstFactory.functionExpression2(
-        AstFactory.formalParameterList(), AstFactory.blockFunctionBody2());
+    FunctionExpression expression = AstTestFactory.functionExpression2(
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
     expression.accept(builder);
     List<FunctionElement> functions = holder.functions;
     expect(functions, hasLength(1));
@@ -401,9 +403,9 @@
     ElementBuilder builder = _makeBuilder(holder);
     String aliasName = "F";
     String parameterName = "E";
-    FunctionTypeAlias aliasNode = AstFactory.typeAlias(
-        null, aliasName, AstFactory.typeParameterList([parameterName]), null);
-    aliasNode.documentationComment = AstFactory.documentationComment(
+    FunctionTypeAlias aliasNode = AstTestFactory.typeAlias(null, aliasName,
+        AstTestFactory.typeParameterList([parameterName]), null);
+    aliasNode.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     aliasNode.endToken.offset = 80;
     aliasNode.accept(builder);
@@ -428,7 +430,7 @@
     ElementBuilder builder = _makeBuilder(holder);
     String parameterName = "p";
     FunctionTypedFormalParameter formalParameter =
-        AstFactory.functionTypedFormalParameter(null, parameterName);
+        AstTestFactory.functionTypedFormalParameter(null, parameterName);
     _useParameterInMethod(formalParameter, 100, 110);
     formalParameter.accept(builder);
     List<ParameterElement> parameters = holder.parameters;
@@ -449,8 +451,8 @@
     ElementBuilder builder = _makeBuilder(holder);
     String parameterName = "p";
     FunctionTypedFormalParameter formalParameter =
-        AstFactory.functionTypedFormalParameter(null, parameterName);
-    formalParameter.typeParameters = AstFactory.typeParameterList(['F']);
+        AstTestFactory.functionTypedFormalParameter(null, parameterName);
+    formalParameter.typeParameters = AstTestFactory.typeParameterList(['F']);
     _useParameterInMethod(formalParameter, 100, 110);
     formalParameter.accept(builder);
     List<ParameterElement> parameters = holder.parameters;
@@ -523,9 +525,10 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = _makeBuilder(holder);
     String parameterName = "p";
-    DefaultFormalParameter formalParameter = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter3(parameterName),
-        AstFactory.identifier3("42"));
+    DefaultFormalParameter formalParameter =
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter3(parameterName),
+            AstTestFactory.identifier3("42"));
     _useParameterInMethod(formalParameter, 100, 110);
     formalParameter.beginToken.offset = 50;
     formalParameter.endToken.offset = 80;
@@ -554,7 +557,7 @@
     ElementBuilder builder = _makeBuilder(holder);
     String parameterName = "p";
     SimpleFormalParameter formalParameter =
-        AstFactory.simpleFormalParameter3(parameterName);
+        AstTestFactory.simpleFormalParameter3(parameterName);
     _useParameterInMethod(formalParameter, 100, 110);
     formalParameter.accept(builder);
     List<ParameterElement> parameters = holder.parameters;
@@ -576,8 +579,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = _makeBuilder(holder);
     String parameterName = "p";
-    SimpleFormalParameter formalParameter = AstFactory.simpleFormalParameter4(
-        AstFactory.typeName4('T'), parameterName);
+    SimpleFormalParameter formalParameter = AstTestFactory
+        .simpleFormalParameter4(AstTestFactory.typeName4('T'), parameterName);
     _useParameterInMethod(formalParameter, 100, 110);
     formalParameter.accept(builder);
     List<ParameterElement> parameters = holder.parameters;
@@ -617,19 +620,19 @@
     // m() { for (var v in []) }
     //
     String variableName = "v";
-    Statement statement = AstFactory.forEachStatement(
-        AstFactory.declaredIdentifier3('v'),
-        AstFactory.listLiteral(),
-        AstFactory.block());
+    Statement statement = AstTestFactory.forEachStatement(
+        AstTestFactory.declaredIdentifier3('v'),
+        AstTestFactory.listLiteral(),
+        AstTestFactory.block());
     _setNodeSourceRange(statement, 100, 110);
-    MethodDeclaration method = AstFactory.methodDeclaration2(
+    MethodDeclaration method = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2([statement]));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2([statement]));
     _setBlockBodySourceRange(method.body, 200, 220);
     method.accept(builder);
 
@@ -649,21 +652,23 @@
     // m() { for (T v;;) }
     //
     String variableName = "v";
-    ForStatement statement = AstFactory.forStatement2(
-        AstFactory.variableDeclarationList(null, AstFactory.typeName4('T'),
-            [AstFactory.variableDeclaration('v')]),
+    ForStatement statement = AstTestFactory.forStatement2(
+        AstTestFactory.variableDeclarationList(
+            null,
+            AstTestFactory.typeName4('T'),
+            [AstTestFactory.variableDeclaration('v')]),
         null,
         null,
-        AstFactory.block());
+        AstTestFactory.block());
     _setNodeSourceRange(statement, 100, 110);
-    MethodDeclaration method = AstFactory.methodDeclaration2(
+    MethodDeclaration method = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2([statement]));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2([statement]));
     _setBlockBodySourceRange(method.body, 200, 220);
     method.accept(builder);
 
@@ -684,17 +689,17 @@
     //
     String variableName = "v";
     VariableDeclaration variable =
-        AstFactory.variableDeclaration2(variableName, null);
-    Statement statement = AstFactory.variableDeclarationStatement(
-        null, AstFactory.typeName4('T'), [variable]);
-    MethodDeclaration method = AstFactory.methodDeclaration2(
+        AstTestFactory.variableDeclaration2(variableName, null);
+    Statement statement = AstTestFactory.variableDeclarationStatement(
+        null, AstTestFactory.typeName4('T'), [variable]);
+    MethodDeclaration method = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2([statement]));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2([statement]));
     _setBlockBodySourceRange(method.body, 100, 110);
     method.accept(builder);
 
@@ -716,17 +721,17 @@
     //
     String variableName = "v";
     VariableDeclaration variable =
-        AstFactory.variableDeclaration2(variableName, null);
+        AstTestFactory.variableDeclaration2(variableName, null);
     Statement statement =
-        AstFactory.variableDeclarationStatement2(null, [variable]);
-    Expression initializer = AstFactory.functionExpression2(
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2([statement]));
+        AstTestFactory.variableDeclarationStatement2(null, [variable]);
+    Expression initializer = AstTestFactory.functionExpression2(
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2([statement]));
     String fieldName = "f";
     VariableDeclaration field =
-        AstFactory.variableDeclaration2(fieldName, initializer);
+        AstTestFactory.variableDeclaration2(fieldName, initializer);
     FieldDeclaration fieldDeclaration =
-        AstFactory.fieldDeclaration2(false, null, [field]);
+        AstTestFactory.fieldDeclaration2(false, null, [field]);
     fieldDeclaration.accept(builder);
 
     List<FieldElement> variables = holder.fields;
@@ -755,8 +760,8 @@
     ElementBuilder builder = _makeBuilder(holder);
     String variableName = "v";
     VariableDeclaration variableDeclaration =
-        AstFactory.variableDeclaration2(variableName, null);
-    AstFactory.variableDeclarationList2(null, [variableDeclaration]);
+        AstTestFactory.variableDeclaration2(variableName, null);
+    AstTestFactory.variableDeclarationList2(null, [variableDeclaration]);
     variableDeclaration.accept(builder);
 
     List<TopLevelVariableElement> variables = holder.topLevelVariables;
@@ -778,13 +783,13 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = _makeBuilder(holder);
     VariableDeclaration variableDeclaration1 =
-        AstFactory.variableDeclaration('a');
+        AstTestFactory.variableDeclaration('a');
     VariableDeclaration variableDeclaration2 =
-        AstFactory.variableDeclaration('b');
-    TopLevelVariableDeclaration topLevelVariableDeclaration = AstFactory
+        AstTestFactory.variableDeclaration('b');
+    TopLevelVariableDeclaration topLevelVariableDeclaration = AstTestFactory
         .topLevelVariableDeclaration(
             Keyword.FINAL, null, [variableDeclaration1, variableDeclaration2]);
-    topLevelVariableDeclaration.documentationComment = AstFactory
+    topLevelVariableDeclaration.documentationComment = AstTestFactory
         .documentationComment(
             [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
 
@@ -806,9 +811,10 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = _makeBuilder(holder);
     String variableName = "v";
-    VariableDeclaration variableDeclaration =
-        AstFactory.variableDeclaration2(variableName, AstFactory.integer(42));
-    AstFactory.variableDeclarationList2(Keyword.CONST, [variableDeclaration]);
+    VariableDeclaration variableDeclaration = AstTestFactory
+        .variableDeclaration2(variableName, AstTestFactory.integer(42));
+    AstTestFactory
+        .variableDeclarationList2(Keyword.CONST, [variableDeclaration]);
     variableDeclaration.accept(builder);
 
     List<TopLevelVariableElement> variables = holder.topLevelVariables;
@@ -833,8 +839,9 @@
     ElementBuilder builder = _makeBuilder(holder);
     String variableName = "v";
     VariableDeclaration variableDeclaration =
-        AstFactory.variableDeclaration2(variableName, null);
-    AstFactory.variableDeclarationList2(Keyword.FINAL, [variableDeclaration]);
+        AstTestFactory.variableDeclaration2(variableName, null);
+    AstTestFactory
+        .variableDeclarationList2(Keyword.FINAL, [variableDeclaration]);
     variableDeclaration.accept(builder);
     List<TopLevelVariableElement> variables = holder.topLevelVariables;
     expect(variables, hasLength(1));
@@ -865,17 +872,17 @@
 
   void _useParameterInMethod(
       FormalParameter formalParameter, int blockOffset, int blockEnd) {
-    Block block = AstFactory.block();
+    Block block = AstTestFactory.block();
     block.leftBracket.offset = blockOffset;
     block.rightBracket.offset = blockEnd - 1;
-    BlockFunctionBody body = AstFactory.blockFunctionBody(block);
-    AstFactory.methodDeclaration2(
+    BlockFunctionBody body = AstTestFactory.blockFunctionBody(block);
+    AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("main"),
-        AstFactory.formalParameterList([formalParameter]),
+        AstTestFactory.identifier3("main"),
+        AstTestFactory.formalParameterList([formalParameter]),
         body);
   }
 }
@@ -1262,9 +1269,9 @@
 
   void test_visitClassDeclaration_minimal() {
     String className = "C";
-    ClassDeclaration classDeclaration =
-        AstFactory.classDeclaration(null, className, null, null, null, null);
-    classDeclaration.documentationComment = AstFactory.documentationComment(
+    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
+        null, className, null, null, null, null);
+    classDeclaration.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     classDeclaration.endToken.offset = 80;
 
@@ -1287,10 +1294,11 @@
     String className = "C";
     String firstVariableName = "E";
     String secondVariableName = "F";
-    ClassDeclaration classDeclaration = AstFactory.classDeclaration(
+    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
         null,
         className,
-        AstFactory.typeParameterList([firstVariableName, secondVariableName]),
+        AstTestFactory
+            .typeParameterList([firstVariableName, secondVariableName]),
         null,
         null,
         null);
@@ -1315,23 +1323,23 @@
     String typeParameterName = "E";
     String fieldName = "f";
     String methodName = "m";
-    ClassDeclaration classDeclaration = AstFactory.classDeclaration(
+    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
         null,
         className,
-        AstFactory.typeParameterList([typeParameterName]),
+        AstTestFactory.typeParameterList([typeParameterName]),
         null,
         null,
         null, [
-      AstFactory.fieldDeclaration2(
-          false, null, [AstFactory.variableDeclaration(fieldName)]),
-      AstFactory.methodDeclaration2(
+      AstTestFactory.fieldDeclaration2(
+          false, null, [AstTestFactory.variableDeclaration(fieldName)]),
+      AstTestFactory.methodDeclaration2(
           null,
           null,
           null,
           null,
-          AstFactory.identifier3(methodName),
-          AstFactory.formalParameterList(),
-          AstFactory.blockFunctionBody2())
+          AstTestFactory.identifier3(methodName),
+          AstTestFactory.formalParameterList(),
+          AstTestFactory.blockFunctionBody2())
     ]);
 
     ElementHolder holder = buildElementsForAst(classDeclaration);
@@ -1371,9 +1379,9 @@
     classB.constructors = [constructorB];
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(classM, [])]);
-    ClassTypeAlias alias = AstFactory.classTypeAlias(
-        'C', null, null, AstFactory.typeName(classB, []), withClause, null);
+        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
+        'C', null, null, AstTestFactory.typeName(classB, []), withClause, null);
 
     ElementHolder holder = buildElementsForAst(alias);
     List<ClassElement> types = holder.types;
@@ -1400,9 +1408,14 @@
     classB.constructors = [constructorB];
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(classM, [])]);
-    ClassTypeAlias alias = AstFactory.classTypeAlias('C', null,
-        Keyword.ABSTRACT, AstFactory.typeName(classB, []), withClause, null);
+        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
+        'C',
+        null,
+        Keyword.ABSTRACT,
+        AstTestFactory.typeName(classB, []),
+        withClause,
+        null);
 
     ElementHolder holder = buildElementsForAst(alias);
     List<ClassElement> types = holder.types;
@@ -1423,12 +1436,12 @@
     classB.constructors = [constructorB];
     ClassElementImpl classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(classM, [])]);
-    ClassTypeAlias alias = AstFactory.classTypeAlias(
+        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
         'C',
-        AstFactory.typeParameterList(['T']),
+        AstTestFactory.typeParameterList(['T']),
         null,
-        AstFactory.typeName(classB, []),
+        AstTestFactory.typeName(classB, []),
         withClause,
         null);
 
@@ -1443,14 +1456,14 @@
   void test_visitConstructorDeclaration_external() {
     String className = "A";
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3(className),
+            AstTestFactory.identifier3(className),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2());
+            AstTestFactory.blockFunctionBody2());
     constructorDeclaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
 
@@ -1471,14 +1484,14 @@
   void test_visitConstructorDeclaration_factory() {
     String className = "A";
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             Keyword.FACTORY,
-            AstFactory.identifier3(className),
+            AstTestFactory.identifier3(className),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2());
+            AstTestFactory.blockFunctionBody2());
 
     ElementHolder holder = buildElementsForAst(constructorDeclaration);
     List<ConstructorElement> constructors = holder.constructors;
@@ -1497,15 +1510,15 @@
   void test_visitConstructorDeclaration_minimal() {
     String className = "A";
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3(className),
+            AstTestFactory.identifier3(className),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2());
-    constructorDeclaration.documentationComment = AstFactory
+            AstTestFactory.blockFunctionBody2());
+    constructorDeclaration.documentationComment = AstTestFactory
         .documentationComment(
             [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     constructorDeclaration.endToken.offset = 80;
@@ -1530,14 +1543,14 @@
     String className = "A";
     String constructorName = "c";
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3(className),
+            AstTestFactory.identifier3(className),
             constructorName,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2());
+            AstTestFactory.blockFunctionBody2());
 
     ElementHolder holder = buildElementsForAst(constructorDeclaration);
     List<ConstructorElement> constructors = holder.constructors;
@@ -1558,14 +1571,14 @@
   void test_visitConstructorDeclaration_unnamed() {
     String className = "A";
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3(className),
+            AstTestFactory.identifier3(className),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2());
+            AstTestFactory.blockFunctionBody2());
 
     ElementHolder holder = buildElementsForAst(constructorDeclaration);
     List<ConstructorElement> constructors = holder.constructors;
@@ -1585,8 +1598,8 @@
   void test_visitEnumDeclaration() {
     String enumName = "E";
     EnumDeclaration enumDeclaration =
-        AstFactory.enumDeclaration2(enumName, ["ONE"]);
-    enumDeclaration.documentationComment = AstFactory.documentationComment(
+        AstTestFactory.enumDeclaration2(enumName, ["ONE"]);
+    enumDeclaration.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     enumDeclaration.endToken.offset = 80;
     ElementHolder holder = buildElementsForAst(enumDeclaration);
@@ -1603,11 +1616,11 @@
     String firstFieldName = "x";
     String secondFieldName = "y";
     FieldDeclaration fieldDeclaration =
-        AstFactory.fieldDeclaration2(false, null, [
-      AstFactory.variableDeclaration(firstFieldName),
-      AstFactory.variableDeclaration(secondFieldName)
+        AstTestFactory.fieldDeclaration2(false, null, [
+      AstTestFactory.variableDeclaration(firstFieldName),
+      AstTestFactory.variableDeclaration(secondFieldName)
     ]);
-    fieldDeclaration.documentationComment = AstFactory.documentationComment(
+    fieldDeclaration.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     fieldDeclaration.endToken.offset = 110;
 
@@ -1639,7 +1652,7 @@
   void test_visitFieldFormalParameter() {
     String parameterName = "p";
     FieldFormalParameter formalParameter =
-        AstFactory.fieldFormalParameter(null, null, parameterName);
+        AstTestFactory.fieldFormalParameter(null, null, parameterName);
     formalParameter.beginToken.offset = 50;
     formalParameter.endToken.offset = 80;
     ElementHolder holder = buildElementsForAst(formalParameter);
@@ -1659,12 +1672,12 @@
 
   void test_visitFieldFormalParameter_functionTyped() {
     String parameterName = "p";
-    FieldFormalParameter formalParameter = AstFactory.fieldFormalParameter(
+    FieldFormalParameter formalParameter = AstTestFactory.fieldFormalParameter(
         null,
         null,
         parameterName,
-        AstFactory
-            .formalParameterList([AstFactory.simpleFormalParameter3("a")]));
+        AstTestFactory
+            .formalParameterList([AstTestFactory.simpleFormalParameter3("a")]));
     ElementHolder holder = buildElementsForAst(formalParameter);
     List<ParameterElement> parameters = holder.parameters;
     expect(parameters, hasLength(1));
@@ -1682,9 +1695,9 @@
   void test_visitFormalParameterList() {
     String firstParameterName = "a";
     String secondParameterName = "b";
-    FormalParameterList parameterList = AstFactory.formalParameterList([
-      AstFactory.simpleFormalParameter3(firstParameterName),
-      AstFactory.simpleFormalParameter3(secondParameterName)
+    FormalParameterList parameterList = AstTestFactory.formalParameterList([
+      AstTestFactory.simpleFormalParameter3(firstParameterName),
+      AstTestFactory.simpleFormalParameter3(secondParameterName)
     ]);
     ElementHolder holder = buildElementsForAst(parameterList);
     List<ParameterElement> parameters = holder.parameters;
@@ -1696,12 +1709,12 @@
   void test_visitFunctionDeclaration_external() {
     // external f();
     String functionName = "f";
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
         null,
         null,
         functionName,
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList(), AstFactory.emptyFunctionBody()));
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.emptyFunctionBody()));
     declaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
 
@@ -1722,13 +1735,13 @@
   void test_visitFunctionDeclaration_getter() {
     // get f() {}
     String functionName = "f";
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
         null,
         Keyword.GET,
         functionName,
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
-    declaration.documentationComment = AstFactory.documentationComment(
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
+    declaration.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     declaration.endToken.offset = 80;
 
@@ -1757,13 +1770,13 @@
   void test_visitFunctionDeclaration_plain() {
     // T f() {}
     String functionName = "f";
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        AstFactory.typeName4('T'),
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        AstTestFactory.typeName4('T'),
         null,
         functionName,
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
-    declaration.documentationComment = AstFactory.documentationComment(
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
+    declaration.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     declaration.endToken.offset = 80;
 
@@ -1786,13 +1799,13 @@
   void test_visitFunctionDeclaration_setter() {
     // set f() {}
     String functionName = "f";
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
         null,
         Keyword.SET,
         functionName,
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
-    declaration.documentationComment = AstFactory.documentationComment(
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
+    declaration.documentationComment = AstTestFactory.documentationComment(
         [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     declaration.endToken.offset = 80;
 
@@ -1822,12 +1835,12 @@
     // f<E>() {}
     String functionName = 'f';
     String typeParameterName = 'E';
-    FunctionExpression expression = AstFactory.functionExpression3(
-        AstFactory.typeParameterList([typeParameterName]),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    FunctionDeclaration declaration =
-        AstFactory.functionDeclaration(null, null, functionName, expression);
+    FunctionExpression expression = AstTestFactory.functionExpression3(
+        AstTestFactory.typeParameterList([typeParameterName]),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        null, null, functionName, expression);
 
     ElementHolder holder = buildElementsForAst(declaration);
     List<FunctionElement> functions = holder.functions;
@@ -1850,14 +1863,14 @@
   void test_visitMethodDeclaration_abstract() {
     // m();
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.emptyFunctionBody());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.emptyFunctionBody());
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
     List<MethodElement> methods = holder.methods;
@@ -1917,14 +1930,14 @@
   void test_visitMethodDeclaration_external() {
     // external m();
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.emptyFunctionBody());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.emptyFunctionBody());
     methodDeclaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
 
@@ -1949,16 +1962,17 @@
   void test_visitMethodDeclaration_getter() {
     // get m() {}
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         Keyword.GET,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    methodDeclaration.documentationComment = AstFactory.documentationComment(
-        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    methodDeclaration.documentationComment = AstTestFactory
+        .documentationComment(
+            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     methodDeclaration.endToken.offset = 80;
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
@@ -1989,14 +2003,14 @@
   void test_visitMethodDeclaration_getter_abstract() {
     // get m();
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         Keyword.GET,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.emptyFunctionBody());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.emptyFunctionBody());
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
     List<FieldElement> fields = holder.fields;
@@ -2024,13 +2038,13 @@
   void test_visitMethodDeclaration_getter_external() {
     // external get m();
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration(
         null,
         null,
         Keyword.GET,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList());
     methodDeclaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
 
@@ -2060,16 +2074,17 @@
   void test_visitMethodDeclaration_minimal() {
     // T m() {}
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
-        AstFactory.typeName4('T'),
+        AstTestFactory.typeName4('T'),
         null,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    methodDeclaration.documentationComment = AstFactory.documentationComment(
-        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    methodDeclaration.documentationComment = AstTestFactory
+        .documentationComment(
+            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     methodDeclaration.endToken.offset = 80;
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
@@ -2095,15 +2110,15 @@
   void test_visitMethodDeclaration_operator() {
     // operator +(addend) {}
     String methodName = "+";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         Keyword.OPERATOR,
-        AstFactory.identifier3(methodName),
-        AstFactory
-            .formalParameterList([AstFactory.simpleFormalParameter3("addend")]),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(
+            [AstTestFactory.simpleFormalParameter3("addend")]),
+        AstTestFactory.blockFunctionBody2());
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
     List<MethodElement> methods = holder.methods;
@@ -2126,16 +2141,17 @@
   void test_visitMethodDeclaration_setter() {
     // set m() {}
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         Keyword.SET,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    methodDeclaration.documentationComment = AstFactory.documentationComment(
-        [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    methodDeclaration.documentationComment = AstTestFactory
+        .documentationComment(
+            [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
     methodDeclaration.endToken.offset = 80;
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
@@ -2168,14 +2184,14 @@
   void test_visitMethodDeclaration_setter_abstract() {
     // set m();
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         Keyword.SET,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.emptyFunctionBody());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.emptyFunctionBody());
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
     List<FieldElement> fields = holder.fields;
@@ -2204,13 +2220,13 @@
   void test_visitMethodDeclaration_setter_external() {
     // external m();
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration(
         null,
         null,
         Keyword.SET,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList());
     methodDeclaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
 
@@ -2241,14 +2257,14 @@
   void test_visitMethodDeclaration_static() {
     // static m() {}
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         Keyword.STATIC,
         null,
         null,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
     ElementHolder holder = buildElementsForAst(methodDeclaration);
     List<MethodElement> methods = holder.methods;
     expect(methods, hasLength(1));
@@ -2270,15 +2286,15 @@
   void test_visitMethodDeclaration_typeParameters() {
     // m<E>() {}
     String methodName = "m";
-    MethodDeclaration methodDeclaration = AstFactory.methodDeclaration2(
+    MethodDeclaration methodDeclaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    methodDeclaration.typeParameters = AstFactory.typeParameterList(['E']);
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    methodDeclaration.typeParameters = AstTestFactory.typeParameterList(['E']);
 
     ElementHolder holder = buildElementsForAst(methodDeclaration);
     List<MethodElement> methods = holder.methods;
@@ -2300,7 +2316,7 @@
 
   void test_visitTypeAlias_minimal() {
     String aliasName = "F";
-    TypeAlias typeAlias = AstFactory.typeAlias(null, aliasName, null, null);
+    TypeAlias typeAlias = AstTestFactory.typeAlias(null, aliasName, null, null);
     ElementHolder holder = buildElementsForAst(typeAlias);
     List<FunctionTypeAliasElement> aliases = holder.typeAliases;
     expect(aliases, hasLength(1));
@@ -2315,13 +2331,13 @@
     String aliasName = "F";
     String firstParameterName = "x";
     String secondParameterName = "y";
-    TypeAlias typeAlias = AstFactory.typeAlias(
+    TypeAlias typeAlias = AstTestFactory.typeAlias(
         null,
         aliasName,
-        AstFactory.typeParameterList(),
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3(firstParameterName),
-          AstFactory.simpleFormalParameter3(secondParameterName)
+        AstTestFactory.typeParameterList(),
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3(firstParameterName),
+          AstTestFactory.simpleFormalParameter3(secondParameterName)
         ]));
     typeAlias.beginToken.offset = 50;
     typeAlias.endToken.offset = 80;
@@ -2347,12 +2363,12 @@
     String aliasName = "F";
     String firstTypeParameterName = "A";
     String secondTypeParameterName = "B";
-    TypeAlias typeAlias = AstFactory.typeAlias(
+    TypeAlias typeAlias = AstTestFactory.typeAlias(
         null,
         aliasName,
-        AstFactory.typeParameterList(
+        AstTestFactory.typeParameterList(
             [firstTypeParameterName, secondTypeParameterName]),
-        AstFactory.formalParameterList());
+        AstTestFactory.formalParameterList());
     ElementHolder holder = buildElementsForAst(typeAlias);
     List<FunctionTypeAliasElement> aliases = holder.typeAliases;
     expect(aliases, hasLength(1));
@@ -2372,7 +2388,7 @@
 
   void test_visitTypeParameter() {
     String parameterName = "E";
-    TypeParameter typeParameter = AstFactory.typeParameter(parameterName);
+    TypeParameter typeParameter = AstTestFactory.typeParameter(parameterName);
     typeParameter.beginToken.offset = 50;
     ElementHolder holder = buildElementsForAst(typeParameter);
     List<TypeParameterElement> typeParameters = holder.typeParameters;
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 127ce4e..6229305 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -26,7 +26,7 @@
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
@@ -559,12 +559,12 @@
 
   void test_locate_InstanceCreationExpression_type_prefixedIdentifier() {
     // prepare: new pref.A()
-    SimpleIdentifier identifier = AstFactory.identifier3("A");
+    SimpleIdentifier identifier = AstTestFactory.identifier3("A");
     PrefixedIdentifier prefixedIdentifier =
-        AstFactory.identifier4("pref", identifier);
+        AstTestFactory.identifier4("pref", identifier);
     InstanceCreationExpression creation =
-        AstFactory.instanceCreationExpression2(
-            Keyword.NEW, AstFactory.typeName3(prefixedIdentifier));
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.NEW, AstTestFactory.typeName3(prefixedIdentifier));
     // set ClassElement
     ClassElement classElement = ElementFactory.classElement2("A");
     identifier.staticElement = classElement;
@@ -579,10 +579,10 @@
 
   void test_locate_InstanceCreationExpression_type_simpleIdentifier() {
     // prepare: new A()
-    SimpleIdentifier identifier = AstFactory.identifier3("A");
+    SimpleIdentifier identifier = AstTestFactory.identifier3("A");
     InstanceCreationExpression creation =
-        AstFactory.instanceCreationExpression2(
-            Keyword.NEW, AstFactory.typeName3(identifier));
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.NEW, AstTestFactory.typeName3(identifier));
     // set ClassElement
     ClassElement classElement = ElementFactory.classElement2("A");
     identifier.staticElement = classElement;
@@ -797,8 +797,8 @@
     String firstName = "ONE";
     String secondName = "TWO";
     String thirdName = "THREE";
-    EnumDeclaration enumDeclaration =
-        AstFactory.enumDeclaration2("E", [firstName, secondName, thirdName]);
+    EnumDeclaration enumDeclaration = AstTestFactory
+        .enumDeclaration2("E", [firstName, secondName, thirdName]);
 
     ClassElement enumElement = _buildElement(enumDeclaration);
     List<FieldElement> fields = enumElement.fields;
@@ -829,8 +829,8 @@
   void test_visitEnumDeclaration_single() {
     String firstName = "ONE";
     EnumDeclaration enumDeclaration =
-        AstFactory.enumDeclaration2("E", [firstName]);
-    enumDeclaration.constants[0].documentationComment = AstFactory
+        AstTestFactory.enumDeclaration2("E", [firstName]);
+    enumDeclaration.constants[0].documentationComment = AstTestFactory
         .documentationComment(
             [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
 
@@ -967,7 +967,7 @@
         new ErrorReporter(listener, firstType.element.source);
     reporter.reportTypeErrorForNode(
         StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-        AstFactory.identifier3("x"),
+        AstTestFactory.identifier3("x"),
         [firstType, secondType]);
     AnalysisError error = listener.errors[0];
     expect(error.message.indexOf("(") < 0, isTrue);
@@ -982,7 +982,7 @@
         new ErrorReporter(listener, firstType.element.source);
     reporter.reportTypeErrorForNode(
         StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-        AstFactory.identifier3("x"),
+        AstTestFactory.identifier3("x"),
         [firstType, secondType]);
     AnalysisError error = listener.errors[0];
     expect(error.message.indexOf("(") >= 0, isTrue);
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index fe3c66a..ffbe349 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -21,7 +21,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -156,11 +156,11 @@
             "override", true, false, overrideClassElement.type);
     {
       ClassElement deprecatedElement = provider.deprecatedType.element;
-      InstanceCreationExpression initializer = AstFactory
+      InstanceCreationExpression initializer = AstTestFactory
           .instanceCreationExpression2(
               Keyword.CONST,
-              AstFactory.typeName(deprecatedElement),
-              [AstFactory.string2('next release')]);
+              AstTestFactory.typeName(deprecatedElement),
+              [AstTestFactory.string2('next release')]);
       ConstructorElement constructor = deprecatedElement.constructors.single;
       initializer.staticElement = constructor;
       initializer.constructorName.staticElement = constructor;
@@ -177,13 +177,13 @@
       proxyTopLevelVariableElt
     ];
     LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
-        coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
+        coreContext, AstTestFactory.libraryIdentifier2(["dart", "core"]));
     coreLibrary.definingCompilationUnit = coreUnit;
     //
     // dart:async
     //
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
-        coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
+        coreContext, AstTestFactory.libraryIdentifier2(["dart", "async"]));
     CompilationUnitElementImpl asyncUnit =
         new CompilationUnitElementImpl("async.dart");
     Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
@@ -328,8 +328,8 @@
             "document", false, true, htmlDocumentElement.type);
     htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
     htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
-    LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
-        coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"]));
+    LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(coreContext,
+        AstTestFactory.libraryIdentifier2(["dart", "dom", "html"]));
     htmlLibrary.definingCompilationUnit = htmlUnit;
     //
     // dart:math
@@ -390,7 +390,7 @@
     ];
     mathUnit.types = <ClassElement>[randomElement];
     LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
-        coreContext, AstFactory.libraryIdentifier2(["dart", "math"]));
+        coreContext, AstTestFactory.libraryIdentifier2(["dart", "math"]));
     mathLibrary.definingCompilationUnit = mathUnit;
     //
     // Set empty sources for the rest of the libraries.
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 90acbe9..9824236 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -14,7 +14,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/source/source_resource.dart';
@@ -330,8 +330,8 @@
     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"])
+    ExportDirective directive = AstTestFactory.exportDirective2(null, [
+      AstTestFactory.hideCombinator2(["A"])
     ]);
     _resolveNode(directive);
     _listener.assertNoErrors();
@@ -346,8 +346,8 @@
     fail("Not yet tested");
     // Need to set up the imported library so that the identifier can be
     // resolved.
-    ImportDirective directive = AstFactory.importDirective3(null, null, [
-      AstFactory.showCombinator2(["A"])
+    ImportDirective directive = AstTestFactory.importDirective3(null, null, [
+      AstTestFactory.showCombinator2(["A"])
     ]);
     _resolveNode(directive);
     _listener.assertNoErrors();
@@ -361,9 +361,10 @@
     _definingLibrary.imports = <ImportElement>[
       ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
     ];
-    ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
-      AstFactory.showCombinator2(["A"]),
-      AstFactory.hideCombinator2(["B"])
+    ImportDirective directive =
+        AstTestFactory.importDirective3(null, prefixName, [
+      AstTestFactory.showCombinator2(["A"]),
+      AstTestFactory.hideCombinator2(["B"])
     ]);
     _resolveNode(directive);
     _listener.assertNoErrors();
@@ -409,20 +410,20 @@
     // D a;
     // a[i];
     //
-    SimpleIdentifier array = AstFactory.identifier3("a");
+    SimpleIdentifier array = AstTestFactory.identifier3("a");
     array.staticType = classD.type;
     IndexExpression expression =
-        AstFactory.indexExpression(array, AstFactory.identifier3("i"));
+        AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
     expect(_resolveIndexExpression(expression), same(operator));
     _listener.assertNoErrors();
   }
 
   void test_visitAssignmentExpression_compound() {
     InterfaceType intType = _typeProvider.intType;
-    SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
+    SimpleIdentifier leftHandSide = AstTestFactory.identifier3("a");
     leftHandSide.staticType = intType;
-    AssignmentExpression assignment = AstFactory.assignmentExpression(
-        leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
+    AssignmentExpression assignment = AstTestFactory.assignmentExpression(
+        leftHandSide, TokenType.PLUS_EQ, AstTestFactory.integer(1));
     _resolveNode(assignment);
     expect(
         assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
@@ -430,8 +431,10 @@
   }
 
   void test_visitAssignmentExpression_simple() {
-    AssignmentExpression expression = AstFactory.assignmentExpression(
-        AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
+    AssignmentExpression expression = AstTestFactory.assignmentExpression(
+        AstTestFactory.identifier3("x"),
+        TokenType.EQ,
+        AstTestFactory.integer(0));
     _resolveNode(expression);
     expect(expression.staticElement, isNull);
     _listener.assertNoErrors();
@@ -442,10 +445,10 @@
     // var j;
     // i == j
     InterfaceType stringType = _typeProvider.stringType;
-    SimpleIdentifier left = AstFactory.identifier3("i");
+    SimpleIdentifier left = AstTestFactory.identifier3("i");
     left.staticType = stringType;
-    BinaryExpression expression = AstFactory.binaryExpression(
-        left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
+    BinaryExpression expression = AstTestFactory.binaryExpression(
+        left, TokenType.BANG_EQ, AstTestFactory.identifier3("j"));
     _resolveNode(expression);
     var stringElement = stringType.element;
     expect(expression.staticElement, isNotNull);
@@ -462,10 +465,10 @@
     // var j;
     // i == j
     InterfaceType stringType = _typeProvider.stringType;
-    SimpleIdentifier left = AstFactory.identifier3("i");
+    SimpleIdentifier left = AstTestFactory.identifier3("i");
     left.staticType = stringType;
-    BinaryExpression expression = AstFactory.binaryExpression(
-        left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
+    BinaryExpression expression = AstTestFactory.binaryExpression(
+        left, TokenType.EQ_EQ, AstTestFactory.identifier3("j"));
     _resolveNode(expression);
     var stringElement = stringType.element;
     expect(
@@ -481,10 +484,10 @@
     // var j;
     // i + j
     InterfaceType numType = _typeProvider.numType;
-    SimpleIdentifier left = AstFactory.identifier3("i");
+    SimpleIdentifier left = AstTestFactory.identifier3("i");
     left.staticType = numType;
-    BinaryExpression expression = AstFactory.binaryExpression(
-        left, TokenType.PLUS, AstFactory.identifier3("j"));
+    BinaryExpression expression = AstTestFactory.binaryExpression(
+        left, TokenType.PLUS, AstTestFactory.identifier3("j"));
     _resolveNode(expression);
     expect(expression.staticElement, getMethod(numType, "+"));
     expect(expression.propagatedElement, isNull);
@@ -496,10 +499,10 @@
     // var j;
     // i + j
     InterfaceType numType = _typeProvider.numType;
-    SimpleIdentifier left = AstFactory.identifier3("i");
+    SimpleIdentifier left = AstTestFactory.identifier3("i");
     left.propagatedType = numType;
-    BinaryExpression expression = AstFactory.binaryExpression(
-        left, TokenType.PLUS, AstFactory.identifier3("j"));
+    BinaryExpression expression = AstTestFactory.binaryExpression(
+        left, TokenType.PLUS, AstTestFactory.identifier3("j"));
     _resolveNode(expression);
     expect(expression.staticElement, isNull);
     expect(expression.propagatedElement, getMethod(numType, "+"));
@@ -512,11 +515,11 @@
     // }
     String label = "loop";
     LabelElementImpl labelElement = new LabelElementImpl.forNode(
-        AstFactory.identifier3(label), false, false);
-    BreakStatement breakStatement = AstFactory.breakStatement2(label);
-    Expression condition = AstFactory.booleanLiteral(true);
+        AstTestFactory.identifier3(label), false, false);
+    BreakStatement breakStatement = AstTestFactory.breakStatement2(label);
+    Expression condition = AstTestFactory.booleanLiteral(true);
     WhileStatement whileStatement =
-        AstFactory.whileStatement(condition, breakStatement);
+        AstTestFactory.whileStatement(condition, breakStatement);
     expect(_resolveBreak(breakStatement, labelElement, whileStatement),
         same(labelElement));
     expect(breakStatement.target, same(whileStatement));
@@ -524,7 +527,7 @@
   }
 
   void test_visitBreakStatement_withoutLabel() {
-    BreakStatement statement = AstFactory.breakStatement();
+    BreakStatement statement = AstTestFactory.breakStatement();
     _resolveStatement(statement, null, null);
     _listener.assertNoErrors();
   }
@@ -542,7 +545,7 @@
     _visitor.nameScope = new EnclosedScope(null)
       ..defineNameWithoutChecking('A', classA);
     // prepare "A.p"
-    PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
+    PrefixedIdentifier prefixed = AstTestFactory.identifier5('A', 'p');
     CommentReference commentReference = new CommentReference(null, prefixed);
     // resolve
     _resolveNode(commentReference);
@@ -561,7 +564,7 @@
     _visitor.nameScope = new EnclosedScope(null)
       ..defineNameWithoutChecking('A', classA);
     // prepare "A.m"
-    PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
+    PrefixedIdentifier prefixed = AstTestFactory.identifier5('A', 'm');
     CommentReference commentReference = new CommentReference(null, prefixed);
     // resolve
     _resolveNode(commentReference);
@@ -580,7 +583,7 @@
     _visitor.nameScope = new EnclosedScope(null)
       ..defineNameWithoutChecking('A', classA);
     // prepare "A.=="
-    PrefixedIdentifier prefixed = AstFactory.identifier5('A', '==');
+    PrefixedIdentifier prefixed = AstTestFactory.identifier5('A', '==');
     CommentReference commentReference = new CommentReference(null, prefixed);
     // resolve
     _resolveNode(commentReference);
@@ -595,8 +598,8 @@
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
-    ConstructorName name = AstFactory.constructorName(
-        AstFactory.typeName(classA), constructorName);
+    ConstructorName name = AstTestFactory.constructorName(
+        AstTestFactory.typeName(classA), constructorName);
     _resolveNode(name);
     expect(name.staticElement, same(constructor));
     _listener.assertNoErrors();
@@ -608,8 +611,8 @@
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
-    ConstructorName name = AstFactory.constructorName(
-        AstFactory.typeName(classA), constructorName);
+    ConstructorName name = AstTestFactory.constructorName(
+        AstTestFactory.typeName(classA), constructorName);
     _resolveNode(name);
     expect(name.staticElement, same(constructor));
     _listener.assertNoErrors();
@@ -621,11 +624,12 @@
     // }
     String label = "loop";
     LabelElementImpl labelElement = new LabelElementImpl.forNode(
-        AstFactory.identifier3(label), false, false);
-    ContinueStatement continueStatement = AstFactory.continueStatement(label);
-    Expression condition = AstFactory.booleanLiteral(true);
+        AstTestFactory.identifier3(label), false, false);
+    ContinueStatement continueStatement =
+        AstTestFactory.continueStatement(label);
+    Expression condition = AstTestFactory.booleanLiteral(true);
     WhileStatement whileStatement =
-        AstFactory.whileStatement(condition, continueStatement);
+        AstTestFactory.whileStatement(condition, continueStatement);
     expect(_resolveContinue(continueStatement, labelElement, whileStatement),
         same(labelElement));
     expect(continueStatement.target, same(whileStatement));
@@ -633,7 +637,7 @@
   }
 
   void test_visitContinueStatement_withoutLabel() {
-    ContinueStatement statement = AstFactory.continueStatement();
+    ContinueStatement statement = AstTestFactory.continueStatement();
     _resolveStatement(statement, null, null);
     _listener.assertNoErrors();
   }
@@ -644,9 +648,9 @@
     EnumElementImpl enumElement =
         ElementFactory.enumElement(_typeProvider, ('E'));
     compilationUnitElement.enums = <ClassElement>[enumElement];
-    EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
+    EnumDeclaration enumNode = AstTestFactory.enumDeclaration2('E', []);
     Annotation annotationNode =
-        AstFactory.annotation(AstFactory.identifier3('a'));
+        AstTestFactory.annotation(AstTestFactory.identifier3('a'));
     annotationNode.element = ElementFactory.classElement2('A');
     annotationNode.elementAnnotation =
         new ElementAnnotationImpl(compilationUnitElement);
@@ -660,7 +664,7 @@
   }
 
   void test_visitExportDirective_noCombinators() {
-    ExportDirective directive = AstFactory.exportDirective2(null);
+    ExportDirective directive = AstTestFactory.exportDirective2(null);
     directive.element = ElementFactory
         .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
     _resolveNode(directive);
@@ -675,7 +679,7 @@
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.fields = <FieldElement>[fieldElement];
     FieldFormalParameter parameter =
-        AstFactory.fieldFormalParameter2(fieldName);
+        AstTestFactory.fieldFormalParameter2(fieldName);
     FieldFormalParameterElementImpl parameterElement =
         ElementFactory.fieldFormalParameter(parameter.identifier);
     parameterElement.field = fieldElement;
@@ -686,7 +690,7 @@
   }
 
   void test_visitImportDirective_noCombinators_noPrefix() {
-    ImportDirective directive = AstFactory.importDirective3(null, null);
+    ImportDirective directive = AstTestFactory.importDirective3(null, null);
     directive.element = ElementFactory.importFor(
         ElementFactory.library(_definingLibrary.context, "lib"), null);
     _resolveNode(directive);
@@ -699,16 +703,17 @@
         ElementFactory.library(_definingLibrary.context, "lib"),
         ElementFactory.prefix(prefixName));
     _definingLibrary.imports = <ImportElement>[importElement];
-    ImportDirective directive = AstFactory.importDirective3(null, prefixName);
+    ImportDirective directive =
+        AstTestFactory.importDirective3(null, prefixName);
     directive.element = importElement;
     _resolveNode(directive);
     _listener.assertNoErrors();
   }
 
   void test_visitImportDirective_withCombinators() {
-    ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
+    ShowCombinator combinator = AstTestFactory.showCombinator2(["A", "B", "C"]);
     ImportDirective directive =
-        AstFactory.importDirective3(null, null, [combinator]);
+        AstTestFactory.importDirective3(null, null, [combinator]);
     LibraryElementImpl library =
         ElementFactory.library(_definingLibrary.context, "lib");
     TopLevelVariableElementImpl varA =
@@ -740,10 +745,10 @@
     MethodElement getter =
         ElementFactory.methodElement("[]", intType, [intType]);
     classA.methods = <MethodElement>[getter];
-    SimpleIdentifier array = AstFactory.identifier3("a");
+    SimpleIdentifier array = AstTestFactory.identifier3("a");
     array.staticType = classA.type;
     IndexExpression expression =
-        AstFactory.indexExpression(array, AstFactory.identifier3("i"));
+        AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
     expect(_resolveIndexExpression(expression), same(getter));
     _listener.assertNoErrors();
   }
@@ -754,12 +759,12 @@
     MethodElement setter =
         ElementFactory.methodElement("[]=", intType, [intType]);
     classA.methods = <MethodElement>[setter];
-    SimpleIdentifier array = AstFactory.identifier3("a");
+    SimpleIdentifier array = AstTestFactory.identifier3("a");
     array.staticType = classA.type;
     IndexExpression expression =
-        AstFactory.indexExpression(array, AstFactory.identifier3("i"));
-    AstFactory.assignmentExpression(
-        expression, TokenType.EQ, AstFactory.integer(0));
+        AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
+    AstTestFactory.assignmentExpression(
+        expression, TokenType.EQ, AstTestFactory.integer(0));
     expect(_resolveIndexExpression(expression), same(setter));
     _listener.assertNoErrors();
   }
@@ -770,11 +775,11 @@
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
-    ConstructorName name = AstFactory.constructorName(
-        AstFactory.typeName(classA), constructorName);
+    ConstructorName name = AstTestFactory.constructorName(
+        AstTestFactory.typeName(classA), constructorName);
     name.staticElement = constructor;
     InstanceCreationExpression creation =
-        AstFactory.instanceCreationExpression(Keyword.NEW, name);
+        AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
     _resolveNode(creation);
     expect(creation.staticElement, same(constructor));
     _listener.assertNoErrors();
@@ -786,11 +791,11 @@
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
-    ConstructorName name = AstFactory.constructorName(
-        AstFactory.typeName(classA), constructorName);
+    ConstructorName name = AstTestFactory.constructorName(
+        AstTestFactory.typeName(classA), constructorName);
     name.staticElement = constructor;
     InstanceCreationExpression creation =
-        AstFactory.instanceCreationExpression(Keyword.NEW, name);
+        AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
     _resolveNode(creation);
     expect(creation.staticElement, same(constructor));
     _listener.assertNoErrors();
@@ -805,13 +810,13 @@
     ParameterElement parameter = ElementFactory.namedParameter(parameterName);
     constructor.parameters = <ParameterElement>[parameter];
     classA.constructors = <ConstructorElement>[constructor];
-    ConstructorName name = AstFactory.constructorName(
-        AstFactory.typeName(classA), constructorName);
+    ConstructorName name = AstTestFactory.constructorName(
+        AstTestFactory.typeName(classA), constructorName);
     name.staticElement = constructor;
-    InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
-        Keyword.NEW,
-        name,
-        [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
+    InstanceCreationExpression creation = AstTestFactory
+        .instanceCreationExpression(Keyword.NEW, name, [
+      AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
+    ]);
     _resolveNode(creation);
     expect(creation.staticElement, same(constructor));
     expect(
@@ -825,10 +830,11 @@
 
   void test_visitMethodInvocation() {
     InterfaceType numType = _typeProvider.numType;
-    SimpleIdentifier left = AstFactory.identifier3("i");
+    SimpleIdentifier left = AstTestFactory.identifier3("i");
     left.staticType = numType;
     String methodName = "abs";
-    MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
+    MethodInvocation invocation =
+        AstTestFactory.methodInvocation(left, methodName);
     _resolveNode(invocation);
     expect(invocation.methodName.staticElement,
         same(getMethod(numType, methodName)));
@@ -843,10 +849,12 @@
     ParameterElement parameter = ElementFactory.namedParameter(parameterName);
     method.parameters = <ParameterElement>[parameter];
     classA.methods = <MethodElement>[method];
-    SimpleIdentifier left = AstFactory.identifier3("i");
+    SimpleIdentifier left = AstTestFactory.identifier3("i");
     left.staticType = classA.type;
-    MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
-        [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
+    MethodInvocation invocation = AstTestFactory.methodInvocation(
+        left, methodName, [
+      AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
+    ]);
     _resolveNode(invocation);
     expect(invocation.methodName.staticElement, same(method));
     expect(
@@ -860,10 +868,10 @@
 
   void test_visitPostfixExpression() {
     InterfaceType numType = _typeProvider.numType;
-    SimpleIdentifier operand = AstFactory.identifier3("i");
+    SimpleIdentifier operand = AstTestFactory.identifier3("i");
     operand.staticType = numType;
     PostfixExpression expression =
-        AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
+        AstTestFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
     _resolveNode(expression);
     expect(expression.staticElement, getMethod(numType, "+"));
     _listener.assertNoErrors();
@@ -871,13 +879,13 @@
 
   void test_visitPrefixedIdentifier_dynamic() {
     DartType dynamicType = _typeProvider.dynamicType;
-    SimpleIdentifier target = AstFactory.identifier3("a");
+    SimpleIdentifier target = AstTestFactory.identifier3("a");
     VariableElementImpl variable = ElementFactory.localVariableElement(target);
     variable.type = dynamicType;
     target.staticElement = variable;
     target.staticType = dynamicType;
     PrefixedIdentifier identifier =
-        AstFactory.identifier(target, AstFactory.identifier3("b"));
+        AstTestFactory.identifier(target, AstTestFactory.identifier3("b"));
     _resolveNode(identifier);
     expect(identifier.staticElement, isNull);
     expect(identifier.identifier.staticElement, isNull);
@@ -890,13 +898,13 @@
     PropertyAccessorElement getter =
         ElementFactory.getterElement(getterName, false, _typeProvider.intType);
     classA.accessors = <PropertyAccessorElement>[getter];
-    SimpleIdentifier target = AstFactory.identifier3("a");
+    SimpleIdentifier target = AstTestFactory.identifier3("a");
     VariableElementImpl variable = ElementFactory.localVariableElement(target);
     variable.type = classA.type;
     target.staticElement = variable;
     target.staticType = classA.type;
-    PrefixedIdentifier identifier =
-        AstFactory.identifier(target, AstFactory.identifier3(getterName));
+    PrefixedIdentifier identifier = AstTestFactory.identifier(
+        target, AstTestFactory.identifier3(getterName));
     _resolveNode(identifier);
     expect(identifier.staticElement, same(getter));
     expect(identifier.identifier.staticElement, same(getter));
@@ -913,11 +921,11 @@
         ElementFactory.setterElement(propName, false, _typeProvider.intType);
     classA.accessors = <PropertyAccessorElement>[getter, setter];
     // prepare "A.m"
-    SimpleIdentifier target = AstFactory.identifier3("A");
+    SimpleIdentifier target = AstTestFactory.identifier3("A");
     target.staticElement = classA;
     target.staticType = classA.type;
     PrefixedIdentifier identifier =
-        AstFactory.identifier(target, AstFactory.identifier3(propName));
+        AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
     // resolve
     _resolveNode(identifier);
     expect(identifier.staticElement, same(getter));
@@ -933,13 +941,13 @@
         ElementFactory.methodElement("m", _typeProvider.intType);
     classA.methods = <MethodElement>[method];
     // prepare "A.m"
-    SimpleIdentifier target = AstFactory.identifier3("A");
+    SimpleIdentifier target = AstTestFactory.identifier3("A");
     target.staticElement = classA;
     target.staticType = classA.type;
     PrefixedIdentifier identifier =
-        AstFactory.identifier(target, AstFactory.identifier3(propName));
-    AstFactory.assignmentExpression(
-        identifier, TokenType.EQ, AstFactory.nullLiteral());
+        AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
+    AstTestFactory.assignmentExpression(
+        identifier, TokenType.EQ, AstTestFactory.nullLiteral());
     // resolve
     _resolveNode(identifier);
     expect(identifier.staticElement, same(method));
@@ -957,13 +965,13 @@
         ElementFactory.setterElement(propName, false, _typeProvider.intType);
     classA.accessors = <PropertyAccessorElement>[getter, setter];
     // prepare "A.b = null"
-    SimpleIdentifier target = AstFactory.identifier3("A");
+    SimpleIdentifier target = AstTestFactory.identifier3("A");
     target.staticElement = classA;
     target.staticType = classA.type;
     PrefixedIdentifier identifier =
-        AstFactory.identifier(target, AstFactory.identifier3(propName));
-    AstFactory.assignmentExpression(
-        identifier, TokenType.EQ, AstFactory.nullLiteral());
+        AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
+    AstTestFactory.assignmentExpression(
+        identifier, TokenType.EQ, AstTestFactory.nullLiteral());
     // resolve
     _resolveNode(identifier);
     expect(identifier.staticElement, same(setter));
@@ -973,10 +981,10 @@
 
   void test_visitPrefixExpression() {
     InterfaceType numType = _typeProvider.numType;
-    SimpleIdentifier operand = AstFactory.identifier3("i");
+    SimpleIdentifier operand = AstTestFactory.identifier3("i");
     operand.staticType = numType;
     PrefixExpression expression =
-        AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
+        AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
     _resolveNode(expression);
     expect(expression.staticElement, getMethod(numType, "+"));
     _listener.assertNoErrors();
@@ -988,9 +996,9 @@
     PropertyAccessorElement getter =
         ElementFactory.getterElement(getterName, false, _typeProvider.intType);
     classA.accessors = <PropertyAccessorElement>[getter];
-    SimpleIdentifier target = AstFactory.identifier3("a");
+    SimpleIdentifier target = AstTestFactory.identifier3("a");
     target.staticType = classA.type;
-    PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
+    PropertyAccess access = AstTestFactory.propertyAccess2(target, getterName);
     _resolveNode(access);
     expect(access.propertyName.staticElement, same(getter));
     _listener.assertNoErrors();
@@ -1010,17 +1018,17 @@
     PropertyAccessorElement getter =
         ElementFactory.getterElement(getterName, false, _typeProvider.intType);
     classA.accessors = <PropertyAccessorElement>[getter];
-    SuperExpression target = AstFactory.superExpression();
+    SuperExpression target = AstTestFactory.superExpression();
     target.staticType = ElementFactory.classElement("B", classA.type).type;
-    PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
-    AstFactory.methodDeclaration2(
+    PropertyAccess access = AstTestFactory.propertyAccess2(target, getterName);
+    AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.expressionFunctionBody(access));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.expressionFunctionBody(access));
     _resolveNode(access);
     expect(access.propertyName.staticElement, same(getter));
     _listener.assertNoErrors();
@@ -1032,11 +1040,11 @@
     PropertyAccessorElement setter =
         ElementFactory.setterElement(setterName, false, _typeProvider.intType);
     classA.accessors = <PropertyAccessorElement>[setter];
-    ThisExpression target = AstFactory.thisExpression();
+    ThisExpression target = AstTestFactory.thisExpression();
     target.staticType = classA.type;
-    PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
-    AstFactory.assignmentExpression(
-        access, TokenType.EQ, AstFactory.integer(0));
+    PropertyAccess access = AstTestFactory.propertyAccess2(target, setterName);
+    AstTestFactory.assignmentExpression(
+        access, TokenType.EQ, AstTestFactory.integer(0));
     _resolveNode(access);
     expect(access.propertyName.staticElement, same(setter));
     _listener.assertNoErrors();
@@ -1045,14 +1053,14 @@
   void test_visitSimpleIdentifier_classScope() {
     InterfaceType doubleType = _typeProvider.doubleType;
     String fieldName = "NAN";
-    SimpleIdentifier node = AstFactory.identifier3(fieldName);
+    SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
     _resolveInClass(node, doubleType.element);
     expect(node.staticElement, getGetter(doubleType, fieldName));
     _listener.assertNoErrors();
   }
 
   void test_visitSimpleIdentifier_dynamic() {
-    SimpleIdentifier node = AstFactory.identifier3("dynamic");
+    SimpleIdentifier node = AstTestFactory.identifier3("dynamic");
     _resolveIdentifier(node);
     expect(node.staticElement, same(_typeProvider.dynamicType.element));
     expect(node.staticType, same(_typeProvider.typeType));
@@ -1060,7 +1068,7 @@
   }
 
   void test_visitSimpleIdentifier_lexicalScope() {
-    SimpleIdentifier node = AstFactory.identifier3("i");
+    SimpleIdentifier node = AstTestFactory.identifier3("i");
     VariableElementImpl element = ElementFactory.localVariableElement(node);
     expect(_resolveIdentifier(node, [element]), same(element));
     _listener.assertNoErrors();
@@ -1074,8 +1082,9 @@
         ElementFactory.fieldElement(fieldName, false, false, false, intType);
     classA.fields = <FieldElement>[field];
     classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
-    SimpleIdentifier node = AstFactory.identifier3(fieldName);
-    AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
+    SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
+    AstTestFactory.assignmentExpression(
+        node, TokenType.EQ, AstTestFactory.integer(0));
     _resolveInClass(node, classA);
     Element element = node.staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
@@ -1095,9 +1104,9 @@
         ElementFactory.constructorElement2(subclass, null);
     subclass.constructors = <ConstructorElement>[subConstructor];
     SuperConstructorInvocation invocation =
-        AstFactory.superConstructorInvocation();
-    AstFactory.classDeclaration(null, 'C', null, null, null, null, [
-      AstFactory.constructorDeclaration(null, 'C', null, [invocation])
+        AstTestFactory.superConstructorInvocation();
+    AstTestFactory.classDeclaration(null, 'C', null, null, null, null, [
+      AstTestFactory.constructorDeclaration(null, 'C', null, [invocation])
     ]);
     _resolveInClass(invocation, subclass);
     expect(invocation.staticElement, superConstructor);
@@ -1117,12 +1126,12 @@
     ConstructorElementImpl subConstructor =
         ElementFactory.constructorElement2(subclass, null);
     subclass.constructors = <ConstructorElement>[subConstructor];
-    SuperConstructorInvocation invocation = AstFactory
+    SuperConstructorInvocation invocation = AstTestFactory
         .superConstructorInvocation([
-      AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
+      AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
     ]);
-    AstFactory.classDeclaration(null, 'C', null, null, null, null, [
-      AstFactory.constructorDeclaration(null, 'C', null, [invocation])
+    AstTestFactory.classDeclaration(null, 'C', null, null, null, null, [
+      AstTestFactory.constructorDeclaration(null, 'C', null, [invocation])
     ]);
     _resolveInClass(invocation, subclass);
     expect(invocation.staticElement, superConstructor);
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index e6ec9d96..8bcd6bc 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -483,6 +483,7 @@
     return null;
   }
 
+  @deprecated
   @override
   Object/*=V*/ getConfigurationData/*<V>*/(ResultDescriptor/*<V>*/ key) {
     fail("Unexpected invocation of getConfigurationData");
@@ -685,6 +686,7 @@
     fail("Unexpected invocation of setChangedContents");
   }
 
+  @deprecated
   @override
   void setConfigurationData(ResultDescriptor key, Object data) {
     fail("Unexpected invocation of setConfigurationData");
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 5bfd2a9..381d3c2 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -23,7 +23,7 @@
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/task/dart.dart';
@@ -2255,7 +2255,7 @@
 
   void test_scopeFor_notInCompilationUnit() {
     try {
-      _scopeFor(AstFactory.identifier3("x"));
+      _scopeFor(AstTestFactory.identifier3("x"));
       fail("Expected AnalysisException");
     } on AnalysisException {
       // Expected
@@ -2273,7 +2273,7 @@
 
   void test_scopeFor_unresolved() {
     try {
-      _scopeFor(AstFactory.compilationUnit());
+      _scopeFor(AstTestFactory.compilationUnit());
       fail("Expected AnalysisException");
     } on AnalysisException {
       // Expected
@@ -2283,8 +2283,8 @@
   ClassDeclaration _createResolvedClassDeclaration() {
     CompilationUnit unit = _createResolvedCompilationUnit();
     String className = "C";
-    ClassDeclaration classNode = AstFactory.classDeclaration(
-        null, className, AstFactory.typeParameterList(), null, null, null);
+    ClassDeclaration classNode = AstTestFactory.classDeclaration(
+        null, className, AstTestFactory.typeParameterList(), null, null, null);
     unit.declarations.add(classNode);
     ClassElement classElement = ElementFactory.classElement2(className);
     classNode.name.staticElement = classElement;
@@ -2297,8 +2297,8 @@
   ClassTypeAlias _createResolvedClassTypeAlias() {
     CompilationUnit unit = _createResolvedCompilationUnit();
     String className = "C";
-    ClassTypeAlias classNode = AstFactory.classTypeAlias(
-        className, AstFactory.typeParameterList(), null, null, null, null);
+    ClassTypeAlias classNode = AstTestFactory.classTypeAlias(
+        className, AstTestFactory.typeParameterList(), null, null, null, null);
     unit.declarations.add(classNode);
     ClassElement classElement = ElementFactory.classElement2(className);
     classNode.name.staticElement = classElement;
@@ -2309,7 +2309,7 @@
   }
 
   CompilationUnit _createResolvedCompilationUnit() {
-    CompilationUnit unit = AstFactory.compilationUnit();
+    CompilationUnit unit = AstTestFactory.compilationUnit();
     LibraryElementImpl library =
         ElementFactory.library(AnalysisContextFactory.contextWithCore(), "lib");
     unit.element = library.definingCompilationUnit;
@@ -2319,11 +2319,12 @@
   ConstructorDeclaration _createResolvedConstructorDeclaration() {
     ClassDeclaration classNode = _createResolvedClassDeclaration();
     String constructorName = "f";
-    ConstructorDeclaration constructorNode = AstFactory.constructorDeclaration(
-        AstFactory.identifier3(constructorName),
-        null,
-        AstFactory.formalParameterList(),
-        null);
+    ConstructorDeclaration constructorNode =
+        AstTestFactory.constructorDeclaration(
+            AstTestFactory.identifier3(constructorName),
+            null,
+            AstTestFactory.formalParameterList(),
+            null);
     classNode.members.add(constructorNode);
     ConstructorElement constructorElement =
         ElementFactory.constructorElement2(classNode.element, null);
@@ -2337,8 +2338,8 @@
   FunctionDeclaration _createResolvedFunctionDeclaration() {
     CompilationUnit unit = _createResolvedCompilationUnit();
     String functionName = "f";
-    FunctionDeclaration functionNode = AstFactory.functionDeclaration(
-        null, null, functionName, AstFactory.functionExpression());
+    FunctionDeclaration functionNode = AstTestFactory.functionDeclaration(
+        null, null, functionName, AstTestFactory.functionExpression());
     unit.declarations.add(functionNode);
     FunctionElement functionElement =
         ElementFactory.functionElement(functionName);
@@ -2351,11 +2352,11 @@
 
   FunctionTypeAlias _createResolvedFunctionTypeAlias() {
     CompilationUnit unit = _createResolvedCompilationUnit();
-    FunctionTypeAlias aliasNode = AstFactory.typeAlias(
-        AstFactory.typeName4("A"),
+    FunctionTypeAlias aliasNode = AstTestFactory.typeAlias(
+        AstTestFactory.typeName4("A"),
         "F",
-        AstFactory.typeParameterList(),
-        AstFactory.formalParameterList());
+        AstTestFactory.typeParameterList(),
+        AstTestFactory.formalParameterList());
     unit.declarations.add(aliasNode);
     SimpleIdentifier aliasName = aliasNode.name;
     FunctionTypeAliasElement aliasElement =
@@ -2369,13 +2370,13 @@
   MethodDeclaration _createResolvedMethodDeclaration() {
     ClassDeclaration classNode = _createResolvedClassDeclaration();
     String methodName = "f";
-    MethodDeclaration methodNode = AstFactory.methodDeclaration(
+    MethodDeclaration methodNode = AstTestFactory.methodDeclaration(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3(methodName),
-        AstFactory.formalParameterList());
+        AstTestFactory.identifier3(methodName),
+        AstTestFactory.formalParameterList());
     classNode.members.add(methodNode);
     MethodElement methodElement =
         ElementFactory.methodElement(methodName, null);
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index 1216101..9cae945 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -16,7 +16,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -399,11 +399,11 @@
     MethodElementImpl methodM1 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a1"));
     parameter1.type = _typeProvider.intType;
     parameter1.parameterKind = ParameterKind.REQUIRED;
     ParameterElementImpl parameter2 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a2"));
     parameter2.type = _typeProvider.intType;
     parameter2.parameterKind = ParameterKind.POSITIONAL;
     methodM1.parameters = <ParameterElement>[parameter1, parameter2];
@@ -412,15 +412,15 @@
     MethodElementImpl methodM2 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter3 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a3"));
     parameter3.type = _typeProvider.intType;
     parameter3.parameterKind = ParameterKind.REQUIRED;
     ParameterElementImpl parameter4 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a4"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a4"));
     parameter4.type = _typeProvider.intType;
     parameter4.parameterKind = ParameterKind.REQUIRED;
     ParameterElementImpl parameter5 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a5"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a5"));
     parameter5.type = _typeProvider.intType;
     parameter5.parameterKind = ParameterKind.REQUIRED;
     methodM2.parameters = <ParameterElement>[
@@ -584,7 +584,7 @@
     MethodElementImpl methodM1 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
     parameter1.type = _typeProvider.intType;
     parameter1.parameterKind = ParameterKind.REQUIRED;
     methodM1.parameters = <ParameterElement>[parameter1];
@@ -593,7 +593,7 @@
     MethodElementImpl methodM2 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter2 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
     parameter2.type = _typeProvider.numType;
     parameter2.parameterKind = ParameterKind.REQUIRED;
     methodM2.parameters = <ParameterElement>[parameter2];
@@ -692,7 +692,7 @@
     MethodElementImpl methodM1 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
     parameter1.type = classA.type;
     parameter1.parameterKind = ParameterKind.REQUIRED;
     methodM1.parameters = <ParameterElement>[parameter1];
@@ -701,7 +701,7 @@
     MethodElementImpl methodM2 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter2 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
     parameter2.type = classB.type;
     parameter2.parameterKind = ParameterKind.REQUIRED;
     methodM2.parameters = <ParameterElement>[parameter2];
@@ -710,7 +710,7 @@
     MethodElementImpl methodM3 =
         ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
     ParameterElementImpl parameter3 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
     parameter3.type = classC.type;
     parameter3.parameterKind = ParameterKind.REQUIRED;
     methodM3.parameters = <ParameterElement>[parameter3];
@@ -785,7 +785,7 @@
     MethodElementImpl methodM2 =
         ElementFactory.methodElement(methodName, _typeProvider.intType);
     ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a1"));
     parameter1.type = _typeProvider.intType;
     parameter1.parameterKind = ParameterKind.POSITIONAL;
     methodM2.parameters = <ParameterElement>[parameter1];
@@ -814,7 +814,7 @@
     MethodElementImpl methodM2 =
         ElementFactory.methodElement(methodName, _typeProvider.intType);
     ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a1"));
     parameter1.type = _typeProvider.intType;
     parameter1.parameterKind = ParameterKind.POSITIONAL;
     methodM1.parameters = <ParameterElement>[parameter1];
@@ -823,11 +823,11 @@
     MethodElementImpl methodM3 =
         ElementFactory.methodElement(methodName, _typeProvider.intType);
     ParameterElementImpl parameter2 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a2"));
     parameter2.type = _typeProvider.intType;
     parameter2.parameterKind = ParameterKind.POSITIONAL;
     ParameterElementImpl parameter3 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a3"));
     parameter3.type = _typeProvider.intType;
     parameter3.parameterKind = ParameterKind.POSITIONAL;
     methodM3.parameters = <ParameterElement>[parameter2, parameter3];
@@ -865,7 +865,7 @@
     MethodElementImpl methodM3 =
         ElementFactory.methodElement(methodName, _typeProvider.intType);
     ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a1"));
     parameter1.type = _typeProvider.intType;
     parameter1.parameterKind = ParameterKind.POSITIONAL;
     methodM3.parameters = <ParameterElement>[parameter1];
@@ -874,11 +874,11 @@
     MethodElementImpl methodM4 =
         ElementFactory.methodElement(methodName, _typeProvider.intType);
     ParameterElementImpl parameter2 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a2"));
     parameter2.type = _typeProvider.intType;
     parameter2.parameterKind = ParameterKind.POSITIONAL;
     ParameterElementImpl parameter3 =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a3"));
     parameter3.type = _typeProvider.intType;
     parameter3.parameterKind = ParameterKind.POSITIONAL;
     methodM4.parameters = <ParameterElement>[parameter2, parameter3];
diff --git a/pkg/analyzer/test/generated/package_test.dart b/pkg/analyzer/test/generated/package_test.dart
index 7a93dbe..03cceff 100644
--- a/pkg/analyzer/test/generated/package_test.dart
+++ b/pkg/analyzer/test/generated/package_test.dart
@@ -160,7 +160,8 @@
     DartSdk sdk = new MockSdk();
     AnalysisOptionsImpl options1 = new AnalysisOptionsImpl();
     AnalysisOptionsImpl options2 = new AnalysisOptionsImpl();
-    options2.enableGenericMethods = !options1.enableGenericMethods;
+    options2.enableLazyAssignmentOperators =
+        !options1.enableLazyAssignmentOperators;
     PackageDescription first = new PackageDescription(packageId, sdk, options1);
     PackageDescription second =
         new PackageDescription(packageId, sdk, options2);
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 550b854..6ce609f 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -14,7 +14,7 @@
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:test/test.dart';
@@ -201,7 +201,6 @@
   }
 
   void test_assignableExpression_arguments_normal_chain_typeArguments() {
-    enableGenericMethods = true;
     _validate_assignableExpression_arguments_normal_chain_typeArguments(
         "a<E>(b)<F>(c).d<G>(e).f");
   }
@@ -532,7 +531,6 @@
   }
 
   void test_topLevelFunction_nestedGenericFunction() {
-    enableGenericMethods = true;
     parseCompilationUnitWithOptions('''
 void f() {
   void g<T>() {
@@ -1683,7 +1681,6 @@
     // Regression test for https://github.com/dart-lang/sdk/issues/25739.
 
     // TODO(jmesserly): ideally we'd be better at parser recovery here.
-    enableGenericMethods = true;
     createParser('f<E>(E extends num p);');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
@@ -1729,7 +1726,6 @@
     // It doesn't try to advance past the invalid token `!` to find the
     // valid `>`. If it did we'd get less cascading errors, at least for this
     // particular example.
-    enableGenericMethods = true;
     createParser('void m<E, hello!>() {}');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
@@ -2269,7 +2265,6 @@
   }
 
   void test_parseCascadeSection_missingIdentifier_typeArguments() {
-    enableGenericMethods = true;
     createParser('..<E>()');
     MethodInvocation methodInvocation = parser.parseCascadeSection();
     expectNotNullIfNoErrors(methodInvocation);
@@ -2841,12 +2836,6 @@
   bool parseAsync = true;
 
   /**
-   * A flag indicating whether generic method support should be enabled for a
-   * specific test.
-   */
-  bool enableGenericMethods = false;
-
-  /**
    * Whether generic method comments should be enabled for the test.
    */
   bool enableGenericMethodComments = false;
@@ -2864,6 +2853,12 @@
   bool enableNnbd = false;
 
   /**
+   * A flag indicating whether the parser is to parse part-of directives that
+   * specify a URI rather than a library name.
+   */
+  bool enableUriInPartOf = false;
+
+  /**
    * The error listener to which scanner and parser errors will be reported.
    *
    * This field is typically initialized by invoking [createParser].
@@ -2910,10 +2905,10 @@
     //
     parser = new Parser(source, listener);
     parser.enableAssertInitializer = enableAssertInitializer;
-    parser.parseGenericMethods = enableGenericMethods;
     parser.parseGenericMethodComments = enableGenericMethodComments;
     parser.parseFunctionBodies = parseFunctionBodies;
     parser.enableNnbd = enableNnbd;
+    parser.enableUriInPartOf = enableUriInPartOf;
     parser.currentToken = tokenStream;
   }
 
@@ -2996,12 +2991,11 @@
    * Parse the given [code] as a compilation unit.
    */
   static CompilationUnit parseCompilationUnit2(String code,
-      {AnalysisErrorListener listener, bool parseGenericMethods: false}) {
+      {AnalysisErrorListener listener}) {
     listener ??= AnalysisErrorListener.NULL_LISTENER;
     Scanner scanner = new Scanner(null, new CharSequenceReader(code), listener);
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, listener);
-    parser.parseGenericMethods = parseGenericMethods;
     CompilationUnit unit = parser.parseCompilationUnit(token);
     unit.lineInfo = new LineInfo(scanner.lineStarts);
     return unit;
@@ -4427,12 +4421,10 @@
   }
 
   void test_isFunctionDeclaration_nameButNoReturn_typeParameters_block() {
-    enableGenericMethods = true;
     expect(_isFunctionDeclaration("f<E>() {}"), isTrue);
   }
 
   void test_isFunctionDeclaration_nameButNoReturn_typeParameters_expression() {
-    enableGenericMethods = true;
     expect(_isFunctionDeclaration("f<E>() => e"), isTrue);
   }
 
@@ -4445,12 +4437,10 @@
   }
 
   void test_isFunctionDeclaration_normalReturn_typeParameters_block() {
-    enableGenericMethods = true;
     expect(_isFunctionDeclaration("C f<E>() {}"), isTrue);
   }
 
   void test_isFunctionDeclaration_normalReturn_typeParameters_expression() {
-    enableGenericMethods = true;
     expect(_isFunctionDeclaration("C f<E>() => e"), isTrue);
   }
 
@@ -4463,12 +4453,10 @@
   }
 
   void test_isFunctionDeclaration_voidReturn_typeParameters_block() {
-    enableGenericMethods = true;
     expect(_isFunctionDeclaration("void f<E>() {}"), isTrue);
   }
 
   void test_isFunctionDeclaration_voidReturn_typeParameters_expression() {
-    enableGenericMethods = true;
     expect(_isFunctionDeclaration("void f<E>() => e"), isTrue);
   }
 
@@ -4489,12 +4477,10 @@
   }
 
   void test_isFunctionExpression_noParameters_typeParameters_block() {
-    enableGenericMethods = true;
     expect(_isFunctionExpression("<E>() {}"), isTrue);
   }
 
   void test_isFunctionExpression_noParameters_typeParameters_expression() {
-    enableGenericMethods = true;
     expect(_isFunctionExpression("<E>() => e"), isTrue);
   }
 
@@ -4873,7 +4859,6 @@
   }
 
   void test_parseAssignableExpression_expression_args_dot_typeParameters() {
-    enableGenericMethods = true;
     createParser('(x)<F>(y).z');
     Expression expression = parser.parseAssignableExpression(false);
     expectNotNullIfNoErrors(expression);
@@ -4975,7 +4960,6 @@
   }
 
   void test_parseAssignableExpression_identifier_args_dot_typeParameters() {
-    enableGenericMethods = true;
     createParser('x<E>(y).z');
     Expression expression = parser.parseAssignableExpression(false);
     expectNotNullIfNoErrors(expression);
@@ -5328,7 +5312,6 @@
   }
 
   void test_parseCascadeSection_ia_typeArguments() {
-    enableGenericMethods = true;
     createParser('..[i]<E>(b)');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -5372,7 +5355,6 @@
   }
 
   void test_parseCascadeSection_ii_typeArguments() {
-    enableGenericMethods = true;
     createParser('..a<E>(b).c<F>(d)');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -5442,7 +5424,6 @@
   }
 
   void test_parseCascadeSection_p_assign_withCascade_typeArguments() {
-    enableGenericMethods = true;
     createParser('..a = 3..m<E>()');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -5500,7 +5481,6 @@
   }
 
   void test_parseCascadeSection_pa_typeArguments() {
-    enableGenericMethods = true;
     createParser('..a<E>(b)');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -5543,7 +5523,6 @@
   }
 
   void test_parseCascadeSection_paa_typeArguments() {
-    enableGenericMethods = true;
     createParser('..a<E>(b)<F>(c)');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -5584,7 +5563,6 @@
   }
 
   void test_parseCascadeSection_paapaa_typeArguments() {
-    enableGenericMethods = true;
     createParser('..a<E>(b)<F>(c).d<G>(e)<H>(f)');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -5623,7 +5601,6 @@
   }
 
   void test_parseCascadeSection_pap_typeArguments() {
-    enableGenericMethods = true;
     createParser('..a<E>(b).c');
     Expression expression = parser.parseCascadeSection();
     expectNotNullIfNoErrors(expression);
@@ -6124,7 +6101,6 @@
   }
 
   void test_parseClassMember_method_generic_noReturnType() {
-    enableGenericMethods = true;
     createParser('m<T>() {}');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
@@ -6144,7 +6120,6 @@
   }
 
   void test_parseClassMember_method_generic_returnType() {
-    enableGenericMethods = true;
     createParser('T m<T>() {}');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
@@ -6164,7 +6139,6 @@
   }
 
   void test_parseClassMember_method_generic_void() {
-    enableGenericMethods = true;
     createParser('void m<T>() {}');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
@@ -7354,7 +7328,6 @@
   }
 
   void test_parseCompilationUnitMember_function_generic_noReturnType() {
-    enableGenericMethods = true;
     createParser('f<E>() {}');
     CompilationUnitMember member =
         parser.parseCompilationUnitMember(emptyCommentAndMetadata());
@@ -7368,7 +7341,6 @@
 
   void
       test_parseCompilationUnitMember_function_generic_noReturnType_annotated() {
-    enableGenericMethods = true;
     createParser('f<@a E>() {}');
     CompilationUnitMember member =
         parser.parseCompilationUnitMember(emptyCommentAndMetadata());
@@ -7381,7 +7353,6 @@
   }
 
   void test_parseCompilationUnitMember_function_generic_returnType() {
-    enableGenericMethods = true;
     createParser('E f<E>() {}');
     CompilationUnitMember member =
         parser.parseCompilationUnitMember(emptyCommentAndMetadata());
@@ -7394,7 +7365,6 @@
   }
 
   void test_parseCompilationUnitMember_function_generic_void() {
-    enableGenericMethods = true;
     createParser('void f<T>(T t) {}');
     CompilationUnitMember member =
         parser.parseCompilationUnitMember(emptyCommentAndMetadata());
@@ -8418,7 +8388,6 @@
   }
 
   void test_parseExpression_superMethodInvocation_typeArguments() {
-    enableGenericMethods = true;
     Expression expression = parseExpression('super.m<E>()');
     expect(expression, new isInstanceOf<MethodInvocation>());
     MethodInvocation invocation = expression;
@@ -8501,7 +8470,6 @@
 
   void
       test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
-    enableGenericMethods = true;
     createParser('super.m<E>()');
     Expression expression = parser.parseExpressionWithoutCascade();
     expectNotNullIfNoErrors(expression);
@@ -9474,7 +9442,6 @@
   }
 
   void test_parseFunctionDeclaration_functionWithTypeParameters() {
-    enableGenericMethods = true;
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
     createParser('f<E>() {}');
@@ -9576,7 +9543,6 @@
   }
 
   void test_parseFunctionDeclarationStatement_typeParameters() {
-    enableGenericMethods = true;
     createParser('E f<E>(E p) => p * 2;');
     FunctionDeclarationStatement statement =
         parser.parseFunctionDeclarationStatement();
@@ -9613,7 +9579,6 @@
   }
 
   void test_parseFunctionExpression_typeParameters() {
-    enableGenericMethods = true;
     createParser('<E>(E i) => i++');
     FunctionExpression expression = parser.parseFunctionExpression();
     expectNotNullIfNoErrors(expression);
@@ -10358,8 +10323,8 @@
 
   void test_parseMapLiteral_empty() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CONST);
-    TypeArgumentList typeArguments = AstFactory.typeArgumentList(
-        [AstFactory.typeName4("String"), AstFactory.typeName4("int")]);
+    TypeArgumentList typeArguments = AstTestFactory.typeArgumentList(
+        [AstTestFactory.typeName4("String"), AstTestFactory.typeName4("int")]);
     createParser('{}');
     MapLiteral literal = parser.parseMapLiteral(token, typeArguments);
     expectNotNullIfNoErrors(literal);
@@ -10857,7 +10822,6 @@
   }
 
   void test_parseNormalFormalParameter_function_noType_typeParameters() {
-    enableGenericMethods = true;
     createParser('a<E>())');
     NormalFormalParameter parameter = parser.parseNormalFormalParameter();
     expectNotNullIfNoErrors(parameter);
@@ -10874,7 +10838,6 @@
 
   void
       test_parseNormalFormalParameter_function_noType_typeParameters_nullable() {
-    enableGenericMethods = true;
     enableNnbd = true;
     createParser('a<E>()?)');
     NormalFormalParameter parameter = parser.parseNormalFormalParameter();
@@ -10934,7 +10897,6 @@
   }
 
   void test_parseNormalFormalParameter_function_type_typeParameters() {
-    enableGenericMethods = true;
     createParser('A a<E>())');
     NormalFormalParameter parameter = parser.parseNormalFormalParameter();
     expectNotNullIfNoErrors(parameter);
@@ -10949,7 +10911,6 @@
   }
 
   void test_parseNormalFormalParameter_function_type_typeParameters_nullable() {
-    enableGenericMethods = true;
     enableNnbd = true;
     createParser('A a<E>()?)');
     NormalFormalParameter parameter = parser.parseNormalFormalParameter();
@@ -11009,7 +10970,6 @@
   }
 
   void test_parseNormalFormalParameter_function_void_typeParameters() {
-    enableGenericMethods = true;
     createParser('void a<E>())');
     NormalFormalParameter parameter = parser.parseNormalFormalParameter();
     expectNotNullIfNoErrors(parameter);
@@ -11024,7 +10984,6 @@
   }
 
   void test_parseNormalFormalParameter_function_void_typeParameters_nullable() {
-    enableGenericMethods = true;
     enableNnbd = true;
     createParser('void a<E>()?)');
     NormalFormalParameter parameter = parser.parseNormalFormalParameter();
@@ -11135,7 +11094,7 @@
     // TODO(brianwilkerson) Implement tests for this method.
   }
 
-  void test_parsePartDirective_part() {
+  void test_parsePartDirective() {
     createParser("part 'lib/lib.dart';");
     PartDirective directive =
         parser.parsePartOrPartOfDirective(emptyCommentAndMetadata());
@@ -11146,15 +11105,27 @@
     expect(directive.semicolon, isNotNull);
   }
 
-  void test_parsePartDirective_partOf() {
-    createParser('part of l;');
+  void test_parsePartOfDirective_name() {
+    enableUriInPartOf = true;
+    createParser("part of l;");
     PartOfDirective directive =
         parser.parsePartOrPartOfDirective(emptyCommentAndMetadata());
-    expectNotNullIfNoErrors(directive);
-    listener.assertNoErrors();
     expect(directive.partKeyword, isNotNull);
     expect(directive.ofKeyword, isNotNull);
     expect(directive.libraryName, isNotNull);
+    expect(directive.uri, isNull);
+    expect(directive.semicolon, isNotNull);
+  }
+
+  void test_parsePartOfDirective_uri() {
+    enableUriInPartOf = true;
+    createParser("part of 'lib.dart';");
+    PartOfDirective directive =
+        parser.parsePartOrPartOfDirective(emptyCommentAndMetadata());
+    expect(directive.partKeyword, isNotNull);
+    expect(directive.ofKeyword, isNotNull);
+    expect(directive.libraryName, isNull);
+    expect(directive.uri, isNotNull);
     expect(directive.semicolon, isNotNull);
   }
 
@@ -11239,7 +11210,6 @@
 
   void
       test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
-    enableGenericMethods = true;
     createParser('a?.m<E>()');
     Expression expression = parser.parsePostfixExpression();
     expectNotNullIfNoErrors(expression);
@@ -11270,7 +11240,6 @@
   }
 
   void test_parsePostfixExpression_none_methodInvocation_typeArguments() {
-    enableGenericMethods = true;
     createParser('a.m<E>()');
     Expression expression = parser.parsePostfixExpression();
     expectNotNullIfNoErrors(expression);
@@ -11374,7 +11343,6 @@
   }
 
   void test_parsePrimaryExpression_genericFunctionExpression() {
-    enableGenericMethods = true;
     createParser('<X, Y>(Map<X, Y> m, X x) => m[x]');
     Expression expression = parser.parsePrimaryExpression();
     expectNotNullIfNoErrors(expression);
@@ -11889,7 +11857,6 @@
 
   @failingTest
   void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
-    enableGenericMethods = true;
     createParser('f<E>(a, b) {};');
     Statement statement = parser.parseStatement2();
     expectNotNullIfNoErrors(statement);
@@ -11911,7 +11878,6 @@
   }
 
   void test_parseStatement_functionDeclaration_returnType_typeParameters() {
-    enableGenericMethods = true;
     createParser('int f<E>(a, b) {};');
     Statement statement = parser.parseStatement2();
     expectNotNullIfNoErrors(statement);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index bdd6b8c..416f980 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -20,7 +20,7 @@
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -147,7 +147,7 @@
   void test_define_duplicate() {
     Scope rootScope = new _RootScope();
     EnclosedScope scope = new EnclosedScope(rootScope);
-    SimpleIdentifier identifier = AstFactory.identifier3('v');
+    SimpleIdentifier identifier = AstTestFactory.identifier3('v');
     VariableElement element1 = ElementFactory.localVariableElement(identifier);
     VariableElement element2 = ElementFactory.localVariableElement(identifier);
     scope.define(element1);
@@ -224,13 +224,6 @@
  */
 @reflectiveTest
 class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared {
-  void setUp() {
-    super.setUp();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableGenericMethods = true;
-    resetWithOptions(options);
-  }
-
   void test_genericMethod_propagatedType_promotion() {
     // Regression test for:
     // https://github.com/dart-lang/sdk/issues/25340
@@ -264,8 +257,8 @@
   void test_creation_nonEmpty() {
     AnalysisContext context = AnalysisContextFactory.contextWithCore();
     String importedTypeName = "A";
-    ClassElement importedType =
-        new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
+    ClassElement importedType = new ClassElementImpl.forNode(
+        AstTestFactory.identifier3(importedTypeName));
     LibraryElement importedLibrary = createTestLibrary(context, "imported");
     (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
         .types = <ClassElement>[importedType];
@@ -276,7 +269,8 @@
     definingLibrary.imports = <ImportElement>[importElement];
     Scope scope = new LibraryImportScope(definingLibrary);
     expect(
-        scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
+        scope.lookup(
+            AstTestFactory.identifier3(importedTypeName), definingLibrary),
         importedType);
   }
 
@@ -306,10 +300,10 @@
     ];
     Scope scope = new LibraryImportScope(importingLibrary);
     Element prefixedElement = scope.lookup(
-        AstFactory.identifier5(prefixName, typeName), importingLibrary);
+        AstTestFactory.identifier5(prefixName, typeName), importingLibrary);
     expect(prefixedElement, same(prefixedType));
     Element nonPrefixedElement =
-        scope.lookup(AstFactory.identifier3(typeName), importingLibrary);
+        scope.lookup(AstTestFactory.identifier3(typeName), importingLibrary);
     expect(nonPrefixedElement, same(nonPrefixedType));
   }
 }
@@ -323,8 +317,8 @@
   void test_creation_nonEmpty() {
     AnalysisContext context = AnalysisContextFactory.contextWithCore();
     String importedTypeName = "A";
-    ClassElement importedType =
-        new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
+    ClassElement importedType = new ClassElementImpl.forNode(
+        AstTestFactory.identifier3(importedTypeName));
     LibraryElement importedLibrary = createTestLibrary(context, "imported");
     (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
         .types = <ClassElement>[importedType];
@@ -335,7 +329,8 @@
     definingLibrary.imports = <ImportElement>[importElement];
     Scope scope = new LibraryScope(definingLibrary);
     expect(
-        scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
+        scope.lookup(
+            AstTestFactory.identifier3(importedTypeName), definingLibrary),
         importedType);
   }
 }
@@ -373,7 +368,7 @@
 class ScopeTest extends ResolverTestCase {
   void test_define_duplicate() {
     Scope scope = new _RootScope();
-    SimpleIdentifier identifier = AstFactory.identifier3('v');
+    SimpleIdentifier identifier = AstTestFactory.identifier3('v');
     VariableElement element1 = ElementFactory.localVariableElement(identifier);
     VariableElement element2 = ElementFactory.localVariableElement(identifier);
     scope.define(element1);
@@ -2480,10 +2475,10 @@
     asyncUnit.types = <ClassElement>[futureType.element, streamType.element];
     AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
     LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
-        context, AstFactory.libraryIdentifier2(["dart.core"]));
+        context, AstTestFactory.libraryIdentifier2(["dart.core"]));
     coreLibrary.definingCompilationUnit = coreUnit;
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
-        context, AstFactory.libraryIdentifier2(["dart.async"]));
+        context, AstTestFactory.libraryIdentifier2(["dart.async"]));
     asyncLibrary.definingCompilationUnit = asyncUnit;
     //
     // Create a type provider and ensure that it can return the expected types.
@@ -2509,7 +2504,7 @@
   ClassElement _classElement(String typeName, InterfaceType superclassType,
       [List<String> parameterNames]) {
     ClassElementImpl element =
-        new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3(typeName));
     element.supertype = superclassType;
     if (parameterNames != null) {
       int count = parameterNames.length;
@@ -2521,7 +2516,7 @@
         for (int i = 0; i < count; i++) {
           TypeParameterElementImpl typeParameter =
               new TypeParameterElementImpl.forNode(
-                  AstFactory.identifier3(parameterNames[i]));
+                  AstTestFactory.identifier3(parameterNames[i]));
           typeParameters[i] = typeParameter;
           typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
           typeParameter.type = typeArguments[i];
@@ -2568,8 +2563,9 @@
   void fail_visitVariableDeclaration() {
     fail("Not yet tested");
     ClassElement type = ElementFactory.classElement2("A");
-    VariableDeclaration node = AstFactory.variableDeclaration("a");
-    AstFactory.variableDeclarationList(null, AstFactory.typeName(type), [node]);
+    VariableDeclaration node = AstTestFactory.variableDeclaration("a");
+    AstTestFactory
+        .variableDeclarationList(null, AstTestFactory.typeName(type), [node]);
     //resolve(node);
     expect(node.name.staticType, same(type.type));
     _listener.assertNoErrors();
@@ -2583,7 +2579,7 @@
     Source librarySource =
         new FileSource(resourceProvider.getFile("/lib.dart"));
     LibraryElementImpl element = new LibraryElementImpl.forNode(
-        context, AstFactory.libraryIdentifier2(["lib"]));
+        context, AstTestFactory.libraryIdentifier2(["lib"]));
     element.definingCompilationUnit =
         new CompilationUnitElementImpl("lib.dart");
     _typeProvider = new TestTypeProvider();
@@ -2989,7 +2985,7 @@
 
   void test_visitCatchClause_exception() {
     // catch (e)
-    CatchClause clause = AstFactory.catchClause("e");
+    CatchClause clause = AstTestFactory.catchClause("e");
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement =
         new LocalVariableElementImpl.forNode(exceptionParameter);
@@ -2999,7 +2995,7 @@
 
   void test_visitCatchClause_exception_stackTrace() {
     // catch (e, s)
-    CatchClause clause = AstFactory.catchClause2("e", "s");
+    CatchClause clause = AstTestFactory.catchClause2("e", "s");
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement =
         new LocalVariableElementImpl.forNode(exceptionParameter);
@@ -3014,8 +3010,8 @@
   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");
+    TypeName exceptionType = AstTestFactory.typeName(exceptionElement);
+    CatchClause clause = AstTestFactory.catchClause4(exceptionType, "e");
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement =
         new LocalVariableElementImpl.forNode(exceptionParameter);
@@ -3027,9 +3023,9 @@
   void test_visitCatchClause_on_exception_stackTrace() {
     // on E catch (e, s)
     ClassElement exceptionElement = ElementFactory.classElement2("E");
-    TypeName exceptionType = AstFactory.typeName(exceptionElement);
+    TypeName exceptionType = AstTestFactory.typeName(exceptionElement);
     (exceptionType.name as SimpleIdentifier).staticElement = exceptionElement;
-    CatchClause clause = AstFactory.catchClause5(exceptionType, "e", "s");
+    CatchClause clause = AstTestFactory.catchClause5(exceptionType, "e", "s");
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement =
         new LocalVariableElementImpl.forNode(exceptionParameter);
@@ -3051,12 +3047,12 @@
     ClassElement elementC = ElementFactory.classElement2("C");
     ClassElement elementD = ElementFactory.classElement2("D");
     ExtendsClause extendsClause =
-        AstFactory.extendsClause(AstFactory.typeName(elementB));
+        AstTestFactory.extendsClause(AstTestFactory.typeName(elementB));
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(elementC)]);
+        AstTestFactory.withClause([AstTestFactory.typeName(elementC)]);
     ImplementsClause implementsClause =
-        AstFactory.implementsClause([AstFactory.typeName(elementD)]);
-    ClassDeclaration declaration = AstFactory.classDeclaration(
+        AstTestFactory.implementsClause([AstTestFactory.typeName(elementD)]);
+    ClassDeclaration declaration = AstTestFactory.classDeclaration(
         null, "A", null, extendsClause, withClause, implementsClause);
     declaration.name.staticElement = elementA;
     _resolveNode(declaration, [elementA, elementB, elementC, elementD]);
@@ -3081,9 +3077,9 @@
       ElementFactory.methodElement("A", VoidTypeImpl.instance)
     ];
     ExtendsClause extendsClause =
-        AstFactory.extendsClause(AstFactory.typeName(elementA));
-    ClassDeclaration declaration =
-        AstFactory.classDeclaration(null, "B", null, extendsClause, null, null);
+        AstTestFactory.extendsClause(AstTestFactory.typeName(elementA));
+    ClassDeclaration declaration = AstTestFactory.classDeclaration(
+        null, "B", null, extendsClause, null, null);
     declaration.name.staticElement = elementB;
     _resolveNode(declaration, [elementA, elementB]);
     expect(elementB.supertype, same(elementA.type));
@@ -3097,11 +3093,11 @@
     ClassElement elementC = ElementFactory.classElement2("C");
     ClassElement elementD = ElementFactory.classElement2("D");
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(elementC)]);
+        AstTestFactory.withClause([AstTestFactory.typeName(elementC)]);
     ImplementsClause implementsClause =
-        AstFactory.implementsClause([AstFactory.typeName(elementD)]);
-    ClassTypeAlias alias = AstFactory.classTypeAlias("A", null, null,
-        AstFactory.typeName(elementB), withClause, implementsClause);
+        AstTestFactory.implementsClause([AstTestFactory.typeName(elementD)]);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias("A", null, null,
+        AstTestFactory.typeName(elementB), withClause, implementsClause);
     alias.name.staticElement = elementA;
     _resolveNode(alias, [elementA, elementB, elementC, elementD]);
     expect(elementA.supertype, same(elementB.type));
@@ -3138,10 +3134,10 @@
     classB.constructors = [constructorBc1, constructorBc2, constructorBc3];
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(classM, [])]);
+        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
     ClassElement classC = ElementFactory.classTypeAlias2('C', []);
-    ClassTypeAlias alias = AstFactory.classTypeAlias(
-        'C', null, null, AstFactory.typeName(classB, []), withClause, null);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
+        'C', null, null, AstTestFactory.typeName(classB, []), withClause, null);
     alias.name.staticElement = classC;
     _resolveNode(alias, [classT, classB, classM, classC]);
     expect(classC.constructors, hasLength(1));
@@ -3169,10 +3165,10 @@
     classB.constructors = [constructorB];
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(classM, [])]);
+        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
     ClassElement classC = ElementFactory.classTypeAlias2('C', []);
-    ClassTypeAlias alias = AstFactory.classTypeAlias(
-        'C', null, null, AstFactory.typeName(classB, []), withClause, null);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
+        'C', null, null, AstTestFactory.typeName(classB, []), withClause, null);
     alias.name.staticElement = classC;
     _resolveNode(alias, [classT, classB, classM, classC]);
     expect(classC.constructors, hasLength(1));
@@ -3200,10 +3196,10 @@
     classB.constructors = [constructorB];
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
-        AstFactory.withClause([AstFactory.typeName(classM, [])]);
+        AstTestFactory.withClause([AstTestFactory.typeName(classM, [])]);
     ClassElement classC = ElementFactory.classTypeAlias2('C', []);
-    ClassTypeAlias alias = AstFactory.classTypeAlias(
-        'C', null, null, AstFactory.typeName(classB, []), withClause, null);
+    ClassTypeAlias alias = AstTestFactory.classTypeAlias(
+        'C', null, null, AstTestFactory.typeName(classB, []), withClause, null);
     alias.name.staticElement = classC;
     _resolveNode(alias, [classB, classM, classC]);
     expect(classC.constructors, hasLength(1));
@@ -3219,15 +3215,18 @@
 
   void test_visitFieldFormalParameter_functionType() {
     InterfaceType intType = _typeProvider.intType;
-    TypeName intTypeName = AstFactory.typeName4("int");
+    TypeName intTypeName = AstTestFactory.typeName4("int");
     String innerParameterName = "a";
     SimpleFormalParameter parameter =
-        AstFactory.simpleFormalParameter3(innerParameterName);
+        AstTestFactory.simpleFormalParameter3(innerParameterName);
     parameter.identifier.staticElement =
         ElementFactory.requiredParameter(innerParameterName);
     String outerParameterName = "p";
-    FormalParameter node = AstFactory.fieldFormalParameter(null, intTypeName,
-        outerParameterName, AstFactory.formalParameterList([parameter]));
+    FormalParameter node = AstTestFactory.fieldFormalParameter(
+        null,
+        intTypeName,
+        outerParameterName,
+        AstTestFactory.formalParameterList([parameter]));
     node.identifier.staticElement =
         ElementFactory.requiredParameter(outerParameterName);
     DartType parameterType = _resolveFormalParameter(node, [intType.element]);
@@ -3242,7 +3241,7 @@
   void test_visitFieldFormalParameter_noType() {
     String parameterName = "p";
     FormalParameter node =
-        AstFactory.fieldFormalParameter(Keyword.VAR, null, parameterName);
+        AstTestFactory.fieldFormalParameter(Keyword.VAR, null, parameterName);
     node.identifier.staticElement =
         ElementFactory.requiredParameter(parameterName);
     expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
@@ -3251,10 +3250,10 @@
 
   void test_visitFieldFormalParameter_type() {
     InterfaceType intType = _typeProvider.intType;
-    TypeName intTypeName = AstFactory.typeName4("int");
+    TypeName intTypeName = AstTestFactory.typeName4("int");
     String parameterName = "p";
     FormalParameter node =
-        AstFactory.fieldFormalParameter(null, intTypeName, parameterName);
+        AstTestFactory.fieldFormalParameter(null, intTypeName, parameterName);
     node.identifier.staticElement =
         ElementFactory.requiredParameter(parameterName);
     expect(_resolveFormalParameter(node, [intType.element]), same(intType));
@@ -3268,13 +3267,14 @@
     ClassElement elementR = ElementFactory.classElement2('R');
     ClassElement elementP = ElementFactory.classElement2('P');
     FunctionElement elementF = ElementFactory.functionElement('f');
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        AstFactory.typeName4('R'),
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        AstTestFactory.typeName4('R'),
         null,
         'f',
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList([
-              AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
+        AstTestFactory.functionExpression2(
+            AstTestFactory.formalParameterList([
+              AstTestFactory.simpleFormalParameter4(
+                  AstTestFactory.typeName4('P'), 'p')
             ]),
             null));
     declaration.name.staticElement = elementF;
@@ -3291,13 +3291,14 @@
     TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
     FunctionElementImpl elementF = ElementFactory.functionElement('f');
     elementF.typeParameters = <TypeParameterElement>[elementE];
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        AstFactory.typeName4('E'),
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        AstTestFactory.typeName4('E'),
         null,
         'f',
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList([
-              AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
+        AstTestFactory.functionExpression2(
+            AstTestFactory.formalParameterList([
+              AstTestFactory.simpleFormalParameter4(
+                  AstTestFactory.typeName4('E'), 'e')
             ]),
             null));
     declaration.name.staticElement = elementF;
@@ -3318,17 +3319,17 @@
     FunctionElement elementF = ElementFactory.functionElement('f');
     ParameterElementImpl requiredParameter =
         ElementFactory.requiredParameter('p');
-    FunctionTypedFormalParameter parameterDeclaration = AstFactory
-        .functionTypedFormalParameter(AstFactory.typeName4('R'), 'g', [
-      AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
+    FunctionTypedFormalParameter parameterDeclaration = AstTestFactory
+        .functionTypedFormalParameter(AstTestFactory.typeName4('R'), 'g', [
+      AstTestFactory.simpleFormalParameter4(AstTestFactory.typeName4('P'), 'p')
     ]);
     parameterDeclaration.identifier.staticElement = requiredParameter;
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        AstFactory.typeName4('R'),
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        AstTestFactory.typeName4('R'),
         null,
         'f',
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList([parameterDeclaration]), null));
+        AstTestFactory.functionExpression2(
+            AstTestFactory.formalParameterList([parameterDeclaration]), null));
     declaration.name.staticElement = elementF;
     _resolveNode(declaration, [elementR, elementP]);
     expect(declaration.returnType.type, elementR.type);
@@ -3349,17 +3350,17 @@
     ParameterElementImpl requiredParameter =
         ElementFactory.requiredParameter('g');
     requiredParameter.typeParameters = <TypeParameterElement>[elementE];
-    FunctionTypedFormalParameter parameterDeclaration = AstFactory
-        .functionTypedFormalParameter(AstFactory.typeName4('R'), 'g', [
-      AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
+    FunctionTypedFormalParameter parameterDeclaration = AstTestFactory
+        .functionTypedFormalParameter(AstTestFactory.typeName4('R'), 'g', [
+      AstTestFactory.simpleFormalParameter4(AstTestFactory.typeName4('E'), 'e')
     ]);
     parameterDeclaration.identifier.staticElement = requiredParameter;
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        AstFactory.typeName4('R'),
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        AstTestFactory.typeName4('R'),
         null,
         'f',
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList([parameterDeclaration]), null));
+        AstTestFactory.functionExpression2(
+            AstTestFactory.formalParameterList([parameterDeclaration]), null));
     declaration.name.staticElement = elementF;
     _resolveNode(declaration, [elementR]);
     expect(declaration.returnType.type, elementR.type);
@@ -3382,14 +3383,15 @@
     ClassElement elementP = ElementFactory.classElement2('P');
     MethodElement elementM = ElementFactory.methodElement('m', null);
     elementA.methods = <MethodElement>[elementM];
-    MethodDeclaration declaration = AstFactory.methodDeclaration(
+    MethodDeclaration declaration = AstTestFactory.methodDeclaration(
         null,
-        AstFactory.typeName4('R'),
+        AstTestFactory.typeName4('R'),
         null,
         null,
-        AstFactory.identifier3('m'),
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
+        AstTestFactory.identifier3('m'),
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter4(
+              AstTestFactory.typeName4('P'), 'p')
         ]));
     declaration.name.staticElement = elementM;
     _resolveNode(declaration, [elementA, elementR, elementP]);
@@ -3408,14 +3410,15 @@
     MethodElementImpl elementM = ElementFactory.methodElement('m', null);
     elementM.typeParameters = <TypeParameterElement>[elementE];
     elementA.methods = <MethodElement>[elementM];
-    MethodDeclaration declaration = AstFactory.methodDeclaration(
+    MethodDeclaration declaration = AstTestFactory.methodDeclaration(
         null,
-        AstFactory.typeName4('E'),
+        AstTestFactory.typeName4('E'),
         null,
         null,
-        AstFactory.identifier3('m'),
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
+        AstTestFactory.identifier3('m'),
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter4(
+              AstTestFactory.typeName4('E'), 'e')
         ]));
     declaration.name.staticElement = elementM;
     _resolveNode(declaration, [elementA]);
@@ -3427,9 +3430,9 @@
 
   void test_visitSimpleFormalParameter_noType() {
     // p
-    FormalParameter node = AstFactory.simpleFormalParameter3("p");
+    FormalParameter node = AstTestFactory.simpleFormalParameter3("p");
     node.identifier.staticElement =
-        new ParameterElementImpl.forNode(AstFactory.identifier3("p"));
+        new ParameterElementImpl.forNode(AstTestFactory.identifier3("p"));
     expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
     _listener.assertNoErrors();
   }
@@ -3438,8 +3441,8 @@
     // int p
     InterfaceType intType = _typeProvider.intType;
     ClassElement intElement = intType.element;
-    FormalParameter node =
-        AstFactory.simpleFormalParameter4(AstFactory.typeName(intElement), "p");
+    FormalParameter node = AstTestFactory.simpleFormalParameter4(
+        AstTestFactory.typeName(intElement), "p");
     SimpleIdentifier identifier = node.identifier;
     ParameterElementImpl element = new ParameterElementImpl.forNode(identifier);
     identifier.staticElement = element;
@@ -3449,7 +3452,7 @@
 
   void test_visitTypeName_noParameters_noArguments() {
     ClassElement classA = ElementFactory.classElement2("A");
-    TypeName typeName = AstFactory.typeName(classA);
+    TypeName typeName = AstTestFactory.typeName(classA);
     typeName.type = null;
     _resolveNode(typeName, [classA]);
     expect(typeName.type, same(classA.type));
@@ -3457,7 +3460,7 @@
   }
 
   void test_visitTypeName_noParameters_noArguments_undefined() {
-    SimpleIdentifier id = AstFactory.identifier3("unknown")
+    SimpleIdentifier id = AstTestFactory.identifier3("unknown")
       ..staticElement = new _StaleElement();
     TypeName typeName = new TypeName(id, null);
     _resolveNode(typeName, []);
@@ -3470,7 +3473,7 @@
     ClassElement classA = ElementFactory.classElement2("A", ["E"]);
     ClassElement classB = ElementFactory.classElement2("B");
     TypeName typeName =
-        AstFactory.typeName(classA, [AstFactory.typeName(classB)]);
+        AstTestFactory.typeName(classA, [AstTestFactory.typeName(classB)]);
     typeName.type = null;
     _resolveNode(typeName, [classA, classB]);
     InterfaceType resultType = typeName.type as InterfaceType;
@@ -3483,7 +3486,7 @@
 
   void test_visitTypeName_parameters_noArguments() {
     ClassElement classA = ElementFactory.classElement2("A", ["E"]);
-    TypeName typeName = AstFactory.typeName(classA);
+    TypeName typeName = AstTestFactory.typeName(classA);
     typeName.type = null;
     _resolveNode(typeName, [classA]);
     InterfaceType resultType = typeName.type as InterfaceType;
@@ -3495,12 +3498,12 @@
   }
 
   void test_visitTypeName_prefixed_noParameters_noArguments_undefined() {
-    SimpleIdentifier prefix = AstFactory.identifier3("unknownPrefix")
+    SimpleIdentifier prefix = AstTestFactory.identifier3("unknownPrefix")
       ..staticElement = new _StaleElement();
-    SimpleIdentifier suffix = AstFactory.identifier3("unknownSuffix")
+    SimpleIdentifier suffix = AstTestFactory.identifier3("unknownSuffix")
       ..staticElement = new _StaleElement();
     TypeName typeName =
-        new TypeName(AstFactory.identifier(prefix, suffix), null);
+        new TypeName(AstTestFactory.identifier(prefix, suffix), null);
     _resolveNode(typeName, []);
     expect(typeName.type, UndefinedTypeImpl.instance);
     expect(prefix.staticElement, null);
@@ -3510,7 +3513,7 @@
 
   void test_visitTypeName_void() {
     ClassElement classA = ElementFactory.classElement2("A");
-    TypeName typeName = AstFactory.typeName4("void");
+    TypeName typeName = AstTestFactory.typeName4("void");
     _resolveNode(typeName, [classA]);
     expect(typeName.type, same(VoidTypeImpl.instance));
     _listener.assertNoErrors();
@@ -3581,8 +3584,7 @@
    */
   void _resolveTypeModeLocal(
       String code, AstNode getNodeToResolve(CompilationUnit unit)) {
-    CompilationUnit unit =
-        ParserTestCase.parseCompilationUnit2(code, parseGenericMethods: true);
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit2(code);
     var unitElement = new CompilationUnitElementImpl('/test.dart');
 
     // Build API elements.
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 32b42e9..5cd095d 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -17,7 +17,7 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:test/test.dart';
 
@@ -544,7 +544,7 @@
       for (int i = 0; i < count; i++) {
         String typeName = typeNames[i];
         ClassElementImpl type =
-            new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
+            new ClassElementImpl.forNode(AstTestFactory.identifier3(typeName));
         String fileName = "$typeName.dart";
         CompilationUnitElementImpl compilationUnit =
             new CompilationUnitElementImpl(fileName);
@@ -559,7 +559,7 @@
     compilationUnit.librarySource =
         compilationUnit.source = definingCompilationUnitSource;
     LibraryElementImpl library = new LibraryElementImpl.forNode(
-        context, AstFactory.libraryIdentifier2([libraryName]));
+        context, AstTestFactory.libraryIdentifier2([libraryName]));
     library.definingCompilationUnit = compilationUnit;
     library.parts = sourcedCompilationUnits;
     return library;
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 5ccf569..ae59f48 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -18,7 +18,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
@@ -127,9 +127,6 @@
   }
 
   void test_staticMethods_classTypeParameters_genericMethod() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableGenericMethods = true;
-    resetWithOptions(options);
     String code = r'''
 class C<T> {
   static void m<S>(S s) {
@@ -357,7 +354,7 @@
 
   void test_visitAdjacentStrings() {
     // "a" "b"
-    Expression node = AstFactory
+    Expression node = AstTestFactory
         .adjacentStrings([_resolvedString("a"), _resolvedString("b")]);
     expect(_analyze(node), same(_typeProvider.stringType));
     _listener.assertNoErrors();
@@ -369,8 +366,8 @@
     ClassElement superclass = ElementFactory.classElement2("A");
     InterfaceType superclassType = superclass.type;
     ClassElement subclass = ElementFactory.classElement("B", superclassType);
-    Expression node = AstFactory.asExpression(
-        AstFactory.thisExpression(), AstFactory.typeName(subclass));
+    Expression node = AstTestFactory.asExpression(
+        AstTestFactory.thisExpression(), AstTestFactory.typeName(subclass));
     expect(_analyze3(node, superclassType), same(subclass.type));
     _listener.assertNoErrors();
   }
@@ -380,7 +377,7 @@
       InterfaceType numType = _typeProvider.numType;
       InterfaceType intType = _typeProvider.intType;
       SimpleIdentifier identifier = _resolvedVariable(intType, "i");
-      AssignmentExpression node = AstFactory.assignmentExpression(
+      AssignmentExpression node = AstTestFactory.assignmentExpression(
           identifier, operator, _resolvedInteger(1));
       MethodElement plusMethod = getMethod(numType, "+");
       node.staticElement = plusMethod;
@@ -399,7 +396,7 @@
     validate(TokenType operator) {
       InterfaceType boolType = _typeProvider.boolType;
       SimpleIdentifier identifier = _resolvedVariable(boolType, "b");
-      AssignmentExpression node = AstFactory.assignmentExpression(
+      AssignmentExpression node = AstTestFactory.assignmentExpression(
           identifier, operator, _resolvedBool(true));
       expect(_analyze(node), same(boolType));
       _listener.assertNoErrors();
@@ -415,7 +412,7 @@
       InterfaceType intType = _typeProvider.intType;
       InterfaceType doubleType = _typeProvider.doubleType;
       SimpleIdentifier identifier = _resolvedVariable(intType, "i");
-      AssignmentExpression node = AstFactory.assignmentExpression(
+      AssignmentExpression node = AstTestFactory.assignmentExpression(
           identifier, operator, _resolvedDouble(1.0));
       MethodElement plusMethod = getMethod(numType, "+");
       node.staticElement = plusMethod;
@@ -431,7 +428,7 @@
 
   void test_visitAssignmentExpression_compoundIfNull_differentTypes() {
     // double d; d ??= 0
-    Expression node = AstFactory.assignmentExpression(
+    Expression node = AstTestFactory.assignmentExpression(
         _resolvedVariable(_typeProvider.doubleType, 'd'),
         TokenType.QUESTION_QUESTION_EQ,
         _resolvedInteger(0));
@@ -441,7 +438,7 @@
 
   void test_visitAssignmentExpression_compoundIfNull_sameTypes() {
     // int i; i ??= 0
-    Expression node = AstFactory.assignmentExpression(
+    Expression node = AstTestFactory.assignmentExpression(
         _resolvedVariable(_typeProvider.intType, 'i'),
         TokenType.QUESTION_QUESTION_EQ,
         _resolvedInteger(0));
@@ -452,7 +449,7 @@
   void test_visitAssignmentExpression_simple() {
     // i = 0
     InterfaceType intType = _typeProvider.intType;
-    Expression node = AstFactory.assignmentExpression(
+    Expression node = AstTestFactory.assignmentExpression(
         _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0));
     expect(_analyze(node), same(intType));
     _listener.assertNoErrors();
@@ -465,8 +462,8 @@
         _typeProvider.futureType.instantiate(<DartType>[intType]);
     InterfaceType futureFutureIntType =
         _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
-    Expression node =
-        AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
+    Expression node = AstTestFactory
+        .awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
     expect(_analyze(node), same(intType));
     _listener.assertNoErrors();
   }
@@ -477,14 +474,14 @@
     InterfaceType futureIntType =
         _typeProvider.futureType.instantiate(<DartType>[intType]);
     Expression node =
-        AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
+        AstTestFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
     expect(_analyze(node), same(intType));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_equals() {
     // 2 == 3
-    Expression node = AstFactory.binaryExpression(
+    Expression node = AstTestFactory.binaryExpression(
         _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
@@ -492,7 +489,7 @@
 
   void test_visitBinaryExpression_ifNull() {
     // 1 ?? 1.5
-    Expression node = AstFactory.binaryExpression(
+    Expression node = AstTestFactory.binaryExpression(
         _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5));
     expect(_analyze(node), same(_typeProvider.numType));
     _listener.assertNoErrors();
@@ -500,27 +497,27 @@
 
   void test_visitBinaryExpression_logicalAnd() {
     // false && true
-    Expression node = AstFactory.binaryExpression(
-        AstFactory.booleanLiteral(false),
+    Expression node = AstTestFactory.binaryExpression(
+        AstTestFactory.booleanLiteral(false),
         TokenType.AMPERSAND_AMPERSAND,
-        AstFactory.booleanLiteral(true));
+        AstTestFactory.booleanLiteral(true));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_logicalOr() {
     // false || true
-    Expression node = AstFactory.binaryExpression(
-        AstFactory.booleanLiteral(false),
+    Expression node = AstTestFactory.binaryExpression(
+        AstTestFactory.booleanLiteral(false),
         TokenType.BAR_BAR,
-        AstFactory.booleanLiteral(true));
+        AstTestFactory.booleanLiteral(true));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitBinaryExpression_minusID_propagated() {
     // a - b
-    BinaryExpression node = AstFactory.binaryExpression(
+    BinaryExpression node = AstTestFactory.binaryExpression(
         _propagatedVariable(_typeProvider.intType, 'a'),
         TokenType.MINUS,
         _propagatedVariable(_typeProvider.doubleType, 'b'));
@@ -532,7 +529,7 @@
 
   void test_visitBinaryExpression_notEquals() {
     // 2 != 3
-    Expression node = AstFactory.binaryExpression(
+    Expression node = AstTestFactory.binaryExpression(
         _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
@@ -540,7 +537,7 @@
 
   void test_visitBinaryExpression_plusID() {
     // 1 + 2.0
-    BinaryExpression node = AstFactory.binaryExpression(
+    BinaryExpression node = AstTestFactory.binaryExpression(
         _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
     node.staticElement = getMethod(_typeProvider.numType, "+");
     expect(_analyze(node), same(_typeProvider.doubleType));
@@ -549,7 +546,7 @@
 
   void test_visitBinaryExpression_plusII() {
     // 1 + 2
-    BinaryExpression node = AstFactory.binaryExpression(
+    BinaryExpression node = AstTestFactory.binaryExpression(
         _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
     node.staticElement = getMethod(_typeProvider.numType, "+");
     expect(_analyze(node), same(_typeProvider.intType));
@@ -558,7 +555,7 @@
 
   void test_visitBinaryExpression_plusII_propagated() {
     // a + b
-    BinaryExpression node = AstFactory.binaryExpression(
+    BinaryExpression node = AstTestFactory.binaryExpression(
         _propagatedVariable(_typeProvider.intType, 'a'),
         TokenType.PLUS,
         _propagatedVariable(_typeProvider.intType, 'b'));
@@ -570,7 +567,7 @@
 
   void test_visitBinaryExpression_slash() {
     // 2 / 2
-    BinaryExpression node = AstFactory.binaryExpression(
+    BinaryExpression node = AstTestFactory.binaryExpression(
         _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
     node.staticElement = getMethod(_typeProvider.numType, "/");
     expect(_analyze(node), same(_typeProvider.doubleType));
@@ -587,9 +584,9 @@
     MethodElement operator =
         ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
     classA.methods = <MethodElement>[operator];
-    BinaryExpression node = AstFactory.binaryExpression(
-        AstFactory.asExpression(
-            AstFactory.identifier3("a"), AstFactory.typeName(classA)),
+    BinaryExpression node = AstTestFactory.binaryExpression(
+        AstTestFactory.asExpression(
+            AstTestFactory.identifier3("a"), AstTestFactory.typeName(classA)),
         TokenType.PLUS,
         _resolvedDouble(2.0));
     node.staticElement = operator;
@@ -599,7 +596,7 @@
 
   void test_visitBinaryExpression_starID() {
     // 1 * 2.0
-    BinaryExpression node = AstFactory.binaryExpression(
+    BinaryExpression node = AstTestFactory.binaryExpression(
         _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
     node.staticElement = getMethod(_typeProvider.numType, "*");
     expect(_analyze(node), same(_typeProvider.doubleType));
@@ -608,30 +605,30 @@
 
   void test_visitBooleanLiteral_false() {
     // false
-    Expression node = AstFactory.booleanLiteral(false);
+    Expression node = AstTestFactory.booleanLiteral(false);
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitBooleanLiteral_true() {
     // true
-    Expression node = AstFactory.booleanLiteral(true);
+    Expression node = AstTestFactory.booleanLiteral(true);
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitCascadeExpression() {
     // a..length
-    Expression node = AstFactory.cascadeExpression(
-        _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]);
+    Expression node = AstTestFactory.cascadeExpression(
+        _resolvedString("a"), [AstTestFactory.propertyAccess2(null, "length")]);
     expect(_analyze(node), same(_typeProvider.stringType));
     _listener.assertNoErrors();
   }
 
   void test_visitConditionalExpression_differentTypes() {
     // true ? 1.0 : 0
-    Expression node = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true),
+    Expression node = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(true),
         _resolvedDouble(1.0),
         _resolvedInteger(0));
     expect(_analyze(node), same(_typeProvider.numType));
@@ -640,8 +637,8 @@
 
   void test_visitConditionalExpression_sameTypes() {
     // true ? 1 : 0
-    Expression node = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true),
+    Expression node = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(true),
         _resolvedInteger(1),
         _resolvedInteger(0));
     expect(_analyze(node), same(_typeProvider.intType));
@@ -650,17 +647,17 @@
 
   void test_visitDoubleLiteral() {
     // 4.33
-    Expression node = AstFactory.doubleLiteral(4.33);
+    Expression node = AstTestFactory.doubleLiteral(4.33);
     expect(_analyze(node), same(_typeProvider.doubleType));
     _listener.assertNoErrors();
   }
 
   void test_visitFunctionExpression_async_block() {
     // () async {}
-    BlockFunctionBody body = AstFactory.blockFunctionBody2();
+    BlockFunctionBody body = AstTestFactory.blockFunctionBody2();
     body.keyword = TokenFactory.tokenFromString('async');
-    FunctionExpression node =
-        _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+    FunctionExpression node = _resolvedFunctionExpression(
+        AstTestFactory.formalParameterList([]), body);
     DartType resultType = _analyze(node);
     _assertFunctionType(
         _typeProvider.futureDynamicType, null, null, null, resultType);
@@ -673,10 +670,11 @@
     InterfaceType futureIntType =
         _typeProvider.futureType.instantiate(<DartType>[intType]);
     Expression expression = _resolvedVariable(intType, 'e');
-    ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
+    ExpressionFunctionBody body =
+        AstTestFactory.expressionFunctionBody(expression);
     body.keyword = TokenFactory.tokenFromString('async');
-    FunctionExpression node =
-        _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+    FunctionExpression node = _resolvedFunctionExpression(
+        AstTestFactory.formalParameterList([]), body);
     DartType resultType = _analyze(node);
     _assertFunctionType(futureIntType, null, null, null, resultType);
     _listener.assertNoErrors();
@@ -688,10 +686,11 @@
     InterfaceType futureIntType =
         _typeProvider.futureType.instantiate(<DartType>[intType]);
     Expression expression = _resolvedVariable(futureIntType, 'e');
-    ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
+    ExpressionFunctionBody body =
+        AstTestFactory.expressionFunctionBody(expression);
     body.keyword = TokenFactory.tokenFromString('async');
-    FunctionExpression node =
-        _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+    FunctionExpression node = _resolvedFunctionExpression(
+        AstTestFactory.formalParameterList([]), body);
     DartType resultType = _analyze(node);
     _assertFunctionType(futureIntType, null, null, null, resultType);
     _listener.assertNoErrors();
@@ -705,10 +704,11 @@
     InterfaceType futureFutureIntType =
         _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
     Expression expression = _resolvedVariable(futureFutureIntType, 'e');
-    ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
+    ExpressionFunctionBody body =
+        AstTestFactory.expressionFunctionBody(expression);
     body.keyword = TokenFactory.tokenFromString('async');
-    FunctionExpression node =
-        _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+    FunctionExpression node = _resolvedFunctionExpression(
+        AstTestFactory.formalParameterList([]), body);
     DartType resultType = _analyze(node);
     _assertFunctionType(futureIntType, null, null, null, resultType);
     _listener.assertNoErrors();
@@ -716,11 +716,11 @@
 
   void test_visitFunctionExpression_generator_async() {
     // () async* {}
-    BlockFunctionBody body = AstFactory.blockFunctionBody2();
+    BlockFunctionBody body = AstTestFactory.blockFunctionBody2();
     body.keyword = TokenFactory.tokenFromString('async');
     body.star = TokenFactory.tokenFromType(TokenType.STAR);
-    FunctionExpression node =
-        _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+    FunctionExpression node = _resolvedFunctionExpression(
+        AstTestFactory.formalParameterList([]), body);
     DartType resultType = _analyze(node);
     _assertFunctionType(
         _typeProvider.streamDynamicType, null, null, null, resultType);
@@ -729,11 +729,11 @@
 
   void test_visitFunctionExpression_generator_sync() {
     // () sync* {}
-    BlockFunctionBody body = AstFactory.blockFunctionBody2();
+    BlockFunctionBody body = AstTestFactory.blockFunctionBody2();
     body.keyword = TokenFactory.tokenFromString('sync');
     body.star = TokenFactory.tokenFromType(TokenType.STAR);
-    FunctionExpression node =
-        _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+    FunctionExpression node = _resolvedFunctionExpression(
+        AstTestFactory.formalParameterList([]), body);
     DartType resultType = _analyze(node);
     _assertFunctionType(
         _typeProvider.iterableDynamicType, null, null, null, resultType);
@@ -743,15 +743,15 @@
   void test_visitFunctionExpression_named_block() {
     // ({p1 : 0, p2 : 0}) {}
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
+    FormalParameter p1 = AstTestFactory.namedFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+    FormalParameter p2 = AstTestFactory.namedFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.blockFunctionBody2());
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
@@ -766,12 +766,12 @@
   void test_visitFunctionExpression_named_expression() {
     // ({p : 0}) -> 0;
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
+    FormalParameter p = AstTestFactory.namedFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
     _setType(p, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p]),
-        AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+        AstTestFactory.formalParameterList([p]),
+        AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
     _analyze5(p);
     DartType resultType = _analyze(node);
     Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
@@ -784,13 +784,13 @@
   void test_visitFunctionExpression_normal_block() {
     // (p1, p2) {}
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+    FormalParameter p1 = AstTestFactory.simpleFormalParameter3("p1");
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
+    FormalParameter p2 = AstTestFactory.simpleFormalParameter3("p2");
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.blockFunctionBody2());
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
@@ -802,11 +802,11 @@
   void test_visitFunctionExpression_normal_expression() {
     // (p1, p2) -> 0
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p = AstFactory.simpleFormalParameter3("p");
+    FormalParameter p = AstTestFactory.simpleFormalParameter3("p");
     _setType(p, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p]),
-        AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+        AstTestFactory.formalParameterList([p]),
+        AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
     _analyze5(p);
     DartType resultType = _analyze(node);
     _assertFunctionType(
@@ -817,14 +817,14 @@
   void test_visitFunctionExpression_normalAndNamed_block() {
     // (p1, {p2 : 0}) {}
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+    FormalParameter p1 = AstTestFactory.simpleFormalParameter3("p1");
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+    FormalParameter p2 = AstTestFactory.namedFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.blockFunctionBody2());
     _analyze5(p2);
     DartType resultType = _analyze(node);
     Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
@@ -837,14 +837,14 @@
   void test_visitFunctionExpression_normalAndNamed_expression() {
     // (p1, {p2 : 0}) -> 0
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+    FormalParameter p1 = AstTestFactory.simpleFormalParameter3("p1");
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.namedFormalParameter(
-        AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+    FormalParameter p2 = AstTestFactory.namedFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
     _analyze5(p2);
     DartType resultType = _analyze(node);
     Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
@@ -857,14 +857,14 @@
   void test_visitFunctionExpression_normalAndPositional_block() {
     // (p1, [p2 = 0]) {}
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+    FormalParameter p1 = AstTestFactory.simpleFormalParameter3("p1");
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+    FormalParameter p2 = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.blockFunctionBody2());
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
@@ -876,14 +876,14 @@
   void test_visitFunctionExpression_normalAndPositional_expression() {
     // (p1, [p2 = 0]) -> 0
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+    FormalParameter p1 = AstTestFactory.simpleFormalParameter3("p1");
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+    FormalParameter p2 = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
@@ -895,15 +895,15 @@
   void test_visitFunctionExpression_positional_block() {
     // ([p1 = 0, p2 = 0]) {}
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p1 = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
+    FormalParameter p1 = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
     _setType(p1, dynamicType);
-    FormalParameter p2 = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+    FormalParameter p2 = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
     _setType(p2, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p1, p2]),
-        AstFactory.blockFunctionBody2());
+        AstTestFactory.formalParameterList([p1, p2]),
+        AstTestFactory.blockFunctionBody2());
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
@@ -915,12 +915,12 @@
   void test_visitFunctionExpression_positional_expression() {
     // ([p1 = 0, p2 = 0]) -> 0
     DartType dynamicType = _typeProvider.dynamicType;
-    FormalParameter p = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
+    FormalParameter p = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
     _setType(p, dynamicType);
     FunctionExpression node = _resolvedFunctionExpression(
-        AstFactory.formalParameterList([p]),
-        AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+        AstTestFactory.formalParameterList([p]),
+        AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
     _analyze5(p);
     DartType resultType = _analyze(node);
     _assertFunctionType(
@@ -934,7 +934,7 @@
     InterfaceType listType = _typeProvider.listType;
     SimpleIdentifier identifier = _resolvedVariable(listType, "a");
     IndexExpression node =
-        AstFactory.indexExpression(identifier, _resolvedInteger(2));
+        AstTestFactory.indexExpression(identifier, _resolvedInteger(2));
     MethodElement indexMethod = listType.element.methods[0];
     node.staticElement = indexMethod;
     expect(_analyze(node), same(listType.typeArguments[0]));
@@ -947,10 +947,11 @@
     InterfaceType listType = _typeProvider.listType;
     SimpleIdentifier identifier = _resolvedVariable(listType, "a");
     IndexExpression node =
-        AstFactory.indexExpression(identifier, _resolvedInteger(2));
+        AstTestFactory.indexExpression(identifier, _resolvedInteger(2));
     MethodElement indexMethod = listType.element.methods[1];
     node.staticElement = indexMethod;
-    AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
+    AstTestFactory.assignmentExpression(
+        node, TokenType.EQ, AstTestFactory.integer(0));
     expect(_analyze(node), same(listType.typeArguments[0]));
     _listener.assertNoErrors();
   }
@@ -963,12 +964,12 @@
     // (int) -> E
     MethodElement methodElement = getMethod(listType, "[]");
     // "list" has type List<int>
-    SimpleIdentifier identifier = AstFactory.identifier3("list");
+    SimpleIdentifier identifier = AstTestFactory.identifier3("list");
     InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
     identifier.staticType = listOfIntType;
     // list[0] has MethodElement element (int) -> E
     IndexExpression indexExpression =
-        AstFactory.indexExpression(identifier, AstFactory.integer(0));
+        AstTestFactory.indexExpression(identifier, AstTestFactory.integer(0));
     MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
     indexExpression.staticElement = indexMethod;
     // analyze and assert result of the index expression
@@ -984,17 +985,17 @@
     // (int, E) -> void
     MethodElement methodElement = getMethod(listType, "[]=");
     // "list" has type List<int>
-    SimpleIdentifier identifier = AstFactory.identifier3("list");
+    SimpleIdentifier identifier = AstTestFactory.identifier3("list");
     InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
     identifier.staticType = listOfIntType;
     // list[0] has MethodElement element (int) -> E
     IndexExpression indexExpression =
-        AstFactory.indexExpression(identifier, AstFactory.integer(0));
+        AstTestFactory.indexExpression(identifier, AstTestFactory.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));
+    AstTestFactory.assignmentExpression(
+        indexExpression, TokenType.EQ, AstTestFactory.integer(0));
     // analyze and assert result of the index expression
     expect(_analyze(indexExpression), same(intType));
     _listener.assertNoErrors();
@@ -1007,10 +1008,11 @@
     ConstructorElementImpl constructor =
         ElementFactory.constructorElement2(classElement, constructorName);
     classElement.constructors = <ConstructorElement>[constructor];
-    InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
-        null,
-        AstFactory.typeName(classElement),
-        [AstFactory.identifier3(constructorName)]);
+    InstanceCreationExpression node = AstTestFactory
+        .instanceCreationExpression2(
+            null,
+            AstTestFactory.typeName(classElement),
+            [AstTestFactory.identifier3(constructorName)]);
     node.staticElement = constructor;
     expect(_analyze(node), same(classElement.type));
     _listener.assertNoErrors();
@@ -1024,10 +1026,10 @@
         ElementFactory.constructorElement2(elementC, null);
     elementC.constructors = <ConstructorElement>[constructor];
     TypeName typeName =
-        AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
+        AstTestFactory.typeName(elementC, [AstTestFactory.typeName(elementI)]);
     typeName.type = elementC.type.instantiate(<DartType>[elementI.type]);
     InstanceCreationExpression node =
-        AstFactory.instanceCreationExpression2(null, typeName);
+        AstTestFactory.instanceCreationExpression2(null, typeName);
     node.staticElement = constructor;
     InterfaceType interfaceType = _analyze(node) as InterfaceType;
     List<DartType> typeArgs = interfaceType.typeArguments;
@@ -1042,8 +1044,9 @@
     ConstructorElementImpl constructor =
         ElementFactory.constructorElement2(classElement, null);
     classElement.constructors = <ConstructorElement>[constructor];
-    InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
-        null, AstFactory.typeName(classElement));
+    InstanceCreationExpression node =
+        AstTestFactory.instanceCreationExpression2(
+            null, AstTestFactory.typeName(classElement));
     node.staticElement = constructor;
     expect(_analyze(node), same(classElement.type));
     _listener.assertNoErrors();
@@ -1058,23 +1061,23 @@
 
   void test_visitIsExpression_negated() {
     // a is! String
-    Expression node = AstFactory.isExpression(
-        _resolvedString("a"), true, AstFactory.typeName4("String"));
+    Expression node = AstTestFactory.isExpression(
+        _resolvedString("a"), true, AstTestFactory.typeName4("String"));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitIsExpression_notNegated() {
     // a is String
-    Expression node = AstFactory.isExpression(
-        _resolvedString("a"), false, AstFactory.typeName4("String"));
+    Expression node = AstTestFactory.isExpression(
+        _resolvedString("a"), false, AstTestFactory.typeName4("String"));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitListLiteral_empty() {
     // []
-    Expression node = AstFactory.listLiteral();
+    Expression node = AstTestFactory.listLiteral();
     DartType resultType = _analyze(node);
     _assertType2(
         _typeProvider.listType
@@ -1085,7 +1088,7 @@
 
   void test_visitListLiteral_nonEmpty() {
     // [0]
-    Expression node = AstFactory.listLiteral([_resolvedInteger(0)]);
+    Expression node = AstTestFactory.listLiteral([_resolvedInteger(0)]);
     DartType resultType = _analyze(node);
     _assertType2(
         _typeProvider.listType
@@ -1097,8 +1100,8 @@
   void test_visitListLiteral_unresolved() {
     _analyzer = _createAnalyzer(strongMode: true);
     // [a] // where 'a' is not resolved
-    Identifier identifier = AstFactory.identifier3('a');
-    Expression node = AstFactory.listLiteral([identifier]);
+    Identifier identifier = AstTestFactory.identifier3('a');
+    Expression node = AstTestFactory.listLiteral([identifier]);
     DartType resultType = _analyze(node);
     _assertType2(
         _typeProvider.listType
@@ -1110,8 +1113,8 @@
   void test_visitListLiteral_unresolved_multiple() {
     _analyzer = _createAnalyzer(strongMode: true);
     // [0, a, 1] // where 'a' is not resolved
-    Identifier identifier = AstFactory.identifier3('a');
-    Expression node = AstFactory
+    Identifier identifier = AstTestFactory.identifier3('a');
+    Expression node = AstTestFactory
         .listLiteral([_resolvedInteger(0), identifier, _resolvedInteger(1)]);
     DartType resultType = _analyze(node);
     _assertType2(
@@ -1122,7 +1125,7 @@
 
   void test_visitMapLiteral_empty() {
     // {}
-    Expression node = AstFactory.mapLiteral2();
+    Expression node = AstTestFactory.mapLiteral2();
     DartType resultType = _analyze(node);
     _assertType2(
         _typeProvider.mapType.instantiate(
@@ -1133,8 +1136,8 @@
 
   void test_visitMapLiteral_nonEmpty() {
     // {"k" : 0}
-    Expression node = AstFactory
-        .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
+    Expression node = AstTestFactory.mapLiteral2(
+        [AstTestFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
     DartType resultType = _analyze(node);
     _assertType2(
         _typeProvider.mapType.instantiate(
@@ -1145,35 +1148,37 @@
 
   void test_visitMethodInvocation_then() {
     // then()
-    Expression node = AstFactory.methodInvocation(null, "then");
+    Expression node = AstTestFactory.methodInvocation(null, "then");
     _analyze(node);
     _listener.assertNoErrors();
   }
 
   void test_visitNamedExpression() {
     // n: a
-    Expression node = AstFactory.namedExpression2("n", _resolvedString("a"));
+    Expression node =
+        AstTestFactory.namedExpression2("n", _resolvedString("a"));
     expect(_analyze(node), same(_typeProvider.stringType));
     _listener.assertNoErrors();
   }
 
   void test_visitNullLiteral() {
     // null
-    Expression node = AstFactory.nullLiteral();
+    Expression node = AstTestFactory.nullLiteral();
     expect(_analyze(node), same(_typeProvider.bottomType));
     _listener.assertNoErrors();
   }
 
   void test_visitParenthesizedExpression() {
     // (0)
-    Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0));
+    Expression node =
+        AstTestFactory.parenthesizedExpression(_resolvedInteger(0));
     expect(_analyze(node), same(_typeProvider.intType));
     _listener.assertNoErrors();
   }
 
   void test_visitPostfixExpression_minusMinus() {
     // 0--
-    PostfixExpression node = AstFactory.postfixExpression(
+    PostfixExpression node = AstTestFactory.postfixExpression(
         _resolvedInteger(0), TokenType.MINUS_MINUS);
     expect(_analyze(node), same(_typeProvider.intType));
     _listener.assertNoErrors();
@@ -1181,8 +1186,8 @@
 
   void test_visitPostfixExpression_plusPlus() {
     // 0++
-    PostfixExpression node =
-        AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS);
+    PostfixExpression node = AstTestFactory.postfixExpression(
+        _resolvedInteger(0), TokenType.PLUS_PLUS);
     expect(_analyze(node), same(_typeProvider.intType));
     _listener.assertNoErrors();
   }
@@ -1191,7 +1196,7 @@
     DartType boolType = _typeProvider.boolType;
     PropertyAccessorElementImpl getter =
         ElementFactory.getterElement("b", false, boolType);
-    PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+    PrefixedIdentifier node = AstTestFactory.identifier5("a", "b");
     node.identifier.staticElement = getter;
     expect(_analyze(node), same(boolType));
     _listener.assertNoErrors();
@@ -1202,7 +1207,7 @@
     FieldElementImpl field =
         ElementFactory.fieldElement("b", false, false, false, boolType);
     PropertyAccessorElement setter = field.setter;
-    PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+    PrefixedIdentifier node = AstTestFactory.identifier5("a", "b");
     node.identifier.staticElement = setter;
     expect(_analyze(node), same(boolType));
     _listener.assertNoErrors();
@@ -1211,7 +1216,7 @@
   void test_visitPrefixedIdentifier_variable() {
     VariableElementImpl variable = ElementFactory.localVariableElement2("b");
     variable.type = _typeProvider.boolType;
-    PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+    PrefixedIdentifier node = AstTestFactory.identifier5("a", "b");
     node.identifier.staticElement = variable;
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
@@ -1220,7 +1225,7 @@
   void test_visitPrefixExpression_bang() {
     // !0
     PrefixExpression node =
-        AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
+        AstTestFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
@@ -1228,7 +1233,7 @@
   void test_visitPrefixExpression_minus() {
     // -0
     PrefixExpression node =
-        AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
+        AstTestFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
     MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
     node.staticElement = minusMethod;
     expect(_analyze(node), same(_typeProvider.numType));
@@ -1237,8 +1242,8 @@
 
   void test_visitPrefixExpression_minusMinus() {
     // --0
-    PrefixExpression node =
-        AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0));
+    PrefixExpression node = AstTestFactory.prefixExpression(
+        TokenType.MINUS_MINUS, _resolvedInteger(0));
     MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
     node.staticElement = minusMethod;
     expect(_analyze(node), same(_typeProvider.intType));
@@ -1247,16 +1252,16 @@
 
   void test_visitPrefixExpression_not() {
     // !true
-    Expression node = AstFactory.prefixExpression(
-        TokenType.BANG, AstFactory.booleanLiteral(true));
+    Expression node = AstTestFactory.prefixExpression(
+        TokenType.BANG, AstTestFactory.booleanLiteral(true));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
 
   void test_visitPrefixExpression_plusPlus() {
     // ++0
-    PrefixExpression node =
-        AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0));
+    PrefixExpression node = AstTestFactory.prefixExpression(
+        TokenType.PLUS_PLUS, _resolvedInteger(0));
     MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
     node.staticElement = plusMethod;
     expect(_analyze(node), same(_typeProvider.intType));
@@ -1266,7 +1271,7 @@
   void test_visitPrefixExpression_tilde() {
     // ~0
     PrefixExpression node =
-        AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
+        AstTestFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
     MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
     node.staticElement = tildeMethod;
     expect(_analyze(node), same(_typeProvider.intType));
@@ -1278,7 +1283,7 @@
     PropertyAccessorElementImpl getter =
         ElementFactory.getterElement("b", false, boolType);
     PropertyAccess node =
-        AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("a"), "b");
     node.propertyName.propagatedElement = getter;
     expect(_analyze2(node, false), same(boolType));
     _listener.assertNoErrors();
@@ -1290,7 +1295,7 @@
         ElementFactory.fieldElement("b", false, false, false, boolType);
     PropertyAccessorElement setter = field.setter;
     PropertyAccess node =
-        AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("a"), "b");
     node.propertyName.propagatedElement = setter;
     expect(_analyze2(node, false), same(boolType));
     _listener.assertNoErrors();
@@ -1301,7 +1306,7 @@
     PropertyAccessorElementImpl getter =
         ElementFactory.getterElement("b", false, boolType);
     PropertyAccess node =
-        AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("a"), "b");
     node.propertyName.staticElement = getter;
     expect(_analyze(node), same(boolType));
     _listener.assertNoErrors();
@@ -1313,7 +1318,7 @@
         ElementFactory.fieldElement("b", false, false, false, boolType);
     PropertyAccessorElement setter = field.setter;
     PropertyAccess node =
-        AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("a"), "b");
     node.propertyName.staticElement = setter;
     expect(_analyze(node), same(boolType));
     _listener.assertNoErrors();
@@ -1321,7 +1326,7 @@
 
   void test_visitSimpleIdentifier_dynamic() {
     // "dynamic"
-    SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
+    SimpleIdentifier identifier = AstTestFactory.identifier3('dynamic');
     DynamicElementImpl element = DynamicElementImpl.instance;
     identifier.staticElement = element;
     identifier.staticType = _typeProvider.typeType;
@@ -1338,10 +1343,10 @@
 
   void test_visitStringInterpolation() {
     // "a${'b'}c"
-    Expression node = AstFactory.string([
-      AstFactory.interpolationString("a", "a"),
-      AstFactory.interpolationExpression(_resolvedString("b")),
-      AstFactory.interpolationString("c", "c")
+    Expression node = AstTestFactory.string([
+      AstTestFactory.interpolationString("a", "a"),
+      AstTestFactory.interpolationExpression(_resolvedString("b")),
+      AstTestFactory.interpolationString("c", "c")
     ]);
     expect(_analyze(node), same(_typeProvider.stringType));
     _listener.assertNoErrors();
@@ -1351,13 +1356,13 @@
     // super
     InterfaceType superType = ElementFactory.classElement2("A").type;
     InterfaceType thisType = ElementFactory.classElement("B", superType).type;
-    Expression node = AstFactory.superExpression();
+    Expression node = AstTestFactory.superExpression();
     expect(_analyze3(node, thisType), same(thisType));
     _listener.assertNoErrors();
   }
 
   void test_visitSymbolLiteral() {
-    expect(_analyze(AstFactory.symbolLiteral(["a"])),
+    expect(_analyze(AstTestFactory.symbolLiteral(["a"])),
         same(_typeProvider.symbolType));
   }
 
@@ -1366,21 +1371,21 @@
     InterfaceType thisType = ElementFactory
         .classElement("B", ElementFactory.classElement2("A").type)
         .type;
-    Expression node = AstFactory.thisExpression();
+    Expression node = AstTestFactory.thisExpression();
     expect(_analyze3(node, thisType), same(thisType));
     _listener.assertNoErrors();
   }
 
   void test_visitThrowExpression_withoutValue() {
     // throw
-    Expression node = AstFactory.throwExpression();
+    Expression node = AstTestFactory.throwExpression();
     expect(_analyze(node), same(_typeProvider.bottomType));
     _listener.assertNoErrors();
   }
 
   void test_visitThrowExpression_withValue() {
     // throw 0
-    Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
+    Expression node = AstTestFactory.throwExpression2(_resolvedInteger(0));
     expect(_analyze(node), same(_typeProvider.bottomType));
     _listener.assertNoErrors();
   }
@@ -1565,7 +1570,7 @@
    */
   SimpleIdentifier _propagatedVariable(
       InterfaceType type, String variableName) {
-    SimpleIdentifier identifier = AstFactory.identifier3(variableName);
+    SimpleIdentifier identifier = AstTestFactory.identifier3(variableName);
     VariableElementImpl element =
         ElementFactory.localVariableElement(identifier);
     element.type = type;
@@ -1580,7 +1585,7 @@
    * the correct type.
    */
   BooleanLiteral _resolvedBool(bool value) {
-    BooleanLiteral literal = AstFactory.booleanLiteral(value);
+    BooleanLiteral literal = AstTestFactory.booleanLiteral(value);
     literal.staticType = _typeProvider.intType;
     return literal;
   }
@@ -1592,7 +1597,7 @@
    * @return an integer literal that has been resolved to the correct type
    */
   DoubleLiteral _resolvedDouble(double value) {
-    DoubleLiteral literal = AstFactory.doubleLiteral(value);
+    DoubleLiteral literal = AstTestFactory.doubleLiteral(value);
     literal.staticType = _typeProvider.doubleType;
     return literal;
   }
@@ -1618,7 +1623,8 @@
       parameter.identifier.staticElement = element;
       parameterElements.add(element);
     }
-    FunctionExpression node = AstFactory.functionExpression2(parameters, body);
+    FunctionExpression node =
+        AstTestFactory.functionExpression2(parameters, body);
     FunctionElementImpl element = new FunctionElementImpl.forNode(null);
     element.parameters = parameterElements;
     element.type = new FunctionTypeImpl(element);
@@ -1633,7 +1639,7 @@
    * @return an integer literal that has been resolved to the correct type
    */
   IntegerLiteral _resolvedInteger(int value) {
-    IntegerLiteral literal = AstFactory.integer(value);
+    IntegerLiteral literal = AstTestFactory.integer(value);
     literal.staticType = _typeProvider.intType;
     return literal;
   }
@@ -1645,7 +1651,7 @@
    * @return a string literal that has been resolved to the correct type
    */
   SimpleStringLiteral _resolvedString(String value) {
-    SimpleStringLiteral string = AstFactory.string2(value);
+    SimpleStringLiteral string = AstTestFactory.string2(value);
     string.staticType = _typeProvider.stringType;
     return string;
   }
@@ -1658,7 +1664,7 @@
    * @return a simple identifier that has been resolved to a variable element with the given type
    */
   SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
-    SimpleIdentifier identifier = AstFactory.identifier3(variableName);
+    SimpleIdentifier identifier = AstTestFactory.identifier3(variableName);
     VariableElementImpl element =
         ElementFactory.localVariableElement(identifier);
     element.type = type;
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index ae8bdca..1fc56f4 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -3374,7 +3374,6 @@
   }
 
   void test_typeAnnotationGenericFunctionParameter_localFunction() {
-    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
     Source source = addSource(r'''
 class A {
   void method() {
@@ -3390,7 +3389,6 @@
   }
 
   void test_typeAnnotationGenericFunctionParameter_method() {
-    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
     Source source = addSource(r'''
 class A {
   T method<T>(Object t) {
@@ -3404,7 +3402,6 @@
   }
 
   void test_typeAnnotationGenericFunctionParameter_topLevelFunction() {
-    resetWithOptions(new AnalysisOptionsImpl()..enableGenericMethods = true);
     Source source = addSource(r'''
 T function<T>(Object t) {
   return (t is T) ? t : null;
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 2c57df9..88b88d5 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -16,7 +16,7 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:test/test.dart';
@@ -2951,8 +2951,8 @@
   static const List<Token> EMPTY_TOKEN_LIST = const <Token>[];
 
   void test_adjacentStrings() {
-    AdjacentStrings node = AstFactory
-        .adjacentStrings([AstFactory.string2("a"), AstFactory.string2("b")]);
+    AdjacentStrings node = AstTestFactory.adjacentStrings(
+        [AstTestFactory.string2("a"), AstTestFactory.string2("b")]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_adjacentStrings_2(0));
     _assertReplace(
@@ -2960,39 +2960,42 @@
   }
 
   void test_annotation() {
-    Annotation node = AstFactory.annotation2(
-        AstFactory.identifier3("C"),
-        AstFactory.identifier3("c"),
-        AstFactory.argumentList([AstFactory.integer(0)]));
+    Annotation node = AstTestFactory.annotation2(
+        AstTestFactory.identifier3("C"),
+        AstTestFactory.identifier3("c"),
+        AstTestFactory.argumentList([AstTestFactory.integer(0)]));
     _assertReplace(node, new Getter_NodeReplacerTest_test_annotation());
     _assertReplace(node, new Getter_NodeReplacerTest_test_annotation_3());
     _assertReplace(node, new Getter_NodeReplacerTest_test_annotation_2());
   }
 
   void test_argumentList() {
-    ArgumentList node = AstFactory.argumentList([AstFactory.integer(0)]);
+    ArgumentList node =
+        AstTestFactory.argumentList([AstTestFactory.integer(0)]);
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_argumentList(0));
   }
 
   void test_asExpression() {
-    AsExpression node = AstFactory.asExpression(
-        AstFactory.integer(0),
-        AstFactory.typeName3(
-            AstFactory.identifier3("a"), [AstFactory.typeName4("C")]));
+    AsExpression node = AstTestFactory.asExpression(
+        AstTestFactory.integer(0),
+        AstTestFactory.typeName3(
+            AstTestFactory.identifier3("a"), [AstTestFactory.typeName4("C")]));
     _assertReplace(node, new Getter_NodeReplacerTest_test_asExpression_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_asExpression());
   }
 
   void test_assertStatement() {
-    AssertStatement node = AstFactory.assertStatement(
-        AstFactory.booleanLiteral(true), AstFactory.string2('foo'));
+    AssertStatement node = AstTestFactory.assertStatement(
+        AstTestFactory.booleanLiteral(true), AstTestFactory.string2('foo'));
     _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement());
     _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement_2());
   }
 
   void test_assignmentExpression() {
-    AssignmentExpression node = AstFactory.assignmentExpression(
-        AstFactory.identifier3("l"), TokenType.EQ, AstFactory.identifier3("r"));
+    AssignmentExpression node = AstTestFactory.assignmentExpression(
+        AstTestFactory.identifier3("l"),
+        TokenType.EQ,
+        AstTestFactory.identifier3("r"));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_assignmentExpression_2());
     _assertReplace(
@@ -3000,65 +3003,71 @@
   }
 
   void test_awaitExpression() {
-    var node = AstFactory.awaitExpression(AstFactory.identifier3("A"));
+    var node = AstTestFactory.awaitExpression(AstTestFactory.identifier3("A"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_awaitExpression());
   }
 
   void test_binaryExpression() {
-    BinaryExpression node = AstFactory.binaryExpression(
-        AstFactory.identifier3("l"),
+    BinaryExpression node = AstTestFactory.binaryExpression(
+        AstTestFactory.identifier3("l"),
         TokenType.PLUS,
-        AstFactory.identifier3("r"));
+        AstTestFactory.identifier3("r"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_binaryExpression());
     _assertReplace(node, new Getter_NodeReplacerTest_test_binaryExpression_2());
   }
 
   void test_block() {
-    Block node = AstFactory.block([AstFactory.emptyStatement()]);
+    Block node = AstTestFactory.block([AstTestFactory.emptyStatement()]);
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_block(0));
   }
 
   void test_blockFunctionBody() {
-    BlockFunctionBody node = AstFactory.blockFunctionBody(AstFactory.block());
+    BlockFunctionBody node =
+        AstTestFactory.blockFunctionBody(AstTestFactory.block());
     _assertReplace(node, new Getter_NodeReplacerTest_test_blockFunctionBody());
   }
 
   void test_breakStatement() {
-    BreakStatement node = AstFactory.breakStatement2("l");
+    BreakStatement node = AstTestFactory.breakStatement2("l");
     _assertReplace(node, new Getter_NodeReplacerTest_test_breakStatement());
   }
 
   void test_cascadeExpression() {
-    CascadeExpression node = AstFactory.cascadeExpression(AstFactory.integer(0),
-        [AstFactory.propertyAccess(null, AstFactory.identifier3("b"))]);
+    CascadeExpression node = AstTestFactory.cascadeExpression(
+        AstTestFactory.integer(0),
+        [AstTestFactory.propertyAccess(null, AstTestFactory.identifier3("b"))]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_cascadeExpression());
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_cascadeExpression(0));
   }
 
   void test_catchClause() {
-    CatchClause node = AstFactory.catchClause5(
-        AstFactory.typeName4("E"), "e", "s", [AstFactory.emptyStatement()]);
+    CatchClause node = AstTestFactory.catchClause5(
+        AstTestFactory.typeName4("E"),
+        "e",
+        "s",
+        [AstTestFactory.emptyStatement()]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_catchClause_3());
     _assertReplace(node, new Getter_NodeReplacerTest_test_catchClause_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_catchClause());
   }
 
   void test_classDeclaration() {
-    ClassDeclaration node = AstFactory.classDeclaration(
+    ClassDeclaration node = AstTestFactory.classDeclaration(
         null,
         "A",
-        AstFactory.typeParameterList(["E"]),
-        AstFactory.extendsClause(AstFactory.typeName4("B")),
-        AstFactory.withClause([AstFactory.typeName4("C")]),
-        AstFactory.implementsClause([AstFactory.typeName4("D")]), [
-      AstFactory
-          .fieldDeclaration2(false, null, [AstFactory.variableDeclaration("f")])
+        AstTestFactory.typeParameterList(["E"]),
+        AstTestFactory.extendsClause(AstTestFactory.typeName4("B")),
+        AstTestFactory.withClause([AstTestFactory.typeName4("C")]),
+        AstTestFactory.implementsClause([AstTestFactory.typeName4("D")]), [
+      AstTestFactory.fieldDeclaration2(
+          false, null, [AstTestFactory.variableDeclaration("f")])
     ]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
-    node.nativeClause = AstFactory.nativeClause("");
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
+    node.nativeClause = AstTestFactory.nativeClause("");
     _assertReplace(node, new Getter_NodeReplacerTest_test_classDeclaration_6());
     _assertReplace(node, new Getter_NodeReplacerTest_test_classDeclaration_5());
     _assertReplace(node, new Getter_NodeReplacerTest_test_classDeclaration_4());
@@ -3071,16 +3080,17 @@
   }
 
   void test_classTypeAlias() {
-    ClassTypeAlias node = AstFactory.classTypeAlias(
+    ClassTypeAlias node = AstTestFactory.classTypeAlias(
         "A",
-        AstFactory.typeParameterList(["E"]),
+        AstTestFactory.typeParameterList(["E"]),
         null,
-        AstFactory.typeName4("B"),
-        AstFactory.withClause([AstFactory.typeName4("C")]),
-        AstFactory.implementsClause([AstFactory.typeName4("D")]));
+        AstTestFactory.typeName4("B"),
+        AstTestFactory.withClause([AstTestFactory.typeName4("C")]),
+        AstTestFactory.implementsClause([AstTestFactory.typeName4("D")]));
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_classTypeAlias_4());
     _assertReplace(node, new Getter_NodeReplacerTest_test_classTypeAlias_5());
     _assertReplace(node, new Getter_NodeReplacerTest_test_classTypeAlias());
@@ -3092,22 +3102,22 @@
   void test_comment() {
     Comment node = Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
     node.references
-        .add(new CommentReference(null, AstFactory.identifier3("x")));
+        .add(new CommentReference(null, AstTestFactory.identifier3("x")));
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_comment(0));
   }
 
   void test_commentReference() {
     CommentReference node =
-        new CommentReference(null, AstFactory.identifier3("x"));
+        new CommentReference(null, AstTestFactory.identifier3("x"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_commentReference());
   }
 
   void test_compilationUnit() {
-    CompilationUnit node = AstFactory.compilationUnit8("", [
-      AstFactory.libraryDirective2("lib")
+    CompilationUnit node = AstTestFactory.compilationUnit8("", [
+      AstTestFactory.libraryDirective2("lib")
     ], [
-      AstFactory.topLevelVariableDeclaration2(
-          null, [AstFactory.variableDeclaration("X")])
+      AstTestFactory.topLevelVariableDeclaration2(
+          null, [AstTestFactory.variableDeclaration("X")])
     ]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_compilationUnit());
     _assertReplace(
@@ -3117,10 +3127,10 @@
   }
 
   void test_conditionalExpression() {
-    ConditionalExpression node = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true),
-        AstFactory.integer(0),
-        AstFactory.integer(1));
+    ConditionalExpression node = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(true),
+        AstTestFactory.integer(0),
+        AstTestFactory.integer(1));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_conditionalExpression_3());
     _assertReplace(
@@ -3130,22 +3140,23 @@
   }
 
   void test_constructorDeclaration() {
-    ConstructorDeclaration node = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration node = AstTestFactory.constructorDeclaration2(
         null,
         null,
-        AstFactory.identifier3("C"),
+        AstTestFactory.identifier3("C"),
         "d",
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         [
-          AstFactory.constructorFieldInitializer(
-              false, "x", AstFactory.integer(0))
+          AstTestFactory.constructorFieldInitializer(
+              false, "x", AstTestFactory.integer(0))
         ],
-        AstFactory.emptyFunctionBody());
+        AstTestFactory.emptyFunctionBody());
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     node.redirectedConstructor =
-        AstFactory.constructorName(AstFactory.typeName4("B"), "a");
+        AstTestFactory.constructorName(AstTestFactory.typeName4("B"), "a");
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_constructorDeclaration_3());
     _assertReplace(
@@ -3162,8 +3173,8 @@
   }
 
   void test_constructorFieldInitializer() {
-    ConstructorFieldInitializer node = AstFactory.constructorFieldInitializer(
-        false, "f", AstFactory.integer(0));
+    ConstructorFieldInitializer node = AstTestFactory
+        .constructorFieldInitializer(false, "f", AstTestFactory.integer(0));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_constructorFieldInitializer());
     _assertReplace(
@@ -3172,22 +3183,23 @@
 
   void test_constructorName() {
     ConstructorName node =
-        AstFactory.constructorName(AstFactory.typeName4("C"), "n");
+        AstTestFactory.constructorName(AstTestFactory.typeName4("C"), "n");
     _assertReplace(node, new Getter_NodeReplacerTest_test_constructorName());
     _assertReplace(node, new Getter_NodeReplacerTest_test_constructorName_2());
   }
 
   void test_continueStatement() {
-    ContinueStatement node = AstFactory.continueStatement("l");
+    ContinueStatement node = AstTestFactory.continueStatement("l");
     _assertReplace(node, new Getter_NodeReplacerTest_test_continueStatement());
   }
 
   void test_declaredIdentifier() {
     DeclaredIdentifier node =
-        AstFactory.declaredIdentifier4(AstFactory.typeName4("C"), "i");
+        AstTestFactory.declaredIdentifier4(AstTestFactory.typeName4("C"), "i");
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_declaredIdentifier());
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_declaredIdentifier_2());
@@ -3195,8 +3207,8 @@
   }
 
   void test_defaultFormalParameter() {
-    DefaultFormalParameter node = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0));
+    DefaultFormalParameter node = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p"), AstTestFactory.integer(0));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_defaultFormalParameter());
     _assertReplace(
@@ -3204,8 +3216,8 @@
   }
 
   void test_doStatement() {
-    DoStatement node = AstFactory.doStatement(
-        AstFactory.block(), AstFactory.booleanLiteral(true));
+    DoStatement node = AstTestFactory.doStatement(
+        AstTestFactory.block(), AstTestFactory.booleanLiteral(true));
     _assertReplace(node, new Getter_NodeReplacerTest_test_doStatement_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_doStatement());
   }
@@ -3213,67 +3225,79 @@
   void test_enumConstantDeclaration() {
     EnumConstantDeclaration node = new EnumConstantDeclaration(
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST),
-        [AstFactory.annotation(AstFactory.identifier3("a"))],
-        AstFactory.identifier3("C"));
+        [AstTestFactory.annotation(AstTestFactory.identifier3("a"))],
+        AstTestFactory.identifier3("C"));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_enumConstantDeclaration());
     _testAnnotatedNode(node);
   }
 
   void test_enumDeclaration() {
-    EnumDeclaration node = AstFactory.enumDeclaration2("E", ["ONE", "TWO"]);
+    EnumDeclaration node = AstTestFactory.enumDeclaration2("E", ["ONE", "TWO"]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_enumDeclaration());
     _testAnnotatedNode(node);
   }
 
   void test_exportDirective() {
-    ExportDirective node = AstFactory.exportDirective2("", [
-      AstFactory.hideCombinator2(["C"])
+    ExportDirective node = AstTestFactory.exportDirective2("", [
+      AstTestFactory.hideCombinator2(["C"])
     ]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _testNamespaceDirective(node);
   }
 
   void test_expressionFunctionBody() {
     ExpressionFunctionBody node =
-        AstFactory.expressionFunctionBody(AstFactory.integer(0));
+        AstTestFactory.expressionFunctionBody(AstTestFactory.integer(0));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_expressionFunctionBody());
   }
 
   void test_expressionStatement() {
     ExpressionStatement node =
-        AstFactory.expressionStatement(AstFactory.integer(0));
+        AstTestFactory.expressionStatement(AstTestFactory.integer(0));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_expressionStatement());
   }
 
   void test_extendsClause() {
-    ExtendsClause node = AstFactory.extendsClause(AstFactory.typeName4("S"));
+    ExtendsClause node =
+        AstTestFactory.extendsClause(AstTestFactory.typeName4("S"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_extendsClause());
   }
 
   void test_fieldDeclaration() {
-    FieldDeclaration node = AstFactory.fieldDeclaration(false, null,
-        AstFactory.typeName4("C"), [AstFactory.variableDeclaration("c")]);
+    FieldDeclaration node = AstTestFactory.fieldDeclaration(
+        false,
+        null,
+        AstTestFactory.typeName4("C"),
+        [AstTestFactory.variableDeclaration("c")]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_fieldDeclaration());
     _testAnnotatedNode(node);
   }
 
   void test_fieldFormalParameter() {
-    FieldFormalParameter node = AstFactory.fieldFormalParameter(
-        null, AstFactory.typeName4("C"), "f", AstFactory.formalParameterList());
+    FieldFormalParameter node = AstTestFactory.fieldFormalParameter(
+        null,
+        AstTestFactory.typeName4("C"),
+        "f",
+        AstTestFactory.formalParameterList());
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata = [AstFactory.annotation(AstFactory.identifier3("a"))];
+    node.metadata = [
+      AstTestFactory.annotation(AstTestFactory.identifier3("a"))
+    ];
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_fieldFormalParameter_2());
     _assertReplace(
@@ -3282,10 +3306,10 @@
   }
 
   void test_forEachStatement_withIdentifier() {
-    ForEachStatement node = AstFactory.forEachStatement2(
-        AstFactory.identifier3("i"),
-        AstFactory.identifier3("l"),
-        AstFactory.block());
+    ForEachStatement node = AstTestFactory.forEachStatement2(
+        AstTestFactory.identifier3("i"),
+        AstTestFactory.identifier3("l"),
+        AstTestFactory.block());
     _assertReplace(node,
         new Getter_NodeReplacerTest_test_forEachStatement_withIdentifier_2());
     _assertReplace(node,
@@ -3295,10 +3319,10 @@
   }
 
   void test_forEachStatement_withLoopVariable() {
-    ForEachStatement node = AstFactory.forEachStatement(
-        AstFactory.declaredIdentifier3("e"),
-        AstFactory.identifier3("l"),
-        AstFactory.block());
+    ForEachStatement node = AstTestFactory.forEachStatement(
+        AstTestFactory.declaredIdentifier3("e"),
+        AstTestFactory.identifier3("l"),
+        AstTestFactory.block());
     _assertReplace(node,
         new Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable_2());
     _assertReplace(node,
@@ -3308,18 +3332,18 @@
   }
 
   void test_formalParameterList() {
-    FormalParameterList node = AstFactory
-        .formalParameterList([AstFactory.simpleFormalParameter3("p")]);
+    FormalParameterList node = AstTestFactory
+        .formalParameterList([AstTestFactory.simpleFormalParameter3("p")]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_formalParameterList(0));
   }
 
   void test_forStatement_withInitialization() {
-    ForStatement node = AstFactory.forStatement(
-        AstFactory.identifier3("a"),
-        AstFactory.booleanLiteral(true),
-        [AstFactory.integer(0)],
-        AstFactory.block());
+    ForStatement node = AstTestFactory.forStatement(
+        AstTestFactory.identifier3("a"),
+        AstTestFactory.booleanLiteral(true),
+        [AstTestFactory.integer(0)],
+        AstTestFactory.block());
     _assertReplace(node,
         new Getter_NodeReplacerTest_test_forStatement_withInitialization_3());
     _assertReplace(node,
@@ -3333,12 +3357,12 @@
   }
 
   void test_forStatement_withVariables() {
-    ForStatement node = AstFactory.forStatement2(
-        AstFactory.variableDeclarationList2(
-            null, [AstFactory.variableDeclaration("i")]),
-        AstFactory.booleanLiteral(true),
-        [AstFactory.integer(0)],
-        AstFactory.block());
+    ForStatement node = AstTestFactory.forStatement2(
+        AstTestFactory.variableDeclarationList2(
+            null, [AstTestFactory.variableDeclaration("i")]),
+        AstTestFactory.booleanLiteral(true),
+        [AstTestFactory.integer(0)],
+        AstTestFactory.block());
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_forStatement_withVariables_2());
     _assertReplace(
@@ -3350,15 +3374,16 @@
   }
 
   void test_functionDeclaration() {
-    FunctionDeclaration node = AstFactory.functionDeclaration(
-        AstFactory.typeName4("R"),
+    FunctionDeclaration node = AstTestFactory.functionDeclaration(
+        AstTestFactory.typeName4("R"),
         null,
         "f",
-        AstFactory.functionExpression2(AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody(AstFactory.block())));
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody(AstTestFactory.block())));
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_functionDeclaration());
     _assertReplace(
@@ -3369,28 +3394,31 @@
   }
 
   void test_functionDeclarationStatement() {
-    FunctionDeclarationStatement node = AstFactory.functionDeclarationStatement(
-        AstFactory.typeName4("R"),
-        null,
-        "f",
-        AstFactory.functionExpression2(AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody(AstFactory.block())));
+    FunctionDeclarationStatement node =
+        AstTestFactory.functionDeclarationStatement(
+            AstTestFactory.typeName4("R"),
+            null,
+            "f",
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody(AstTestFactory.block())));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_functionDeclarationStatement());
   }
 
   void test_functionExpression() {
-    FunctionExpression node = AstFactory.functionExpression2(
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody(AstFactory.block()));
+    FunctionExpression node = AstTestFactory.functionExpression2(
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody(AstTestFactory.block()));
     _assertReplace(node, new Getter_NodeReplacerTest_test_functionExpression());
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_functionExpression_2());
   }
 
   void test_functionExpressionInvocation() {
-    FunctionExpressionInvocation node = AstFactory.functionExpressionInvocation(
-        AstFactory.identifier3("f"), [AstFactory.integer(0)]);
+    FunctionExpressionInvocation node = AstTestFactory
+        .functionExpressionInvocation(
+            AstTestFactory.identifier3("f"), [AstTestFactory.integer(0)]);
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_functionExpressionInvocation());
     _assertReplace(node,
@@ -3398,14 +3426,15 @@
   }
 
   void test_functionTypeAlias() {
-    FunctionTypeAlias node = AstFactory.typeAlias(
-        AstFactory.typeName4("R"),
+    FunctionTypeAlias node = AstTestFactory.typeAlias(
+        AstTestFactory.typeName4("R"),
         "F",
-        AstFactory.typeParameterList(["E"]),
-        AstFactory.formalParameterList());
+        AstTestFactory.typeParameterList(["E"]),
+        AstTestFactory.formalParameterList());
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_functionTypeAlias_3());
     _assertReplace(
@@ -3417,13 +3446,14 @@
   }
 
   void test_functionTypedFormalParameter() {
-    FunctionTypedFormalParameter node = AstFactory.functionTypedFormalParameter(
-        AstFactory.typeName4("R"),
-        "f",
-        [AstFactory.simpleFormalParameter3("p")]);
+    FunctionTypedFormalParameter node = AstTestFactory
+        .functionTypedFormalParameter(AstTestFactory.typeName4("R"), "f",
+            [AstTestFactory.simpleFormalParameter3("p")]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata = [AstFactory.annotation(AstFactory.identifier3("a"))];
+    node.metadata = [
+      AstTestFactory.annotation(AstTestFactory.identifier3("a"))
+    ];
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_functionTypedFormalParameter());
     _assertReplace(node,
@@ -3432,48 +3462,52 @@
   }
 
   void test_hideCombinator() {
-    HideCombinator node = AstFactory.hideCombinator2(["A", "B"]);
+    HideCombinator node = AstTestFactory.hideCombinator2(["A", "B"]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_hideCombinator(0));
   }
 
   void test_ifStatement() {
-    IfStatement node = AstFactory.ifStatement2(AstFactory.booleanLiteral(true),
-        AstFactory.block(), AstFactory.block());
+    IfStatement node = AstTestFactory.ifStatement2(
+        AstTestFactory.booleanLiteral(true),
+        AstTestFactory.block(),
+        AstTestFactory.block());
     _assertReplace(node, new Getter_NodeReplacerTest_test_ifStatement());
     _assertReplace(node, new Getter_NodeReplacerTest_test_ifStatement_3());
     _assertReplace(node, new Getter_NodeReplacerTest_test_ifStatement_2());
   }
 
   void test_implementsClause() {
-    ImplementsClause node = AstFactory.implementsClause(
-        [AstFactory.typeName4("I"), AstFactory.typeName4("J")]);
+    ImplementsClause node = AstTestFactory.implementsClause(
+        [AstTestFactory.typeName4("I"), AstTestFactory.typeName4("J")]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_implementsClause(0));
   }
 
   void test_importDirective() {
-    ImportDirective node = AstFactory.importDirective3("", "p", [
-      AstFactory.showCombinator2(["A"]),
-      AstFactory.hideCombinator2(["B"])
+    ImportDirective node = AstTestFactory.importDirective3("", "p", [
+      AstTestFactory.showCombinator2(["A"]),
+      AstTestFactory.hideCombinator2(["B"])
     ]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_importDirective());
     _testNamespaceDirective(node);
   }
 
   void test_indexExpression() {
-    IndexExpression node = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("i"));
+    IndexExpression node = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.identifier3("i"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_indexExpression());
     _assertReplace(node, new Getter_NodeReplacerTest_test_indexExpression_2());
   }
 
   void test_instanceCreationExpression() {
-    InstanceCreationExpression node = AstFactory.instanceCreationExpression3(
-        null, AstFactory.typeName4("C"), "c", [AstFactory.integer(2)]);
+    InstanceCreationExpression node = AstTestFactory
+        .instanceCreationExpression3(null, AstTestFactory.typeName4("C"), "c",
+            [AstTestFactory.integer(2)]);
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_instanceCreationExpression_2());
     _assertReplace(
@@ -3481,83 +3515,85 @@
   }
 
   void test_interpolationExpression() {
-    InterpolationExpression node = AstFactory.interpolationExpression2("x");
+    InterpolationExpression node = AstTestFactory.interpolationExpression2("x");
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_interpolationExpression());
   }
 
   void test_isExpression() {
-    IsExpression node = AstFactory.isExpression(
-        AstFactory.identifier3("v"), false, AstFactory.typeName4("T"));
+    IsExpression node = AstTestFactory.isExpression(
+        AstTestFactory.identifier3("v"), false, AstTestFactory.typeName4("T"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_isExpression());
     _assertReplace(node, new Getter_NodeReplacerTest_test_isExpression_2());
   }
 
   void test_label() {
-    Label node = AstFactory.label2("l");
+    Label node = AstTestFactory.label2("l");
     _assertReplace(node, new Getter_NodeReplacerTest_test_label());
   }
 
   void test_labeledStatement() {
-    LabeledStatement node = AstFactory
-        .labeledStatement([AstFactory.label2("l")], AstFactory.block());
+    LabeledStatement node = AstTestFactory
+        .labeledStatement([AstTestFactory.label2("l")], AstTestFactory.block());
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_labeledStatement(0));
     _assertReplace(node, new Getter_NodeReplacerTest_test_labeledStatement());
   }
 
   void test_libraryDirective() {
-    LibraryDirective node = AstFactory.libraryDirective2("lib");
+    LibraryDirective node = AstTestFactory.libraryDirective2("lib");
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_libraryDirective());
     _testAnnotatedNode(node);
   }
 
   void test_libraryIdentifier() {
-    LibraryIdentifier node = AstFactory.libraryIdentifier2(["lib"]);
+    LibraryIdentifier node = AstTestFactory.libraryIdentifier2(["lib"]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_libraryIdentifier(0));
   }
 
   void test_listLiteral() {
-    ListLiteral node = AstFactory.listLiteral2(
+    ListLiteral node = AstTestFactory.listLiteral2(
         null,
-        AstFactory.typeArgumentList([AstFactory.typeName4("E")]),
-        [AstFactory.identifier3("e")]);
+        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("E")]),
+        [AstTestFactory.identifier3("e")]);
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_listLiteral(0));
     _testTypedLiteral(node);
   }
 
   void test_mapLiteral() {
-    MapLiteral node = AstFactory.mapLiteral(
+    MapLiteral node = AstTestFactory.mapLiteral(
         null,
-        AstFactory.typeArgumentList([AstFactory.typeName4("E")]),
-        [AstFactory.mapLiteralEntry("k", AstFactory.identifier3("v"))]);
+        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("E")]),
+        [AstTestFactory.mapLiteralEntry("k", AstTestFactory.identifier3("v"))]);
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_mapLiteral(0));
     _testTypedLiteral(node);
   }
 
   void test_mapLiteralEntry() {
     MapLiteralEntry node =
-        AstFactory.mapLiteralEntry("k", AstFactory.identifier3("v"));
+        AstTestFactory.mapLiteralEntry("k", AstTestFactory.identifier3("v"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_mapLiteralEntry_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_mapLiteralEntry());
   }
 
   void test_methodDeclaration() {
-    MethodDeclaration node = AstFactory.methodDeclaration2(
+    MethodDeclaration node = AstTestFactory.methodDeclaration2(
         null,
-        AstFactory.typeName4("A"),
+        AstTestFactory.typeName4("A"),
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody(AstFactory.block()));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody(AstTestFactory.block()));
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_methodDeclaration());
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_methodDeclaration_3());
@@ -3569,8 +3605,8 @@
   }
 
   void test_methodInvocation() {
-    MethodInvocation node = AstFactory.methodInvocation(
-        AstFactory.identifier3("t"), "m", [AstFactory.integer(0)]);
+    MethodInvocation node = AstTestFactory.methodInvocation(
+        AstTestFactory.identifier3("t"), "m", [AstTestFactory.integer(0)]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_methodInvocation_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_methodInvocation_3());
     _assertReplace(node, new Getter_NodeReplacerTest_test_methodInvocation());
@@ -3578,75 +3614,77 @@
 
   void test_namedExpression() {
     NamedExpression node =
-        AstFactory.namedExpression2("l", AstFactory.identifier3("v"));
+        AstTestFactory.namedExpression2("l", AstTestFactory.identifier3("v"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_namedExpression());
     _assertReplace(node, new Getter_NodeReplacerTest_test_namedExpression_2());
   }
 
   void test_nativeClause() {
-    NativeClause node = AstFactory.nativeClause("");
+    NativeClause node = AstTestFactory.nativeClause("");
     _assertReplace(node, new Getter_NodeReplacerTest_test_nativeClause());
   }
 
   void test_nativeFunctionBody() {
-    NativeFunctionBody node = AstFactory.nativeFunctionBody("m");
+    NativeFunctionBody node = AstTestFactory.nativeFunctionBody("m");
     _assertReplace(node, new Getter_NodeReplacerTest_test_nativeFunctionBody());
   }
 
   void test_parenthesizedExpression() {
     ParenthesizedExpression node =
-        AstFactory.parenthesizedExpression(AstFactory.integer(0));
+        AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_parenthesizedExpression());
   }
 
   void test_partDirective() {
-    PartDirective node = AstFactory.partDirective2("");
+    PartDirective node = AstTestFactory.partDirective2("");
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _testUriBasedDirective(node);
   }
 
   void test_partOfDirective() {
-    PartOfDirective node =
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
+    PartOfDirective node = AstTestFactory
+        .partOfDirective(AstTestFactory.libraryIdentifier2(["lib"]));
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(node, new Getter_NodeReplacerTest_test_partOfDirective());
     _testAnnotatedNode(node);
   }
 
   void test_postfixExpression() {
-    PostfixExpression node = AstFactory.postfixExpression(
-        AstFactory.identifier3("x"), TokenType.MINUS_MINUS);
+    PostfixExpression node = AstTestFactory.postfixExpression(
+        AstTestFactory.identifier3("x"), TokenType.MINUS_MINUS);
     _assertReplace(node, new Getter_NodeReplacerTest_test_postfixExpression());
   }
 
   void test_prefixedIdentifier() {
-    PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+    PrefixedIdentifier node = AstTestFactory.identifier5("a", "b");
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_prefixedIdentifier_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_prefixedIdentifier());
   }
 
   void test_prefixExpression() {
-    PrefixExpression node = AstFactory.prefixExpression(
-        TokenType.PLUS_PLUS, AstFactory.identifier3("y"));
+    PrefixExpression node = AstTestFactory.prefixExpression(
+        TokenType.PLUS_PLUS, AstTestFactory.identifier3("y"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_prefixExpression());
   }
 
   void test_propertyAccess() {
     PropertyAccess node =
-        AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
     _assertReplace(node, new Getter_NodeReplacerTest_test_propertyAccess());
     _assertReplace(node, new Getter_NodeReplacerTest_test_propertyAccess_2());
   }
 
   void test_redirectingConstructorInvocation() {
-    RedirectingConstructorInvocation node = AstFactory
-        .redirectingConstructorInvocation2("c", [AstFactory.integer(0)]);
+    RedirectingConstructorInvocation node = AstTestFactory
+        .redirectingConstructorInvocation2("c", [AstTestFactory.integer(0)]);
     _assertReplace(node,
         new Getter_NodeReplacerTest_test_redirectingConstructorInvocation());
     _assertReplace(node,
@@ -3654,22 +3692,25 @@
   }
 
   void test_returnStatement() {
-    ReturnStatement node = AstFactory.returnStatement2(AstFactory.integer(0));
+    ReturnStatement node =
+        AstTestFactory.returnStatement2(AstTestFactory.integer(0));
     _assertReplace(node, new Getter_NodeReplacerTest_test_returnStatement());
   }
 
   void test_showCombinator() {
-    ShowCombinator node = AstFactory.showCombinator2(["X", "Y"]);
+    ShowCombinator node = AstTestFactory.showCombinator2(["X", "Y"]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_showCombinator(0));
   }
 
   void test_simpleFormalParameter() {
-    SimpleFormalParameter node =
-        AstFactory.simpleFormalParameter4(AstFactory.typeName4("T"), "p");
+    SimpleFormalParameter node = AstTestFactory.simpleFormalParameter4(
+        AstTestFactory.typeName4("T"), "p");
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata = [AstFactory.annotation(AstFactory.identifier3("a"))];
+    node.metadata = [
+      AstTestFactory.annotation(AstTestFactory.identifier3("a"))
+    ];
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_simpleFormalParameter());
     _testNormalFormalParameter(node);
@@ -3677,14 +3718,14 @@
 
   void test_stringInterpolation() {
     StringInterpolation node =
-        AstFactory.string([AstFactory.interpolationExpression2("a")]);
+        AstTestFactory.string([AstTestFactory.interpolationExpression2("a")]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_stringInterpolation(0));
   }
 
   void test_superConstructorInvocation() {
-    SuperConstructorInvocation node =
-        AstFactory.superConstructorInvocation2("s", [AstFactory.integer(1)]);
+    SuperConstructorInvocation node = AstTestFactory
+        .superConstructorInvocation2("s", [AstTestFactory.integer(1)]);
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_superConstructorInvocation());
     _assertReplace(
@@ -3692,24 +3733,25 @@
   }
 
   void test_switchCase() {
-    SwitchCase node = AstFactory.switchCase2(
-        [AstFactory.label2("l")], AstFactory.integer(0), [AstFactory.block()]);
+    SwitchCase node = AstTestFactory.switchCase2([AstTestFactory.label2("l")],
+        AstTestFactory.integer(0), [AstTestFactory.block()]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_switchCase());
     _testSwitchMember(node);
   }
 
   void test_switchDefault() {
-    SwitchDefault node = AstFactory
-        .switchDefault([AstFactory.label2("l")], [AstFactory.block()]);
+    SwitchDefault node = AstTestFactory
+        .switchDefault([AstTestFactory.label2("l")], [AstTestFactory.block()]);
     _testSwitchMember(node);
   }
 
   void test_switchStatement() {
     SwitchStatement node =
-        AstFactory.switchStatement(AstFactory.identifier3("x"), [
-      AstFactory.switchCase2([AstFactory.label2("l")], AstFactory.integer(0),
-          [AstFactory.block()]),
-      AstFactory.switchDefault([AstFactory.label2("l")], [AstFactory.block()])
+        AstTestFactory.switchStatement(AstTestFactory.identifier3("x"), [
+      AstTestFactory.switchCase2([AstTestFactory.label2("l")],
+          AstTestFactory.integer(0), [AstTestFactory.block()]),
+      AstTestFactory
+          .switchDefault([AstTestFactory.label2("l")], [AstTestFactory.block()])
     ]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_switchStatement());
     _assertReplace(
@@ -3718,28 +3760,30 @@
 
   void test_throwExpression() {
     ThrowExpression node =
-        AstFactory.throwExpression2(AstFactory.identifier3("e"));
+        AstTestFactory.throwExpression2(AstTestFactory.identifier3("e"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_throwExpression());
   }
 
   void test_topLevelVariableDeclaration() {
-    TopLevelVariableDeclaration node = AstFactory.topLevelVariableDeclaration(
-        null, AstFactory.typeName4("T"), [AstFactory.variableDeclaration("t")]);
+    TopLevelVariableDeclaration node = AstTestFactory
+        .topLevelVariableDeclaration(null, AstTestFactory.typeName4("T"),
+            [AstTestFactory.variableDeclaration("t")]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_topLevelVariableDeclaration());
     _testAnnotatedNode(node);
   }
 
   void test_tryStatement() {
-    TryStatement node = AstFactory.tryStatement3(
-        AstFactory.block(),
+    TryStatement node = AstTestFactory.tryStatement3(
+        AstTestFactory.block(),
         [
-          AstFactory.catchClause("e", [AstFactory.block()])
+          AstTestFactory.catchClause("e", [AstTestFactory.block()])
         ],
-        AstFactory.block());
+        AstTestFactory.block());
     _assertReplace(node, new Getter_NodeReplacerTest_test_tryStatement_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_tryStatement());
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_tryStatement(0));
@@ -3747,37 +3791,38 @@
 
   void test_typeArgumentList() {
     TypeArgumentList node =
-        AstFactory.typeArgumentList([AstFactory.typeName4("A")]);
+        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("A")]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_typeArgumentList(0));
   }
 
   void test_typeName() {
-    TypeName node = AstFactory
-        .typeName4("T", [AstFactory.typeName4("E"), AstFactory.typeName4("F")]);
+    TypeName node = AstTestFactory.typeName4(
+        "T", [AstTestFactory.typeName4("E"), AstTestFactory.typeName4("F")]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_typeName_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_typeName());
   }
 
   void test_typeParameter() {
     TypeParameter node =
-        AstFactory.typeParameter2("E", AstFactory.typeName4("B"));
+        AstTestFactory.typeParameter2("E", AstTestFactory.typeName4("B"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_typeParameter_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_typeParameter());
   }
 
   void test_typeParameterList() {
-    TypeParameterList node = AstFactory.typeParameterList(["A", "B"]);
+    TypeParameterList node = AstTestFactory.typeParameterList(["A", "B"]);
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_typeParameterList(0));
   }
 
   void test_variableDeclaration() {
     VariableDeclaration node =
-        AstFactory.variableDeclaration2("a", AstFactory.nullLiteral());
+        AstTestFactory.variableDeclaration2("a", AstTestFactory.nullLiteral());
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_variableDeclaration());
     _assertReplace(
@@ -3786,11 +3831,14 @@
   }
 
   void test_variableDeclarationList() {
-    VariableDeclarationList node = AstFactory.variableDeclarationList(
-        null, AstFactory.typeName4("T"), [AstFactory.variableDeclaration("a")]);
+    VariableDeclarationList node = AstTestFactory.variableDeclarationList(
+        null,
+        AstTestFactory.typeName4("T"),
+        [AstTestFactory.variableDeclaration("a")]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
-    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
+    node.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_variableDeclarationList());
     _assertReplace(
@@ -3799,26 +3847,28 @@
   }
 
   void test_variableDeclarationStatement() {
-    VariableDeclarationStatement node = AstFactory.variableDeclarationStatement(
-        null, AstFactory.typeName4("T"), [AstFactory.variableDeclaration("a")]);
+    VariableDeclarationStatement node = AstTestFactory
+        .variableDeclarationStatement(null, AstTestFactory.typeName4("T"),
+            [AstTestFactory.variableDeclaration("a")]);
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_variableDeclarationStatement());
   }
 
   void test_whileStatement() {
-    WhileStatement node = AstFactory.whileStatement(
-        AstFactory.booleanLiteral(true), AstFactory.block());
+    WhileStatement node = AstTestFactory.whileStatement(
+        AstTestFactory.booleanLiteral(true), AstTestFactory.block());
     _assertReplace(node, new Getter_NodeReplacerTest_test_whileStatement());
     _assertReplace(node, new Getter_NodeReplacerTest_test_whileStatement_2());
   }
 
   void test_withClause() {
-    WithClause node = AstFactory.withClause([AstFactory.typeName4("M")]);
+    WithClause node =
+        AstTestFactory.withClause([AstTestFactory.typeName4("M")]);
     _assertReplace(node, new ListGetter_NodeReplacerTest_test_withClause(0));
   }
 
   void test_yieldStatement() {
-    var node = AstFactory.yieldStatement(AstFactory.identifier3("A"));
+    var node = AstTestFactory.yieldStatement(AstTestFactory.identifier3("A"));
     _assertReplace(node, new Getter_NodeReplacerTest_test_yieldStatement());
   }
 
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 0c47bd0..9ddf64f 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -145,7 +145,8 @@
     AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
     defaultOptions.dart2jsHint = !defaultOptions.dart2jsHint;
     defaultOptions.enableAssertMessage = !defaultOptions.enableAssertMessage;
-    defaultOptions.enableGenericMethods = !defaultOptions.enableGenericMethods;
+    defaultOptions.enableLazyAssignmentOperators =
+        !defaultOptions.enableLazyAssignmentOperators;
     defaultOptions.enableStrictCallChecks =
         !defaultOptions.enableStrictCallChecks;
     defaultOptions.enableSuperMixins = !defaultOptions.enableSuperMixins;
@@ -497,10 +498,10 @@
 
   void test_getAnalysisOptions_default_noOverrides() {
     AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
-    defaultOptions.enableGenericMethods = true;
+    defaultOptions.enableLazyAssignmentOperators = true;
     builderOptions.defaultOptions = defaultOptions;
     AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
-    expected.enableGenericMethods = true;
+    expected.enableLazyAssignmentOperators = true;
     String path = resourceProvider.convertPath('/some/directory/path');
     String filePath =
         pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
@@ -519,11 +520,11 @@
 
   void test_getAnalysisOptions_default_overrides() {
     AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
-    defaultOptions.enableGenericMethods = true;
+    defaultOptions.enableLazyAssignmentOperators = true;
     builderOptions.defaultOptions = defaultOptions;
     AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
     expected.enableSuperMixins = true;
-    expected.enableGenericMethods = true;
+    expected.enableLazyAssignmentOperators = true;
     String path = resourceProvider.convertPath('/some/directory/path');
     String filePath =
         pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
@@ -557,11 +558,9 @@
 
   void test_getAnalysisOptions_includes() {
     AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
-    defaultOptions.enableGenericMethods = true;
     builderOptions.defaultOptions = defaultOptions;
     AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
     expected.enableSuperMixins = true;
-    expected.enableGenericMethods = true;
     resourceProvider.newFile(
         resourceProvider.convertPath('/mypkgs/somepkg/lib/here.yaml'),
         '''
@@ -734,8 +733,9 @@
         same(expected.analyzeFunctionBodiesPredicate));
     expect(actual.dart2jsHint, expected.dart2jsHint);
     expect(actual.enableAssertMessage, expected.enableAssertMessage);
+    expect(actual.enableLazyAssignmentOperators,
+        expected.enableLazyAssignmentOperators);
     expect(actual.enableStrictCallChecks, expected.enableStrictCallChecks);
-    expect(actual.enableGenericMethods, expected.enableGenericMethods);
     expect(actual.enableSuperMixins, expected.enableSuperMixins);
     expect(actual.enableTiming, expected.enableTiming);
     expect(actual.generateImplicitErrors, expected.generateImplicitErrors);
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 13a5526..b9d77b1 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -977,15 +977,6 @@
         });
   }
 
-  void test_configurationData() {
-    var key = new ResultDescriptor('test_key', 'TEST_DEFAULT');
-    var testData = ['test', 'data'];
-    context.setConfigurationData(key, testData);
-    expect(context.getConfigurationData(key), testData);
-    var unusedKey = new ResultDescriptor('unused_key', 'UNUSED_DEFAULT');
-    expect(context.getConfigurationData(unusedKey), 'UNUSED_DEFAULT');
-  }
-
   void test_dispose() {
     expect(context.isDisposed, isFalse);
     context.dispose();
@@ -2543,9 +2534,7 @@
   }
 
   void test_resolveCompilationUnit_existingElementModel() {
-    prepareAnalysisContext(new AnalysisOptionsImpl()
-      ..enableGenericMethods = true
-      ..strongMode = true);
+    prepareAnalysisContext(new AnalysisOptionsImpl()..strongMode = true);
     Source source = addSource(
         '/test.dart',
         r'''
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 796b9b8..bb716cf 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -4,6 +4,8 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
@@ -17,6 +19,30 @@
 
 import '../../context/mock_sdk.dart';
 
+/**
+ * Finds an [Element] with the given [name].
+ */
+Element findChildElement(Element root, String name, [ElementKind kind]) {
+  Element result = null;
+  root.accept(new _ElementVisitorFunctionWrapper((Element element) {
+    if (element.name != name) {
+      return;
+    }
+    if (kind != null && element.kind != kind) {
+      return;
+    }
+    result = element;
+  }));
+  return result;
+}
+
+typedef bool Predicate<E>(E argument);
+
+/**
+ * A function to be called for every [Element].
+ */
+typedef void _ElementVisitorFunction(Element element);
+
 class BaseAnalysisDriverTest {
   static final MockSdk sdk = new MockSdk();
 
@@ -108,6 +134,20 @@
   String _p(String path) => provider.convertPath(path);
 }
 
+/**
+ * Wraps an [_ElementVisitorFunction] into a [GeneralizingElementVisitor].
+ */
+class _ElementVisitorFunctionWrapper extends GeneralizingElementVisitor {
+  final _ElementVisitorFunction function;
+
+  _ElementVisitorFunctionWrapper(this.function);
+
+  visitElement(Element element) {
+    function(element);
+    super.visitElement(element);
+  }
+}
+
 class _Monitor {
   Completer<Null> _completer = new Completer<Null>();
 
diff --git a/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart b/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
index 2099863..9da3f0b 100644
--- a/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/byte_store_test.dart
@@ -15,6 +15,35 @@
 
 @reflectiveTest
 class MemoryCachingByteStoreTest {
+  test_get_notFound_evict() {
+    var store = new _TestByteStore();
+    var cachingStore = new MemoryCachingByteStore(store, 100);
+
+    // Request '1'.  Nothing found.
+    cachingStore.get('1');
+
+    // Add enough data to the store to force an eviction.
+    cachingStore.put('2', _b(40));
+    cachingStore.put('3', _b(40));
+    cachingStore.put('4', _b(40));
+  }
+
+  test_get_notFound_retry() {
+    var mockStore = new _TestByteStore();
+    var baseStore = new MemoryCachingByteStore(mockStore, 1000);
+    var cachingStore = new MemoryCachingByteStore(baseStore, 100);
+
+    // Request '1'.  Nothing found.
+    expect(cachingStore.get('1'), isNull);
+
+    // Add data to the base store, bypassing the caching store.
+    baseStore.put('1', _b(40));
+
+    // Request '1' again.  The previous `null` result should not have been
+    // cached.
+    expect(cachingStore.get('1'), isNotNull);
+  }
+
   test_get_put_evict() {
     var store = new _TestByteStore();
     var cachingStore = new MemoryCachingByteStore(store, 100);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index f4ee85b..6b4231e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -379,6 +379,61 @@
     }
   }
 
+  test_getFilesReferencingName() async {
+    var a = _p('/test/bin/a.dart');
+    var b = _p('/test/bin/b.dart');
+    var c = _p('/test/bin/c.dart');
+    var d = _p('/test/bin/d.dart');
+    var e = _p('/test/bin/e.dart');
+
+    provider.newFile(a, 'class A {}');
+    provider.newFile(b, "import 'a.dart'; A a;");
+    provider.newFile(c, "import 'a.dart'; var a = new A();");
+    provider.newFile(d, "classs A{} A a;");
+    provider.newFile(e, "import 'a.dart'; main() {}");
+
+    driver.addFile(a);
+    driver.addFile(b);
+    driver.addFile(c);
+    driver.addFile(d);
+    driver.addFile(e);
+
+    // 'b.dart' references an external 'A'.
+    // 'c.dart' references an external 'A'.
+    // 'd.dart' references the local 'A'.
+    // 'e.dart' does not reference 'A' at all.
+    List<String> files = await driver.getFilesReferencingName('A');
+    expect(files, unorderedEquals([b, c]));
+
+    // We get the same results second time.
+    List<String> files2 = await driver.getFilesReferencingName('A');
+    expect(files2, unorderedEquals([b, c]));
+  }
+
+  test_getIndex() async {
+    String content = r'''
+foo(int p) {}
+main() {
+  foo(42);
+}
+''';
+    addTestFile(content);
+
+    IndexResult result = await driver.getIndex(testFile);
+
+    CompilationUnitElement unitElement = result.unitElement;
+    expect(unitElement, isNotNull);
+    expect(unitElement.source.fullName, testFile);
+    expect(unitElement.functions.map((c) => c.name),
+        unorderedEquals(['foo', 'main']));
+
+    AnalysisDriverUnitIndex index = result.index;
+    int unitId = index.strings.indexOf('package:test/test.dart');
+    int fooId = index.strings.indexOf('foo');
+    expect(unitId, isNonNegative);
+    expect(fooId, isNonNegative);
+  }
+
   test_getResult() async {
     String content = 'int f() => 42;';
     addTestFile(content, priority: true);
@@ -438,24 +493,6 @@
     }
   }
 
-  test_getResult_hasIndex() async {
-    String content = r'''
-foo(int p) {}
-main() {
-  foo(42);
-}
-''';
-    addTestFile(content);
-
-    AnalysisResult result = await driver.getResult(testFile);
-
-    AnalysisDriverUnitIndex index = result.index;
-    int unitId = index.strings.indexOf('package:test/test.dart');
-    int fooId = index.strings.indexOf('foo');
-    expect(unitId, isNonNegative);
-    expect(fooId, isNonNegative);
-  }
-
   test_getResult_inferTypes_finalField() async {
     addTestFile(
         r'''
@@ -1087,7 +1124,6 @@
     expect(result.contentHash, _md5(content));
     expect(result.unit, isNull);
     expect(result.errors, hasLength(0));
-    expect(result.index, isNotNull);
   }
 
   test_results_status() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 8c544c7..d090dbb 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -7,7 +7,6 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
 import 'package:analyzer/src/summary/format.dart';
@@ -23,28 +22,6 @@
   });
 }
 
-/**
- * Finds an [Element] with the given [name].
- */
-Element findChildElement(Element root, String name, [ElementKind kind]) {
-  Element result = null;
-  root.accept(new _ElementVisitorFunctionWrapper((Element element) {
-    if (element.name != name) {
-      return;
-    }
-    if (kind != null && element.kind != kind) {
-      return;
-    }
-    result = element;
-  }));
-  return result;
-}
-
-/**
- * A function to be called for every [Element].
- */
-typedef void _ElementVisitorFunction(Element element);
-
 class ExpectedLocation {
   final CompilationUnitElement unitElement;
   final int offset;
@@ -816,6 +793,16 @@
       ..isReferencedAt('method); // nq', false);
   }
 
+  test_isReferencedBy_MultiplyDefinedElement() async {
+    provider.newFile(_p('$testProject/a1.dart'), 'class A {}');
+    provider.newFile(_p('$testProject/a2.dart'), 'class A {}');
+    await _indexTestUnit('''
+import 'a1.dart';
+import 'a2.dart';
+A v = null;
+''');
+  }
+
   test_isReferencedBy_ParameterElement() async {
     await _indexTestUnit('''
 foo({var p}) {}
@@ -1210,20 +1197,6 @@
   }
 }
 
-/**
- * Wraps an [_ElementVisitorFunction] into a [GeneralizingElementVisitor].
- */
-class _ElementVisitorFunctionWrapper extends GeneralizingElementVisitor {
-  final _ElementVisitorFunction function;
-
-  _ElementVisitorFunctionWrapper(this.function);
-
-  visitElement(Element element) {
-    function(element);
-    super.visitElement(element);
-  }
-}
-
 class _NameIndexAssert {
   final IndexTest test;
   final String name;
diff --git a/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart b/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart
index ee43d8d..97a1bdca 100644
--- a/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart
@@ -383,8 +383,7 @@
   }
 
   Set<String> _computeReferencedNames(String code) {
-    CompilationUnit unit =
-        ParserTestCase.parseCompilationUnit2(code, parseGenericMethods: true);
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit2(code);
     return computeReferencedNames(unit);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 03a2a53..8872ebd 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -4,8 +4,12 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/search.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -18,14 +22,14 @@
 }
 
 class ExpectedResult {
-  final List<String> enclosingComponents;
+  final Element enclosingElement;
   final SearchResultKind kind;
   final int offset;
   final int length;
   final bool isResolved;
   final bool isQualified;
 
-  ExpectedResult(this.enclosingComponents, this.kind, this.offset, this.length,
+  ExpectedResult(this.enclosingElement, this.kind, this.offset, this.length,
       {this.isResolved: true, this.isQualified: false});
 
   bool operator ==(Object result) {
@@ -34,24 +38,7 @@
         result.isResolved == this.isResolved &&
         result.isQualified == this.isQualified &&
         result.offset == this.offset &&
-        hasExpectedComponents(result.enclosingElement);
-  }
-
-  bool hasExpectedComponents(Element element) {
-    for (int i = enclosingComponents.length - 1; i >= 0; i--) {
-      if (element == null) {
-        return false;
-      }
-      if (element is CompilationUnitElement) {
-        if (element.source.uri.toString() != enclosingComponents[0]) {
-          return false;
-        }
-      } else if (element.name != enclosingComponents[i]) {
-        return false;
-      }
-      element = element.enclosingElement;
-    }
-    return true;
+        result.enclosingElement == this.enclosingElement;
   }
 
   @override
@@ -59,8 +46,8 @@
     StringBuffer buffer = new StringBuffer();
     buffer.write("ExpectedResult(kind=");
     buffer.write(kind);
-    buffer.write(", enclosingComponents=");
-    buffer.write(enclosingComponents);
+    buffer.write(", enclosingElement=");
+    buffer.write(enclosingElement);
     buffer.write(", offset=");
     buffer.write(offset);
     buffer.write(", length=");
@@ -78,8 +65,242 @@
 class SearchTest extends BaseAnalysisDriverTest {
   static const testUri = 'package:test/test.dart';
 
-  test_searchReferences_Label() async {
-    addTestFile('''
+  CompilationUnit testUnit;
+  CompilationUnitElement testUnitElement;
+  LibraryElement testLibraryElement;
+
+  test_searchReferences_ClassElement_definedInside() async {
+    await _resolveTestUnit('''
+class A {};
+main(A p) {
+  A v;
+}
+class B1 extends A {} // extends
+class B2 implements A {} // implements
+class B3 extends Object with A {} // with
+List<A> v2 = null;
+''');
+    ClassElement element = _findElementAtString('A {}');
+    Element p = _findElement('p');
+    Element main = _findElement('main');
+    Element b1 = _findElement('B1');
+    Element b2 = _findElement('B2');
+    Element b3 = _findElement('B3');
+    Element v2 = _findElement('v2');
+    var expected = [
+      _expectId(p, SearchResultKind.REFERENCE, 'A p'),
+      _expectId(main, SearchResultKind.REFERENCE, 'A v'),
+      _expectId(b1, SearchResultKind.REFERENCE, 'A {} // extends'),
+      _expectId(b2, SearchResultKind.REFERENCE, 'A {} // implements'),
+      _expectId(b3, SearchResultKind.REFERENCE, 'A {} // with'),
+      _expectId(v2, SearchResultKind.REFERENCE, 'A> v2'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ClassElement_definedOutside() async {
+    provider.newFile(
+        _p('$testProject/lib.dart'),
+        r'''
+class A {};
+''');
+    await _resolveTestUnit('''
+import 'lib.dart';
+main(A p) {
+  A v;
+}
+''');
+    ClassElement element = _findElementAtString('A p');
+    Element p = _findElement('p');
+    Element main = _findElement('main');
+    var expected = [
+      _expectId(p, SearchResultKind.REFERENCE, 'A p'),
+      _expectId(main, SearchResultKind.REFERENCE, 'A v')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  @failingTest
+  test_searchReferences_CompilationUnitElement() async {
+    provider.newFile(
+        _p('$testProject/my_part.dart'),
+        '''
+part of lib;
+''');
+    await _resolveTestUnit('''
+library lib;
+part 'my_part.dart';
+''');
+    CompilationUnitElement element = _findElementAtString('my_part');
+    var expected = [
+      _expectIdQ(element.library.definingCompilationUnit,
+          SearchResultKind.REFERENCE, "'my_part.dart'",
+          length: "'my_part.dart'".length)
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ConstructorElement() async {
+    await _resolveTestUnit('''
+class A {
+  A.named() {}
+}
+main() {
+  new A.named();
+}
+''');
+    ConstructorElement element = _findElement('named');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, '.named();',
+          length: 6)
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ConstructorElement_synthetic() async {
+    await _resolveTestUnit('''
+class A {
+}
+main() {
+  new A();
+}
+''');
+    ClassElement classElement = _findElement('A');
+    ConstructorElement element = classElement.unnamedConstructor;
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, '();', length: 0)
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_FieldElement() async {
+    await _resolveTestUnit('''
+class A {
+  var field;
+  A({this.field});
+  main() {
+    new A(field: 1);
+    // getter
+    print(field); // ref-nq
+    print(this.field); // ref-q
+    field(); // inv-nq
+    this.field(); // inv-q
+    // setter
+    field = 2; // ref-nq;
+    this.field = 3; // ref-q;
+  }
+}
+''');
+    FieldElement element = _findElement('field', ElementKind.FIELD);
+    Element main = _findElement('main');
+    Element fieldParameter = _findElement('field', ElementKind.PARAMETER);
+    var expected = [
+      _expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'field: 1'),
+      _expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
+      _expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
+      _expectId(main, SearchResultKind.INVOCATION, 'field(); // inv-nq'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'field(); // inv-q'),
+      _expectId(main, SearchResultKind.WRITE, 'field = 2; // ref-nq'),
+      _expectIdQ(main, SearchResultKind.WRITE, 'field = 3; // ref-q'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_FieldElement_ofEnum() async {
+    await _resolveTestUnit('''
+enum MyEnum {
+  A, B, C
+}
+main() {
+  print(MyEnum.A.index);
+  print(MyEnum.values);
+  print(MyEnum.A);
+  print(MyEnum.B);
+}
+''');
+    ClassElement enumElement = _findElement('MyEnum');
+    Element mainElement = _findElement('main');
+    await _verifyReferences(enumElement.getField('index'),
+        [_expectIdQ(mainElement, SearchResultKind.READ, 'index);')]);
+    await _verifyReferences(enumElement.getField('values'),
+        [_expectIdQ(mainElement, SearchResultKind.READ, 'values);')]);
+    await _verifyReferences(enumElement.getField('A'), [
+      _expectIdQ(mainElement, SearchResultKind.READ, 'A.index);'),
+      _expectIdQ(mainElement, SearchResultKind.READ, 'A);')
+    ]);
+    await _verifyReferences(enumElement.getField('B'),
+        [_expectIdQ(mainElement, SearchResultKind.READ, 'B);')]);
+  }
+
+  test_searchReferences_FieldElement_synthetic() async {
+    await _resolveTestUnit('''
+class A {
+  get field => null;
+  set field(x) {}
+  main() {
+    // getter
+    print(field); // ref-nq
+    print(this.field); // ref-q
+    field(); // inv-nq
+    this.field(); // inv-q
+    // setter
+    field = 2; // ref-nq;
+    this.field = 3; // ref-q;
+  }
+}
+''');
+    FieldElement element = _findElement('field', ElementKind.FIELD);
+    Element main = _findElement('main');
+    var expected = [
+      _expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
+      _expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
+      _expectId(main, SearchResultKind.INVOCATION, 'field(); // inv-nq'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'field(); // inv-q'),
+      _expectId(main, SearchResultKind.WRITE, 'field = 2; // ref-nq'),
+      _expectIdQ(main, SearchResultKind.WRITE, 'field = 3; // ref-q'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_FunctionElement() async {
+    await _resolveTestUnit('''
+test() {}
+main() {
+  test();
+  print(test);
+}
+''');
+    FunctionElement element = _findElement('test');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(mainElement, SearchResultKind.INVOCATION, 'test();'),
+      _expectId(mainElement, SearchResultKind.REFERENCE, 'test);')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_FunctionElement_local() async {
+    await _resolveTestUnit('''
+main() {
+  test() {}
+  test();
+  print(test);
+}
+''');
+    FunctionElement element = _findElement('test');
+    Element main = _findElement('main');
+    var expected = [
+      _expectId(main, SearchResultKind.INVOCATION, 'test();'),
+      _expectId(main, SearchResultKind.REFERENCE, 'test);')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_LabelElement() async {
+    await _resolveTestUnit('''
 main() {
 label:
   while (true) {
@@ -90,17 +311,17 @@
   }
 }
 ''');
-    int offset = findOffset('label:');
-    List<String> main = [testUri, 'main'];
+    Element element = _findElement('label');
+    Element main = _findElement('main');
     var expected = [
       _expectId(main, SearchResultKind.REFERENCE, 'label; // 1'),
       _expectId(main, SearchResultKind.REFERENCE, 'label; // 2')
     ];
-    await _verifyReferences(offset, expected);
+    await _verifyReferences(element, expected);
   }
 
-  test_searchReferences_localVariable() async {
-    addTestFile(r'''
+  test_searchReferences_LocalVariableElement() async {
+    await _resolveTestUnit(r'''
 main() {
   var v;
   v = 1;
@@ -109,19 +330,19 @@
   v();
 }
 ''');
-    int offset = findOffset('v;');
-    List<String> main = [testUri, 'main'];
+    Element element = _findElement('v');
+    Element main = _findElement('main');
     var expected = [
       _expectId(main, SearchResultKind.WRITE, 'v = 1;'),
       _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
       _expectId(main, SearchResultKind.READ, 'v);'),
       _expectId(main, SearchResultKind.INVOCATION, 'v();')
     ];
-    await _verifyReferences(offset, expected);
+    await _verifyReferences(element, expected);
   }
 
-  test_searchReferences_localVariable_inForEachLoop() async {
-    addTestFile('''
+  test_searchReferences_localVariableElement_inForEachLoop() async {
+    await _resolveTestUnit('''
 main() {
   for (var v in []) {
     v = 1;
@@ -131,32 +352,352 @@
   }
 }
 ''');
-    int offset = findOffset('v in []');
-    List<String> main = [testUri, 'main'];
+    Element element = _findElementAtString('v in []');
+    Element main = _findElement('main');
     var expected = [
       _expectId(main, SearchResultKind.WRITE, 'v = 1;'),
       _expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
       _expectId(main, SearchResultKind.READ, 'v);'),
       _expectId(main, SearchResultKind.INVOCATION, 'v();')
     ];
-    await _verifyReferences(offset, expected);
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_MethodElement() async {
+    await _resolveTestUnit('''
+class A {
+  m() {}
+  main() {
+    m(); // 1
+    this.m(); // 2
+    print(m); // 3
+    print(this.m); // 4
+  }
+}
+''');
+    MethodElement method = _findElement('m');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(mainElement, SearchResultKind.INVOCATION, 'm(); // 1'),
+      _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'm(); // 2'),
+      _expectId(mainElement, SearchResultKind.REFERENCE, 'm); // 3'),
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'm); // 4')
+    ];
+    await _verifyReferences(method, expected);
+  }
+
+  test_searchReferences_MethodMember() async {
+    await _resolveTestUnit('''
+class A<T> {
+  T m() => null;
+}
+main(A<int> a) {
+  a.m(); // ref
+}
+''');
+    MethodMember method = _findElementAtString('m(); // ref');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'm(); // ref')
+    ];
+    await _verifyReferences(method, expected);
+  }
+
+  test_searchReferences_ParameterElement_ofConstructor() async {
+    await _resolveTestUnit('''
+class C {
+  var f;
+  C({p}) : f = p + 1 {
+    p = 2;
+    p += 3;
+    print(p);
+    p();
+  }
+}
+main() {
+  new C(p: 42);
+}
+''');
+    ParameterElement element = _findElement('p');
+    ClassElement classC = _findElement('C');
+    ConstructorElement constructorA = classC.unnamedConstructor;
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(constructorA, SearchResultKind.READ, 'p + 1 {'),
+      _expectId(constructorA, SearchResultKind.WRITE, 'p = 2;'),
+      _expectId(constructorA, SearchResultKind.READ_WRITE, 'p += 3;'),
+      _expectId(constructorA, SearchResultKind.READ, 'p);'),
+      _expectId(constructorA, SearchResultKind.INVOCATION, 'p();'),
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ParameterElement_ofLocalFunction() async {
+    await _resolveTestUnit('''
+main() {
+  foo({p}) {
+    p = 1;
+    p += 2;
+    print(p);
+    p();
+  }
+  foo(p: 42);
+}
+''');
+    ParameterElement element = _findElement('p');
+    Element fooElement = _findElement('foo');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
+      _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
+      _expectId(fooElement, SearchResultKind.READ, 'p);'),
+      _expectId(fooElement, SearchResultKind.INVOCATION, 'p();'),
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ParameterElement_ofMethod() async {
+    await _resolveTestUnit('''
+class C {
+  foo({p}) {
+    p = 1;
+    p += 2;
+    print(p);
+    p();
+  }
+}
+main(C c) {
+  c.foo(p: 42);
+}
+''');
+    ParameterElement element = _findElement('p');
+    Element fooElement = _findElement('foo');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
+      _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
+      _expectId(fooElement, SearchResultKind.READ, 'p);'),
+      _expectId(fooElement, SearchResultKind.INVOCATION, 'p();'),
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_ParameterElement_ofTopLevelFunction() async {
+    await _resolveTestUnit('''
+foo({p}) {
+  p = 1;
+  p += 2;
+  print(p);
+  p();
+}
+main() {
+  foo(p: 42);
+}
+''');
+    ParameterElement element = _findElement('p');
+    Element fooElement = _findElement('foo');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
+      _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
+      _expectId(fooElement, SearchResultKind.READ, 'p);'),
+      _expectId(fooElement, SearchResultKind.INVOCATION, 'p();'),
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_PropertyAccessorElement_getter() async {
+    await _resolveTestUnit('''
+class A {
+  get ggg => null;
+  main() {
+    print(ggg); // ref-nq
+    print(this.ggg); // ref-q
+    ggg(); // inv-nq
+    this.ggg(); // inv-q
+  }
+}
+''');
+    PropertyAccessorElement element = _findElement('ggg', ElementKind.GETTER);
+    Element main = _findElement('main');
+    var expected = [
+      _expectId(main, SearchResultKind.REFERENCE, 'ggg); // ref-nq'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'ggg); // ref-q'),
+      _expectId(main, SearchResultKind.INVOCATION, 'ggg(); // inv-nq'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'ggg(); // inv-q'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_PropertyAccessorElement_setter() async {
+    await _resolveTestUnit('''
+class A {
+  set s(x) {}
+  main() {
+    s = 1;
+    this.s = 2;
+  }
+}
+''');
+    PropertyAccessorElement element = _findElement('s=');
+    Element mainElement = _findElement('main');
+    var expected = [
+      _expectId(mainElement, SearchResultKind.REFERENCE, 's = 1'),
+      _expectIdQ(mainElement, SearchResultKind.REFERENCE, 's = 2')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_TopLevelVariableElement() async {
+    provider.newFile(
+        _p('$testProject/lib.dart'),
+        '''
+library lib;
+var V;
+''');
+    await _resolveTestUnit('''
+import 'lib.dart' show V; // imp
+import 'lib.dart' as pref;
+main() {
+  pref.V = 1; // q
+  print(pref.V); // q
+  pref.V(); // q
+  V = 1; // nq
+  print(V); // nq
+  V(); // nq
+}
+''');
+    ImportElement importElement = testLibraryElement.imports[0];
+    CompilationUnitElement impUnit =
+        importElement.importedLibrary.definingCompilationUnit;
+    TopLevelVariableElement variable = impUnit.topLevelVariables[0];
+    Element main = _findElement('main');
+    var expected = [
+      _expectIdQ(testUnitElement, SearchResultKind.REFERENCE, 'V; // imp'),
+      _expectIdQ(main, SearchResultKind.WRITE, 'V = 1; // q'),
+      _expectIdQ(main, SearchResultKind.READ, 'V); // q'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'V(); // q'),
+      _expectId(main, SearchResultKind.WRITE, 'V = 1; // nq'),
+      _expectId(main, SearchResultKind.READ, 'V); // nq'),
+      _expectId(main, SearchResultKind.INVOCATION, 'V(); // nq'),
+    ];
+    await _verifyReferences(variable, expected);
+  }
+
+  test_searchReferences_TypeParameterElement_ofClass() async {
+    await _resolveTestUnit('''
+class A<T> {
+  foo(T a) {}
+  bar(T b) {}
+}
+''');
+    TypeParameterElement element = _findElement('T');
+    Element a = _findElement('a');
+    Element b = _findElement('b');
+    var expected = [
+      _expectId(a, SearchResultKind.REFERENCE, 'T a'),
+      _expectId(b, SearchResultKind.REFERENCE, 'T b'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_TypeParameterElement_ofLocalFunction() async {
+    await _resolveTestUnit('''
+main() {
+  void foo<T>(T a) {
+    void bar(T b) {}
+  }
+}
+''');
+    TypeParameterElement element = _findElement('T');
+    Element a = _findElement('a');
+    Element b = _findElement('b');
+    var expected = [
+      _expectId(a, SearchResultKind.REFERENCE, 'T a'),
+      _expectId(b, SearchResultKind.REFERENCE, 'T b'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_TypeParameterElement_ofMethod() async {
+    await _resolveTestUnit('''
+class A {
+  foo<T>(T p) {}
+}
+''');
+    TypeParameterElement element = _findElement('T');
+    Element p = _findElement('p');
+    var expected = [
+      _expectId(p, SearchResultKind.REFERENCE, 'T p'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_TypeParameterElement_ofTopLevelFunction() async {
+    await _resolveTestUnit('''
+foo<T>(T a) {
+  bar(T b) {}
+}
+''');
+    TypeParameterElement element = _findElement('T');
+    Element a = _findElement('a');
+    Element b = _findElement('b');
+    var expected = [
+      _expectId(a, SearchResultKind.REFERENCE, 'T a'),
+      _expectId(b, SearchResultKind.REFERENCE, 'T b'),
+    ];
+    await _verifyReferences(element, expected);
   }
 
   ExpectedResult _expectId(
-      List<String> enclosingComponents, SearchResultKind kind, String search,
+      Element enclosingElement, SearchResultKind kind, String search,
       {int length, bool isResolved: true, bool isQualified: false}) {
     int offset = findOffset(search);
     if (length == null) {
       length = getLeadingIdentifierLength(search);
     }
-    return new ExpectedResult(enclosingComponents, kind, offset, length,
+    return new ExpectedResult(enclosingElement, kind, offset, length,
         isResolved: isResolved, isQualified: isQualified);
   }
 
+  /**
+   * Create [ExpectedResult] for a qualified and resolved match.
+   */
+  ExpectedResult _expectIdQ(
+      Element element, SearchResultKind kind, String search,
+      {int length, bool isResolved: true}) {
+    return _expectId(element, kind, search, isQualified: true, length: length);
+  }
+
+  Element _findElement(String name, [ElementKind kind]) {
+    return findChildElement(testUnit.element, name, kind);
+  }
+
+  Element _findElementAtString(String search) {
+    int offset = findOffset(search);
+    AstNode node = new NodeLocator(offset).searchWithin(testUnit);
+    return ElementLocator.locate(node);
+  }
+
+  String _p(String path) => provider.convertPath(path);
+
+  Future<Null> _resolveTestUnit(String code) async {
+    addTestFile(code);
+    if (testUnit == null) {
+      AnalysisResult result = await driver.getResult(testFile);
+      testUnit = result.unit;
+      testUnitElement = testUnit.element;
+      testLibraryElement = testUnitElement.library;
+    }
+  }
+
   Future _verifyReferences(
-      int offset, List<ExpectedResult> expectedMatches) async {
-    List<SearchResult> results =
-        await driver.search.references(testFile, offset);
+      Element element, List<ExpectedResult> expectedMatches) async {
+    List<SearchResult> results = await driver.search.references(element);
     _assertResults(results, expectedMatches);
     expect(results, hasLength(expectedMatches.length));
   }
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 3d4364f..5a18e5f 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart' show Predicate;
 import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:test/test.dart';
@@ -457,34 +457,34 @@
   void test_visitAnnotation() {
     String annotationName = "proxy";
     Annotation fromNode =
-        AstFactory.annotation(AstFactory.identifier3(annotationName));
+        AstTestFactory.annotation(AstTestFactory.identifier3(annotationName));
     Element element = ElementFactory.topLevelVariableElement2(annotationName);
     fromNode.element = element;
     Annotation toNode =
-        AstFactory.annotation(AstFactory.identifier3(annotationName));
+        AstTestFactory.annotation(AstTestFactory.identifier3(annotationName));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
   }
 
   void test_visitAsExpression() {
-    AsExpression fromNode = AstFactory.asExpression(
-        AstFactory.identifier3("x"), AstFactory.typeName4("A"));
+    AsExpression fromNode = AstTestFactory.asExpression(
+        AstTestFactory.identifier3("x"), AstTestFactory.typeName4("A"));
     DartType propagatedType = ElementFactory.classElement2("A").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("B").type;
     fromNode.staticType = staticType;
-    AsExpression toNode = AstFactory.asExpression(
-        AstFactory.identifier3("x"), AstFactory.typeName4("A"));
+    AsExpression toNode = AstTestFactory.asExpression(
+        AstTestFactory.identifier3("x"), AstTestFactory.typeName4("A"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitAssignmentExpression() {
-    AssignmentExpression fromNode = AstFactory.assignmentExpression(
-        AstFactory.identifier3("a"),
+    AssignmentExpression fromNode = AstTestFactory.assignmentExpression(
+        AstTestFactory.identifier3("a"),
         TokenType.PLUS_EQ,
-        AstFactory.identifier3("b"));
+        AstTestFactory.identifier3("b"));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     MethodElement propagatedElement =
         ElementFactory.methodElement("+", propagatedType);
@@ -494,10 +494,10 @@
     MethodElement staticElement = ElementFactory.methodElement("+", staticType);
     fromNode.staticElement = staticElement;
     fromNode.staticType = staticType;
-    AssignmentExpression toNode = AstFactory.assignmentExpression(
-        AstFactory.identifier3("a"),
+    AssignmentExpression toNode = AstTestFactory.assignmentExpression(
+        AstTestFactory.identifier3("a"),
         TokenType.PLUS_EQ,
-        AstFactory.identifier3("b"));
+        AstTestFactory.identifier3("b"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedElement, same(propagatedElement));
     expect(toNode.propagatedType, same(propagatedType));
@@ -506,10 +506,10 @@
   }
 
   void test_visitBinaryExpression() {
-    BinaryExpression fromNode = AstFactory.binaryExpression(
-        AstFactory.identifier3("a"),
+    BinaryExpression fromNode = AstTestFactory.binaryExpression(
+        AstTestFactory.identifier3("a"),
         TokenType.PLUS,
-        AstFactory.identifier3("b"));
+        AstTestFactory.identifier3("b"));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     MethodElement propagatedElement =
         ElementFactory.methodElement("+", propagatedType);
@@ -519,10 +519,10 @@
     MethodElement staticElement = ElementFactory.methodElement("+", staticType);
     fromNode.staticElement = staticElement;
     fromNode.staticType = staticType;
-    BinaryExpression toNode = AstFactory.binaryExpression(
-        AstFactory.identifier3("a"),
+    BinaryExpression toNode = AstTestFactory.binaryExpression(
+        AstTestFactory.identifier3("a"),
         TokenType.PLUS,
-        AstFactory.identifier3("b"));
+        AstTestFactory.identifier3("b"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedElement, same(propagatedElement));
     expect(toNode.propagatedType, same(propagatedType));
@@ -531,54 +531,54 @@
   }
 
   void test_visitBooleanLiteral() {
-    BooleanLiteral fromNode = AstFactory.booleanLiteral(true);
+    BooleanLiteral fromNode = AstTestFactory.booleanLiteral(true);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    BooleanLiteral toNode = AstFactory.booleanLiteral(true);
+    BooleanLiteral toNode = AstTestFactory.booleanLiteral(true);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitCascadeExpression() {
-    CascadeExpression fromNode = AstFactory.cascadeExpression(
-        AstFactory.identifier3("a"), [AstFactory.identifier3("b")]);
+    CascadeExpression fromNode = AstTestFactory.cascadeExpression(
+        AstTestFactory.identifier3("a"), [AstTestFactory.identifier3("b")]);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    CascadeExpression toNode = AstFactory.cascadeExpression(
-        AstFactory.identifier3("a"), [AstFactory.identifier3("b")]);
+    CascadeExpression toNode = AstTestFactory.cascadeExpression(
+        AstTestFactory.identifier3("a"), [AstTestFactory.identifier3("b")]);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitCompilationUnit() {
-    CompilationUnit fromNode = AstFactory.compilationUnit();
+    CompilationUnit fromNode = AstTestFactory.compilationUnit();
     CompilationUnitElement element =
         new CompilationUnitElementImpl("test.dart");
     fromNode.element = element;
-    CompilationUnit toNode = AstFactory.compilationUnit();
+    CompilationUnit toNode = AstTestFactory.compilationUnit();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
   }
 
   void test_visitConditionalExpression() {
-    ConditionalExpression fromNode = AstFactory.conditionalExpression(
-        AstFactory.identifier3("c"),
-        AstFactory.identifier3("a"),
-        AstFactory.identifier3("b"));
+    ConditionalExpression fromNode = AstTestFactory.conditionalExpression(
+        AstTestFactory.identifier3("c"),
+        AstTestFactory.identifier3("a"),
+        AstTestFactory.identifier3("b"));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    ConditionalExpression toNode = AstFactory.conditionalExpression(
-        AstFactory.identifier3("c"),
-        AstFactory.identifier3("a"),
-        AstFactory.identifier3("b"));
+    ConditionalExpression toNode = AstTestFactory.conditionalExpression(
+        AstTestFactory.identifier3("c"),
+        AstTestFactory.identifier3("a"),
+        AstTestFactory.identifier3("b"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
@@ -587,18 +587,18 @@
   void test_visitConstructorDeclaration() {
     String className = "A";
     String constructorName = "c";
-    ConstructorDeclaration fromNode = AstFactory.constructorDeclaration(
-        AstFactory.identifier3(className),
+    ConstructorDeclaration fromNode = AstTestFactory.constructorDeclaration(
+        AstTestFactory.identifier3(className),
         constructorName,
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         null);
     ConstructorElement element = ElementFactory.constructorElement2(
         ElementFactory.classElement2(className), constructorName);
     fromNode.element = element;
-    ConstructorDeclaration toNode = AstFactory.constructorDeclaration(
-        AstFactory.identifier3(className),
+    ConstructorDeclaration toNode = AstTestFactory.constructorDeclaration(
+        AstTestFactory.identifier3(className),
         constructorName,
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         null);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
@@ -606,40 +606,41 @@
 
   void test_visitConstructorName() {
     ConstructorName fromNode =
-        AstFactory.constructorName(AstFactory.typeName4("A"), "c");
+        AstTestFactory.constructorName(AstTestFactory.typeName4("A"), "c");
     ConstructorElement staticElement = ElementFactory.constructorElement2(
         ElementFactory.classElement2("A"), "c");
     fromNode.staticElement = staticElement;
     ConstructorName toNode =
-        AstFactory.constructorName(AstFactory.typeName4("A"), "c");
+        AstTestFactory.constructorName(AstTestFactory.typeName4("A"), "c");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.staticElement, same(staticElement));
   }
 
   void test_visitDoubleLiteral() {
-    DoubleLiteral fromNode = AstFactory.doubleLiteral(1.0);
+    DoubleLiteral fromNode = AstTestFactory.doubleLiteral(1.0);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    DoubleLiteral toNode = AstFactory.doubleLiteral(1.0);
+    DoubleLiteral toNode = AstTestFactory.doubleLiteral(1.0);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitExportDirective() {
-    ExportDirective fromNode = AstFactory.exportDirective2("dart:uri");
+    ExportDirective fromNode = AstTestFactory.exportDirective2("dart:uri");
     ExportElement element = new ExportElementImpl(-1);
     fromNode.element = element;
-    ExportDirective toNode = AstFactory.exportDirective2("dart:uri");
+    ExportDirective toNode = AstTestFactory.exportDirective2("dart:uri");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
   }
 
   void test_visitFunctionExpression() {
-    FunctionExpression fromNode = AstFactory.functionExpression2(
-        AstFactory.formalParameterList(), AstFactory.emptyFunctionBody());
+    FunctionExpression fromNode = AstTestFactory.functionExpression2(
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.emptyFunctionBody());
     MethodElement element = ElementFactory.methodElement(
         "m", ElementFactory.classElement2("C").type);
     fromNode.element = element;
@@ -647,8 +648,9 @@
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    FunctionExpression toNode = AstFactory.functionExpression2(
-        AstFactory.formalParameterList(), AstFactory.emptyFunctionBody());
+    FunctionExpression toNode = AstTestFactory.functionExpression2(
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.emptyFunctionBody());
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
     expect(toNode.propagatedType, same(propagatedType));
@@ -656,21 +658,21 @@
   }
 
   void test_visitFunctionExpressionInvocation() {
-    FunctionExpressionInvocation fromNode =
-        AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"));
+    FunctionExpressionInvocation fromNode = AstTestFactory
+        .functionExpressionInvocation(AstTestFactory.identifier3("f"));
     MethodElement propagatedElement = ElementFactory.methodElement(
         "m", ElementFactory.classElement2("C").type);
     fromNode.propagatedElement = propagatedElement;
     MethodElement staticElement = ElementFactory.methodElement(
         "m", ElementFactory.classElement2("C").type);
     fromNode.staticElement = staticElement;
-    FunctionExpressionInvocation toNode =
-        AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"));
+    FunctionExpressionInvocation toNode = AstTestFactory
+        .functionExpressionInvocation(AstTestFactory.identifier3("f"));
     ClassElement elementT = ElementFactory.classElement2('T');
-    fromNode.typeArguments =
-        AstFactory.typeArgumentList(<TypeName>[AstFactory.typeName(elementT)]);
-    toNode.typeArguments =
-        AstFactory.typeArgumentList(<TypeName>[AstFactory.typeName4('T')]);
+    fromNode.typeArguments = AstTestFactory
+        .typeArgumentList(<TypeName>[AstTestFactory.typeName(elementT)]);
+    toNode.typeArguments = AstTestFactory
+        .typeArgumentList(<TypeName>[AstTestFactory.typeName4('T')]);
 
     _copyAndVerifyInvocation(fromNode, toNode);
 
@@ -679,17 +681,18 @@
   }
 
   void test_visitImportDirective() {
-    ImportDirective fromNode = AstFactory.importDirective3("dart:uri", null);
+    ImportDirective fromNode =
+        AstTestFactory.importDirective3("dart:uri", null);
     ImportElement element = new ImportElementImpl(0);
     fromNode.element = element;
-    ImportDirective toNode = AstFactory.importDirective3("dart:uri", null);
+    ImportDirective toNode = AstTestFactory.importDirective3("dart:uri", null);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
   }
 
   void test_visitIndexExpression() {
-    IndexExpression fromNode = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.integer(0));
+    IndexExpression fromNode = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.integer(0));
     MethodElement propagatedElement = ElementFactory.methodElement(
         "m", ElementFactory.classElement2("C").type);
     MethodElement staticElement = ElementFactory.methodElement(
@@ -703,8 +706,8 @@
     fromNode.staticElement = staticElement;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    IndexExpression toNode = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.integer(0));
+    IndexExpression toNode = AstTestFactory.indexExpression(
+        AstTestFactory.identifier3("a"), AstTestFactory.integer(0));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.auxiliaryElements, same(auxiliaryElements));
     expect(toNode.propagatedElement, same(propagatedElement));
@@ -714,8 +717,9 @@
   }
 
   void test_visitInstanceCreationExpression() {
-    InstanceCreationExpression fromNode = AstFactory
-        .instanceCreationExpression2(Keyword.NEW, AstFactory.typeName4("C"));
+    InstanceCreationExpression fromNode =
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.NEW, AstTestFactory.typeName4("C"));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     ConstructorElement staticElement = ElementFactory.constructorElement2(
@@ -723,8 +727,9 @@
     fromNode.staticElement = staticElement;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    InstanceCreationExpression toNode = AstFactory.instanceCreationExpression2(
-        Keyword.NEW, AstFactory.typeName4("C"));
+    InstanceCreationExpression toNode =
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.NEW, AstTestFactory.typeName4("C"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticElement, same(staticElement));
@@ -732,26 +737,26 @@
   }
 
   void test_visitIntegerLiteral() {
-    IntegerLiteral fromNode = AstFactory.integer(2);
+    IntegerLiteral fromNode = AstTestFactory.integer(2);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    IntegerLiteral toNode = AstFactory.integer(2);
+    IntegerLiteral toNode = AstTestFactory.integer(2);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitIsExpression() {
-    IsExpression fromNode = AstFactory.isExpression(
-        AstFactory.identifier3("x"), false, AstFactory.typeName4("A"));
+    IsExpression fromNode = AstTestFactory.isExpression(
+        AstTestFactory.identifier3("x"), false, AstTestFactory.typeName4("A"));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    IsExpression toNode = AstFactory.isExpression(
-        AstFactory.identifier3("x"), false, AstFactory.typeName4("A"));
+    IsExpression toNode = AstTestFactory.isExpression(
+        AstTestFactory.identifier3("x"), false, AstTestFactory.typeName4("A"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
@@ -759,74 +764,74 @@
 
   void test_visitLibraryIdentifier() {
     LibraryIdentifier fromNode =
-        AstFactory.libraryIdentifier([AstFactory.identifier3("lib")]);
+        AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("lib")]);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
     LibraryIdentifier toNode =
-        AstFactory.libraryIdentifier([AstFactory.identifier3("lib")]);
+        AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("lib")]);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitListLiteral() {
-    ListLiteral fromNode = AstFactory.listLiteral();
+    ListLiteral fromNode = AstTestFactory.listLiteral();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    ListLiteral toNode = AstFactory.listLiteral();
+    ListLiteral toNode = AstTestFactory.listLiteral();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitMapLiteral() {
-    MapLiteral fromNode = AstFactory.mapLiteral2();
+    MapLiteral fromNode = AstTestFactory.mapLiteral2();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    MapLiteral toNode = AstFactory.mapLiteral2();
+    MapLiteral toNode = AstTestFactory.mapLiteral2();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitMethodInvocation() {
-    MethodInvocation fromNode = AstFactory.methodInvocation2("m");
-    MethodInvocation toNode = AstFactory.methodInvocation2("m");
+    MethodInvocation fromNode = AstTestFactory.methodInvocation2("m");
+    MethodInvocation toNode = AstTestFactory.methodInvocation2("m");
     ClassElement elementT = ElementFactory.classElement2('T');
-    fromNode.typeArguments =
-        AstFactory.typeArgumentList(<TypeName>[AstFactory.typeName(elementT)]);
-    toNode.typeArguments =
-        AstFactory.typeArgumentList(<TypeName>[AstFactory.typeName4('T')]);
+    fromNode.typeArguments = AstTestFactory
+        .typeArgumentList(<TypeName>[AstTestFactory.typeName(elementT)]);
+    toNode.typeArguments = AstTestFactory
+        .typeArgumentList(<TypeName>[AstTestFactory.typeName4('T')]);
     _copyAndVerifyInvocation(fromNode, toNode);
   }
 
   void test_visitNamedExpression() {
     NamedExpression fromNode =
-        AstFactory.namedExpression2("n", AstFactory.integer(0));
+        AstTestFactory.namedExpression2("n", AstTestFactory.integer(0));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
     NamedExpression toNode =
-        AstFactory.namedExpression2("n", AstFactory.integer(0));
+        AstTestFactory.namedExpression2("n", AstTestFactory.integer(0));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitNullLiteral() {
-    NullLiteral fromNode = AstFactory.nullLiteral();
+    NullLiteral fromNode = AstTestFactory.nullLiteral();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    NullLiteral toNode = AstFactory.nullLiteral();
+    NullLiteral toNode = AstTestFactory.nullLiteral();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
@@ -834,44 +839,44 @@
 
   void test_visitParenthesizedExpression() {
     ParenthesizedExpression fromNode =
-        AstFactory.parenthesizedExpression(AstFactory.integer(0));
+        AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
     ParenthesizedExpression toNode =
-        AstFactory.parenthesizedExpression(AstFactory.integer(0));
+        AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitPartDirective() {
-    PartDirective fromNode = AstFactory.partDirective2("part.dart");
+    PartDirective fromNode = AstTestFactory.partDirective2("part.dart");
     LibraryElement element = new LibraryElementImpl.forNode(
-        null, AstFactory.libraryIdentifier2(["lib"]));
+        null, AstTestFactory.libraryIdentifier2(["lib"]));
     fromNode.element = element;
-    PartDirective toNode = AstFactory.partDirective2("part.dart");
+    PartDirective toNode = AstTestFactory.partDirective2("part.dart");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
   }
 
   void test_visitPartOfDirective() {
-    PartOfDirective fromNode =
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
+    PartOfDirective fromNode = AstTestFactory
+        .partOfDirective(AstTestFactory.libraryIdentifier2(["lib"]));
     LibraryElement element = new LibraryElementImpl.forNode(
-        null, AstFactory.libraryIdentifier2(["lib"]));
+        null, AstTestFactory.libraryIdentifier2(["lib"]));
     fromNode.element = element;
-    PartOfDirective toNode =
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
+    PartOfDirective toNode = AstTestFactory
+        .partOfDirective(AstTestFactory.libraryIdentifier2(["lib"]));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.element, same(element));
   }
 
   void test_visitPostfixExpression() {
     String variableName = "x";
-    PostfixExpression fromNode = AstFactory.postfixExpression(
-        AstFactory.identifier3(variableName), TokenType.PLUS_PLUS);
+    PostfixExpression fromNode = AstTestFactory.postfixExpression(
+        AstTestFactory.identifier3(variableName), TokenType.PLUS_PLUS);
     MethodElement propagatedElement = ElementFactory.methodElement(
         "+", ElementFactory.classElement2("C").type);
     fromNode.propagatedElement = propagatedElement;
@@ -882,8 +887,8 @@
     fromNode.staticElement = staticElement;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    PostfixExpression toNode = AstFactory.postfixExpression(
-        AstFactory.identifier3(variableName), TokenType.PLUS_PLUS);
+    PostfixExpression toNode = AstTestFactory.postfixExpression(
+        AstTestFactory.identifier3(variableName), TokenType.PLUS_PLUS);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedElement, same(propagatedElement));
     expect(toNode.propagatedType, same(propagatedType));
@@ -892,20 +897,20 @@
   }
 
   void test_visitPrefixedIdentifier() {
-    PrefixedIdentifier fromNode = AstFactory.identifier5("p", "f");
+    PrefixedIdentifier fromNode = AstTestFactory.identifier5("p", "f");
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    PrefixedIdentifier toNode = AstFactory.identifier5("p", "f");
+    PrefixedIdentifier toNode = AstTestFactory.identifier5("p", "f");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitPrefixExpression() {
-    PrefixExpression fromNode = AstFactory.prefixExpression(
-        TokenType.PLUS_PLUS, AstFactory.identifier3("x"));
+    PrefixExpression fromNode = AstTestFactory.prefixExpression(
+        TokenType.PLUS_PLUS, AstTestFactory.identifier3("x"));
     MethodElement propagatedElement = ElementFactory.methodElement(
         "+", ElementFactory.classElement2("C").type);
     DartType propagatedType = ElementFactory.classElement2("C").type;
@@ -916,8 +921,8 @@
         "+", ElementFactory.classElement2("C").type);
     fromNode.staticElement = staticElement;
     fromNode.staticType = staticType;
-    PrefixExpression toNode = AstFactory.prefixExpression(
-        TokenType.PLUS_PLUS, AstFactory.identifier3("x"));
+    PrefixExpression toNode = AstTestFactory.prefixExpression(
+        TokenType.PLUS_PLUS, AstTestFactory.identifier3("x"));
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedElement, same(propagatedElement));
     expect(toNode.propagatedType, same(propagatedType));
@@ -927,13 +932,13 @@
 
   void test_visitPropertyAccess() {
     PropertyAccess fromNode =
-        AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
     PropertyAccess toNode =
-        AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
@@ -941,30 +946,30 @@
 
   void test_visitRedirectingConstructorInvocation() {
     RedirectingConstructorInvocation fromNode =
-        AstFactory.redirectingConstructorInvocation();
+        AstTestFactory.redirectingConstructorInvocation();
     ConstructorElement staticElement = ElementFactory.constructorElement2(
         ElementFactory.classElement2("C"), null);
     fromNode.staticElement = staticElement;
     RedirectingConstructorInvocation toNode =
-        AstFactory.redirectingConstructorInvocation();
+        AstTestFactory.redirectingConstructorInvocation();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.staticElement, same(staticElement));
   }
 
   void test_visitRethrowExpression() {
-    RethrowExpression fromNode = AstFactory.rethrowExpression();
+    RethrowExpression fromNode = AstTestFactory.rethrowExpression();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    RethrowExpression toNode = AstFactory.rethrowExpression();
+    RethrowExpression toNode = AstTestFactory.rethrowExpression();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitSimpleIdentifier() {
-    SimpleIdentifier fromNode = AstFactory.identifier3("x");
+    SimpleIdentifier fromNode = AstTestFactory.identifier3("x");
     MethodElement propagatedElement = ElementFactory.methodElement(
         "m", ElementFactory.classElement2("C").type);
     MethodElement staticElement = ElementFactory.methodElement(
@@ -978,7 +983,7 @@
     fromNode.staticElement = staticElement;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    SimpleIdentifier toNode = AstFactory.identifier3("x");
+    SimpleIdentifier toNode = AstTestFactory.identifier3("x");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.auxiliaryElements, same(auxiliaryElements));
     expect(toNode.propagatedElement, same(propagatedElement));
@@ -988,12 +993,12 @@
   }
 
   void test_visitSimpleStringLiteral() {
-    SimpleStringLiteral fromNode = AstFactory.string2("abc");
+    SimpleStringLiteral fromNode = AstTestFactory.string2("abc");
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    SimpleStringLiteral toNode = AstFactory.string2("abc");
+    SimpleStringLiteral toNode = AstTestFactory.string2("abc");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
@@ -1001,13 +1006,13 @@
 
   void test_visitStringInterpolation() {
     StringInterpolation fromNode =
-        AstFactory.string([AstFactory.interpolationString("a", "'a'")]);
+        AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
     StringInterpolation toNode =
-        AstFactory.string([AstFactory.interpolationString("a", "'a'")]);
+        AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
@@ -1015,68 +1020,69 @@
 
   void test_visitSuperConstructorInvocation() {
     SuperConstructorInvocation fromNode =
-        AstFactory.superConstructorInvocation();
+        AstTestFactory.superConstructorInvocation();
     ConstructorElement staticElement = ElementFactory.constructorElement2(
         ElementFactory.classElement2("C"), null);
     fromNode.staticElement = staticElement;
-    SuperConstructorInvocation toNode = AstFactory.superConstructorInvocation();
+    SuperConstructorInvocation toNode =
+        AstTestFactory.superConstructorInvocation();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.staticElement, same(staticElement));
   }
 
   void test_visitSuperExpression() {
-    SuperExpression fromNode = AstFactory.superExpression();
+    SuperExpression fromNode = AstTestFactory.superExpression();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    SuperExpression toNode = AstFactory.superExpression();
+    SuperExpression toNode = AstTestFactory.superExpression();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitSymbolLiteral() {
-    SymbolLiteral fromNode = AstFactory.symbolLiteral(["s"]);
+    SymbolLiteral fromNode = AstTestFactory.symbolLiteral(["s"]);
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    SymbolLiteral toNode = AstFactory.symbolLiteral(["s"]);
+    SymbolLiteral toNode = AstTestFactory.symbolLiteral(["s"]);
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitThisExpression() {
-    ThisExpression fromNode = AstFactory.thisExpression();
+    ThisExpression fromNode = AstTestFactory.thisExpression();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    ThisExpression toNode = AstFactory.thisExpression();
+    ThisExpression toNode = AstTestFactory.thisExpression();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitThrowExpression() {
-    ThrowExpression fromNode = AstFactory.throwExpression();
+    ThrowExpression fromNode = AstTestFactory.throwExpression();
     DartType propagatedType = ElementFactory.classElement2("C").type;
     fromNode.propagatedType = propagatedType;
     DartType staticType = ElementFactory.classElement2("C").type;
     fromNode.staticType = staticType;
-    ThrowExpression toNode = AstFactory.throwExpression();
+    ThrowExpression toNode = AstTestFactory.throwExpression();
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.propagatedType, same(propagatedType));
     expect(toNode.staticType, same(staticType));
   }
 
   void test_visitTypeName() {
-    TypeName fromNode = AstFactory.typeName4("C");
+    TypeName fromNode = AstTestFactory.typeName4("C");
     DartType type = ElementFactory.classElement2("C").type;
     fromNode.type = type;
-    TypeName toNode = AstFactory.typeName4("C");
+    TypeName toNode = AstTestFactory.typeName4("C");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
     expect(toNode.type, same(type));
   }
@@ -1115,246 +1121,257 @@
   void test_visitAdjacentStrings() {
     _assertSource(
         "'a' 'b'",
-        AstFactory.adjacentStrings(
-            [AstFactory.string2("a"), AstFactory.string2("b")]));
+        AstTestFactory.adjacentStrings(
+            [AstTestFactory.string2("a"), AstTestFactory.string2("b")]));
   }
 
   void test_visitAnnotation_constant() {
-    _assertSource("@A", AstFactory.annotation(AstFactory.identifier3("A")));
+    _assertSource(
+        "@A", AstTestFactory.annotation(AstTestFactory.identifier3("A")));
   }
 
   void test_visitAnnotation_constructor() {
     _assertSource(
         "@A.c()",
-        AstFactory.annotation2(AstFactory.identifier3("A"),
-            AstFactory.identifier3("c"), AstFactory.argumentList()));
+        AstTestFactory.annotation2(AstTestFactory.identifier3("A"),
+            AstTestFactory.identifier3("c"), AstTestFactory.argumentList()));
   }
 
   void test_visitArgumentList() {
     _assertSource(
         "(a, b)",
-        AstFactory.argumentList(
-            [AstFactory.identifier3("a"), AstFactory.identifier3("b")]));
+        AstTestFactory.argumentList([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b")
+        ]));
   }
 
   void test_visitAsExpression() {
     _assertSource(
         "e as T",
-        AstFactory.asExpression(
-            AstFactory.identifier3("e"), AstFactory.typeName4("T")));
+        AstTestFactory.asExpression(
+            AstTestFactory.identifier3("e"), AstTestFactory.typeName4("T")));
   }
 
   void test_visitAssertStatement() {
-    _assertSource(
-        "assert (a);", AstFactory.assertStatement(AstFactory.identifier3("a")));
+    _assertSource("assert (a);",
+        AstTestFactory.assertStatement(AstTestFactory.identifier3("a")));
   }
 
   void test_visitAssertStatement_withMessage() {
     _assertSource(
         "assert (a, b);",
-        AstFactory.assertStatement(
-            AstFactory.identifier3("a"), AstFactory.identifier3('b')));
+        AstTestFactory.assertStatement(
+            AstTestFactory.identifier3("a"), AstTestFactory.identifier3('b')));
   }
 
   void test_visitAssignmentExpression() {
     _assertSource(
         "a = b",
-        AstFactory.assignmentExpression(AstFactory.identifier3("a"),
-            TokenType.EQ, AstFactory.identifier3("b")));
+        AstTestFactory.assignmentExpression(AstTestFactory.identifier3("a"),
+            TokenType.EQ, AstTestFactory.identifier3("b")));
   }
 
   void test_visitAwaitExpression() {
-    _assertSource(
-        "await e", AstFactory.awaitExpression(AstFactory.identifier3("e")));
+    _assertSource("await e",
+        AstTestFactory.awaitExpression(AstTestFactory.identifier3("e")));
   }
 
   void test_visitBinaryExpression() {
     _assertSource(
         "a + b",
-        AstFactory.binaryExpression(AstFactory.identifier3("a"), TokenType.PLUS,
-            AstFactory.identifier3("b")));
+        AstTestFactory.binaryExpression(AstTestFactory.identifier3("a"),
+            TokenType.PLUS, AstTestFactory.identifier3("b")));
   }
 
   void test_visitBlock_empty() {
-    _assertSource("{}", AstFactory.block());
+    _assertSource("{}", AstTestFactory.block());
   }
 
   void test_visitBlock_nonEmpty() {
     _assertSource(
         "{break; break;}",
-        AstFactory
-            .block([AstFactory.breakStatement(), AstFactory.breakStatement()]));
+        AstTestFactory.block([
+          AstTestFactory.breakStatement(),
+          AstTestFactory.breakStatement()
+        ]));
   }
 
   void test_visitBlockFunctionBody_async() {
-    _assertSource("async {}", AstFactory.asyncBlockFunctionBody());
+    _assertSource("async {}", AstTestFactory.asyncBlockFunctionBody());
   }
 
   void test_visitBlockFunctionBody_async_star() {
-    _assertSource("async* {}", AstFactory.asyncGeneratorBlockFunctionBody());
+    _assertSource(
+        "async* {}", AstTestFactory.asyncGeneratorBlockFunctionBody());
   }
 
   void test_visitBlockFunctionBody_simple() {
-    _assertSource("{}", AstFactory.blockFunctionBody2());
+    _assertSource("{}", AstTestFactory.blockFunctionBody2());
   }
 
   void test_visitBlockFunctionBody_sync() {
-    _assertSource("sync {}", AstFactory.syncBlockFunctionBody());
+    _assertSource("sync {}", AstTestFactory.syncBlockFunctionBody());
   }
 
   void test_visitBlockFunctionBody_sync_star() {
-    _assertSource("sync* {}", AstFactory.syncGeneratorBlockFunctionBody());
+    _assertSource("sync* {}", AstTestFactory.syncGeneratorBlockFunctionBody());
   }
 
   void test_visitBooleanLiteral_false() {
-    _assertSource("false", AstFactory.booleanLiteral(false));
+    _assertSource("false", AstTestFactory.booleanLiteral(false));
   }
 
   void test_visitBooleanLiteral_true() {
-    _assertSource("true", AstFactory.booleanLiteral(true));
+    _assertSource("true", AstTestFactory.booleanLiteral(true));
   }
 
   void test_visitBreakStatement_label() {
-    _assertSource("break l;", AstFactory.breakStatement2("l"));
+    _assertSource("break l;", AstTestFactory.breakStatement2("l"));
   }
 
   void test_visitBreakStatement_noLabel() {
-    _assertSource("break;", AstFactory.breakStatement());
+    _assertSource("break;", AstTestFactory.breakStatement());
   }
 
   void test_visitCascadeExpression_field() {
     _assertSource(
         "a..b..c",
-        AstFactory.cascadeExpression(AstFactory.identifier3("a"), [
-          AstFactory.cascadedPropertyAccess("b"),
-          AstFactory.cascadedPropertyAccess("c")
+        AstTestFactory.cascadeExpression(AstTestFactory.identifier3("a"), [
+          AstTestFactory.cascadedPropertyAccess("b"),
+          AstTestFactory.cascadedPropertyAccess("c")
         ]));
   }
 
   void test_visitCascadeExpression_index() {
     _assertSource(
         "a..[0]..[1]",
-        AstFactory.cascadeExpression(AstFactory.identifier3("a"), [
-          AstFactory.cascadedIndexExpression(AstFactory.integer(0)),
-          AstFactory.cascadedIndexExpression(AstFactory.integer(1))
+        AstTestFactory.cascadeExpression(AstTestFactory.identifier3("a"), [
+          AstTestFactory.cascadedIndexExpression(AstTestFactory.integer(0)),
+          AstTestFactory.cascadedIndexExpression(AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitCascadeExpression_method() {
     _assertSource(
         "a..b()..c()",
-        AstFactory.cascadeExpression(AstFactory.identifier3("a"), [
-          AstFactory.cascadedMethodInvocation("b"),
-          AstFactory.cascadedMethodInvocation("c")
+        AstTestFactory.cascadeExpression(AstTestFactory.identifier3("a"), [
+          AstTestFactory.cascadedMethodInvocation("b"),
+          AstTestFactory.cascadedMethodInvocation("c")
         ]));
   }
 
   void test_visitCatchClause_catch_noStack() {
-    _assertSource("catch (e) {}", AstFactory.catchClause("e"));
+    _assertSource("catch (e) {}", AstTestFactory.catchClause("e"));
   }
 
   void test_visitCatchClause_catch_stack() {
-    _assertSource("catch (e, s) {}", AstFactory.catchClause2("e", "s"));
+    _assertSource("catch (e, s) {}", AstTestFactory.catchClause2("e", "s"));
   }
 
   void test_visitCatchClause_on() {
     _assertSource(
-        "on E {}", AstFactory.catchClause3(AstFactory.typeName4("E")));
+        "on E {}", AstTestFactory.catchClause3(AstTestFactory.typeName4("E")));
   }
 
   void test_visitCatchClause_on_catch() {
     _assertSource("on E catch (e) {}",
-        AstFactory.catchClause4(AstFactory.typeName4("E"), "e"));
+        AstTestFactory.catchClause4(AstTestFactory.typeName4("E"), "e"));
   }
 
   void test_visitClassDeclaration_abstract() {
     _assertSource(
         "abstract class C {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             Keyword.ABSTRACT, "C", null, null, null, null));
   }
 
   void test_visitClassDeclaration_empty() {
     _assertSource("class C {}",
-        AstFactory.classDeclaration(null, "C", null, null, null, null));
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null));
   }
 
   void test_visitClassDeclaration_extends() {
     _assertSource(
         "class C extends A {}",
-        AstFactory.classDeclaration(null, "C", null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")), null, null));
+        AstTestFactory.classDeclaration(
+            null,
+            "C",
+            null,
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            null,
+            null));
   }
 
   void test_visitClassDeclaration_extends_implements() {
     _assertSource(
         "class C extends A implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
             null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
             null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_extends_with() {
     _assertSource(
         "class C extends A with M {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
             null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
             null));
   }
 
   void test_visitClassDeclaration_extends_with_implements() {
     _assertSource(
         "class C extends A with M implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
             null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_implements() {
     _assertSource(
         "class C implements B {}",
-        AstFactory.classDeclaration(null, "C", null, null, null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+        AstTestFactory.classDeclaration(null, "C", null, null, null,
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_multipleMember() {
     _assertSource(
         "class C {var a; var b;}",
-        AstFactory.classDeclaration(null, "C", null, null, null, null, [
-          AstFactory.fieldDeclaration2(
-              false, Keyword.VAR, [AstFactory.variableDeclaration("a")]),
-          AstFactory.fieldDeclaration2(
-              false, Keyword.VAR, [AstFactory.variableDeclaration("b")])
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null, [
+          AstTestFactory.fieldDeclaration2(
+              false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]),
+          AstTestFactory.fieldDeclaration2(
+              false, Keyword.VAR, [AstTestFactory.variableDeclaration("b")])
         ]));
   }
 
   void test_visitClassDeclaration_parameters() {
     _assertSource(
         "class C<E> {}",
-        AstFactory.classDeclaration(
-            null, "C", AstFactory.typeParameterList(["E"]), null, null, null));
+        AstTestFactory.classDeclaration(null, "C",
+            AstTestFactory.typeParameterList(["E"]), null, null, null));
   }
 
   void test_visitClassDeclaration_parameters_extends() {
     _assertSource(
         "class C<E> extends A {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
             null,
             null));
   }
@@ -1362,102 +1379,102 @@
   void test_visitClassDeclaration_parameters_extends_implements() {
     _assertSource(
         "class C<E> extends A implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
             null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_parameters_extends_with() {
     _assertSource(
         "class C<E> extends A with M {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
             null));
   }
 
   void test_visitClassDeclaration_parameters_extends_with_implements() {
     _assertSource(
         "class C<E> extends A with M implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_parameters_implements() {
     _assertSource(
         "class C<E> implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             null,
             null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_singleMember() {
     _assertSource(
         "class C {var a;}",
-        AstFactory.classDeclaration(null, "C", null, null, null, null, [
-          AstFactory.fieldDeclaration2(
-              false, Keyword.VAR, [AstFactory.variableDeclaration("a")])
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null, [
+          AstTestFactory.fieldDeclaration2(
+              false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitClassDeclaration_withMetadata() {
     ClassDeclaration declaration =
-        AstFactory.classDeclaration(null, "C", null, null, null, null);
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null);
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated class C {}", declaration);
   }
 
   void test_visitClassTypeAlias_abstract() {
     _assertSource(
         "abstract class C = S with M1;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
             null,
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
             null));
   }
 
   void test_visitClassTypeAlias_abstract_implements() {
     _assertSource(
         "abstract class C = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
             null,
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_generic() {
     _assertSource(
         "class C<E> = S<E> with M1<E>;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             null,
-            AstFactory.typeName4("S", [AstFactory.typeName4("E")]),
-            AstFactory.withClause([
-              AstFactory.typeName4("M1", [AstFactory.typeName4("E")])
+            AstTestFactory.typeName4("S", [AstTestFactory.typeName4("E")]),
+            AstTestFactory.withClause([
+              AstTestFactory.typeName4("M1", [AstTestFactory.typeName4("E")])
             ]),
             null));
   }
@@ -1465,68 +1482,73 @@
   void test_visitClassTypeAlias_implements() {
     _assertSource(
         "class C = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
             null,
             null,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_minimal() {
     _assertSource(
         "class C = S with M1;",
-        AstFactory.classTypeAlias("C", null, null, AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]), null));
+        AstTestFactory.classTypeAlias(
+            "C",
+            null,
+            null,
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            null));
   }
 
   void test_visitClassTypeAlias_parameters_abstract() {
     _assertSource(
         "abstract class C<E> = S with M1;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
             null));
   }
 
   void test_visitClassTypeAlias_parameters_abstract_implements() {
     _assertSource(
         "abstract class C<E> = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_parameters_implements() {
     _assertSource(
         "class C<E> = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             null,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_withMetadata() {
-    ClassTypeAlias declaration = AstFactory.classTypeAlias(
+    ClassTypeAlias declaration = AstTestFactory.classTypeAlias(
         "C",
         null,
         null,
-        AstFactory.typeName4("S"),
-        AstFactory.withClause([AstFactory.typeName4("M1")]),
+        AstTestFactory.typeName4("S"),
+        AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
         null);
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated class C = S with M1;", declaration);
   }
 
@@ -1538,374 +1560,388 @@
   }
 
   void test_visitCommentReference() {
-    _assertSource("", new CommentReference(null, AstFactory.identifier3("a")));
+    _assertSource(
+        "", new CommentReference(null, AstTestFactory.identifier3("a")));
   }
 
   void test_visitCompilationUnit_declaration() {
     _assertSource(
         "var a;",
-        AstFactory.compilationUnit2([
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+        AstTestFactory.compilationUnit2([
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitCompilationUnit_directive() {
-    _assertSource("library l;",
-        AstFactory.compilationUnit3([AstFactory.libraryDirective2("l")]));
+    _assertSource(
+        "library l;",
+        AstTestFactory
+            .compilationUnit3([AstTestFactory.libraryDirective2("l")]));
   }
 
   void test_visitCompilationUnit_directive_declaration() {
     _assertSource(
         "library l; var a;",
-        AstFactory.compilationUnit4([
-          AstFactory.libraryDirective2("l")
+        AstTestFactory.compilationUnit4([
+          AstTestFactory.libraryDirective2("l")
         ], [
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitCompilationUnit_empty() {
-    _assertSource("", AstFactory.compilationUnit());
+    _assertSource("", AstTestFactory.compilationUnit());
   }
 
   void test_visitCompilationUnit_script() {
     _assertSource(
-        "!#/bin/dartvm", AstFactory.compilationUnit5("!#/bin/dartvm"));
+        "!#/bin/dartvm", AstTestFactory.compilationUnit5("!#/bin/dartvm"));
   }
 
   void test_visitCompilationUnit_script_declaration() {
     _assertSource(
         "!#/bin/dartvm var a;",
-        AstFactory.compilationUnit6("!#/bin/dartvm", [
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+        AstTestFactory.compilationUnit6("!#/bin/dartvm", [
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitCompilationUnit_script_directive() {
     _assertSource(
         "!#/bin/dartvm library l;",
-        AstFactory.compilationUnit7(
-            "!#/bin/dartvm", [AstFactory.libraryDirective2("l")]));
+        AstTestFactory.compilationUnit7(
+            "!#/bin/dartvm", [AstTestFactory.libraryDirective2("l")]));
   }
 
   void test_visitCompilationUnit_script_directives_declarations() {
     _assertSource(
         "!#/bin/dartvm library l; var a;",
-        AstFactory.compilationUnit8("!#/bin/dartvm", [
-          AstFactory.libraryDirective2("l")
+        AstTestFactory.compilationUnit8("!#/bin/dartvm", [
+          AstTestFactory.libraryDirective2("l")
         ], [
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitConditionalExpression() {
     _assertSource(
         "a ? b : c",
-        AstFactory.conditionalExpression(AstFactory.identifier3("a"),
-            AstFactory.identifier3("b"), AstFactory.identifier3("c")));
+        AstTestFactory.conditionalExpression(AstTestFactory.identifier3("a"),
+            AstTestFactory.identifier3("b"), AstTestFactory.identifier3("c")));
   }
 
   void test_visitConstructorDeclaration_const() {
     _assertSource(
         "const C() {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             Keyword.CONST,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_external() {
     _assertSource(
         "external C();",
-        AstFactory.constructorDeclaration(AstFactory.identifier3("C"), null,
-            AstFactory.formalParameterList(), null));
+        AstTestFactory.constructorDeclaration(AstTestFactory.identifier3("C"),
+            null, AstTestFactory.formalParameterList(), null));
   }
 
   void test_visitConstructorDeclaration_minimal() {
     _assertSource(
         "C() {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_multipleInitializers() {
     _assertSource(
         "C() : a = b, c = d {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             [
-              AstFactory.constructorFieldInitializer(
-                  false, "a", AstFactory.identifier3("b")),
-              AstFactory.constructorFieldInitializer(
-                  false, "c", AstFactory.identifier3("d"))
+              AstTestFactory.constructorFieldInitializer(
+                  false, "a", AstTestFactory.identifier3("b")),
+              AstTestFactory.constructorFieldInitializer(
+                  false, "c", AstTestFactory.identifier3("d"))
             ],
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_multipleParameters() {
     _assertSource(
         "C(var a, var b) {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList([
-              AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-              AstFactory.simpleFormalParameter(Keyword.VAR, "b")
+            AstTestFactory.formalParameterList([
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "b")
             ]),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_named() {
     _assertSource(
         "C.m() {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             "m",
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_singleInitializer() {
     _assertSource(
         "C() : a = b {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             [
-              AstFactory.constructorFieldInitializer(
-                  false, "a", AstFactory.identifier3("b"))
+              AstTestFactory.constructorFieldInitializer(
+                  false, "a", AstTestFactory.identifier3("b"))
             ],
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_withMetadata() {
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
         null,
         null,
-        AstFactory.identifier3("C"),
+        AstTestFactory.identifier3("C"),
         null,
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         null,
-        AstFactory.blockFunctionBody2());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+        AstTestFactory.blockFunctionBody2());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated C() {}", declaration);
   }
 
   void test_visitConstructorFieldInitializer_withoutThis() {
     _assertSource(
         "a = b",
-        AstFactory.constructorFieldInitializer(
-            false, "a", AstFactory.identifier3("b")));
+        AstTestFactory.constructorFieldInitializer(
+            false, "a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitConstructorFieldInitializer_withThis() {
     _assertSource(
         "this.a = b",
-        AstFactory.constructorFieldInitializer(
-            true, "a", AstFactory.identifier3("b")));
+        AstTestFactory.constructorFieldInitializer(
+            true, "a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitConstructorName_named_prefix() {
-    _assertSource("p.C.n",
-        AstFactory.constructorName(AstFactory.typeName4("p.C.n"), null));
+    _assertSource(
+        "p.C.n",
+        AstTestFactory.constructorName(
+            AstTestFactory.typeName4("p.C.n"), null));
   }
 
   void test_visitConstructorName_unnamed_noPrefix() {
-    _assertSource(
-        "C", AstFactory.constructorName(AstFactory.typeName4("C"), null));
+    _assertSource("C",
+        AstTestFactory.constructorName(AstTestFactory.typeName4("C"), null));
   }
 
   void test_visitConstructorName_unnamed_prefix() {
     _assertSource(
         "p.C",
-        AstFactory.constructorName(
-            AstFactory.typeName3(AstFactory.identifier5("p", "C")), null));
+        AstTestFactory.constructorName(
+            AstTestFactory.typeName3(AstTestFactory.identifier5("p", "C")),
+            null));
   }
 
   void test_visitContinueStatement_label() {
-    _assertSource("continue l;", AstFactory.continueStatement("l"));
+    _assertSource("continue l;", AstTestFactory.continueStatement("l"));
   }
 
   void test_visitContinueStatement_noLabel() {
-    _assertSource("continue;", AstFactory.continueStatement());
+    _assertSource("continue;", AstTestFactory.continueStatement());
   }
 
   void test_visitDefaultFormalParameter_annotation() {
-    DefaultFormalParameter parameter = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0));
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    DefaultFormalParameter parameter = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p"), AstTestFactory.integer(0));
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A p = 0', parameter);
   }
 
   void test_visitDefaultFormalParameter_named_noValue() {
     _assertSource(
         "p",
-        AstFactory.namedFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), null));
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"), null));
   }
 
   void test_visitDefaultFormalParameter_named_value() {
     _assertSource(
         "p : 0",
-        AstFactory.namedFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0)));
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitDefaultFormalParameter_positional_noValue() {
     _assertSource(
         "p",
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), null));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"), null));
   }
 
   void test_visitDefaultFormalParameter_positional_value() {
     _assertSource(
         "p = 0",
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0)));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitDoStatement() {
     _assertSource(
         "do {} while (c);",
-        AstFactory.doStatement(
-            AstFactory.block(), AstFactory.identifier3("c")));
+        AstTestFactory.doStatement(
+            AstTestFactory.block(), AstTestFactory.identifier3("c")));
   }
 
   void test_visitDoubleLiteral() {
-    _assertSource("4.2", AstFactory.doubleLiteral(4.2));
+    _assertSource("4.2", AstTestFactory.doubleLiteral(4.2));
   }
 
   void test_visitEmptyFunctionBody() {
-    _assertSource(";", AstFactory.emptyFunctionBody());
+    _assertSource(";", AstTestFactory.emptyFunctionBody());
   }
 
   void test_visitEmptyStatement() {
-    _assertSource(";", AstFactory.emptyStatement());
+    _assertSource(";", AstTestFactory.emptyStatement());
   }
 
   void test_visitEnumDeclaration_multiple() {
-    _assertSource(
-        "enum E {ONE, TWO}", AstFactory.enumDeclaration2("E", ["ONE", "TWO"]));
+    _assertSource("enum E {ONE, TWO}",
+        AstTestFactory.enumDeclaration2("E", ["ONE", "TWO"]));
   }
 
   void test_visitEnumDeclaration_single() {
-    _assertSource("enum E {ONE}", AstFactory.enumDeclaration2("E", ["ONE"]));
+    _assertSource(
+        "enum E {ONE}", AstTestFactory.enumDeclaration2("E", ["ONE"]));
   }
 
   void test_visitExportDirective_combinator() {
     _assertSource(
         "export 'a.dart' show A;",
-        AstFactory.exportDirective2("a.dart", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")])
+        AstTestFactory.exportDirective2("a.dart", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
         ]));
   }
 
   void test_visitExportDirective_combinators() {
     _assertSource(
         "export 'a.dart' show A hide B;",
-        AstFactory.exportDirective2("a.dart", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")]),
-          AstFactory.hideCombinator([AstFactory.identifier3("B")])
+        AstTestFactory.exportDirective2("a.dart", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
+          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
         ]));
   }
 
   void test_visitExportDirective_minimal() {
-    _assertSource("export 'a.dart';", AstFactory.exportDirective2("a.dart"));
+    _assertSource(
+        "export 'a.dart';", AstTestFactory.exportDirective2("a.dart"));
   }
 
   void test_visitExportDirective_withMetadata() {
-    ExportDirective directive = AstFactory.exportDirective2("a.dart");
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    ExportDirective directive = AstTestFactory.exportDirective2("a.dart");
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated export 'a.dart';", directive);
   }
 
   void test_visitExpressionFunctionBody_async() {
-    _assertSource("async => a;",
-        AstFactory.asyncExpressionFunctionBody(AstFactory.identifier3("a")));
+    _assertSource(
+        "async => a;",
+        AstTestFactory
+            .asyncExpressionFunctionBody(AstTestFactory.identifier3("a")));
   }
 
   void test_visitExpressionFunctionBody_simple() {
     _assertSource("=> a;",
-        AstFactory.expressionFunctionBody(AstFactory.identifier3("a")));
+        AstTestFactory.expressionFunctionBody(AstTestFactory.identifier3("a")));
   }
 
   void test_visitExpressionStatement() {
-    _assertSource(
-        "a;", AstFactory.expressionStatement(AstFactory.identifier3("a")));
+    _assertSource("a;",
+        AstTestFactory.expressionStatement(AstTestFactory.identifier3("a")));
   }
 
   void test_visitExtendsClause() {
-    _assertSource(
-        "extends C", AstFactory.extendsClause(AstFactory.typeName4("C")));
+    _assertSource("extends C",
+        AstTestFactory.extendsClause(AstTestFactory.typeName4("C")));
   }
 
   void test_visitFieldDeclaration_instance() {
     _assertSource(
         "var a;",
-        AstFactory.fieldDeclaration2(
-            false, Keyword.VAR, [AstFactory.variableDeclaration("a")]));
+        AstTestFactory.fieldDeclaration2(
+            false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]));
   }
 
   void test_visitFieldDeclaration_static() {
     _assertSource(
         "static var a;",
-        AstFactory.fieldDeclaration2(
-            true, Keyword.VAR, [AstFactory.variableDeclaration("a")]));
+        AstTestFactory.fieldDeclaration2(
+            true, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]));
   }
 
   void test_visitFieldDeclaration_withMetadata() {
-    FieldDeclaration declaration = AstFactory.fieldDeclaration2(
-        false, Keyword.VAR, [AstFactory.variableDeclaration("a")]);
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    FieldDeclaration declaration = AstTestFactory.fieldDeclaration2(
+        false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]);
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated var a;", declaration);
   }
 
   void test_visitFieldFormalParameter_annotation() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('f');
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    FieldFormalParameter parameter = AstTestFactory.fieldFormalParameter2('f');
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A this.f', parameter);
   }
 
   void test_visitFieldFormalParameter_functionTyped() {
     _assertSource(
         "A this.a(b)",
-        AstFactory.fieldFormalParameter(
+        AstTestFactory.fieldFormalParameter(
             null,
-            AstFactory.typeName4("A"),
+            AstTestFactory.typeName4("A"),
             "a",
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter3("b")])));
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter3("b")])));
   }
 
   void test_visitFieldFormalParameter_functionTyped_typeParameters() {
@@ -1915,37 +1951,39 @@
             null,
             null,
             null,
-            AstFactory.typeName4('A'),
+            AstTestFactory.typeName4('A'),
             TokenFactory.tokenFromKeyword(Keyword.THIS),
             TokenFactory.tokenFromType(TokenType.PERIOD),
-            AstFactory.identifier3('a'),
-            AstFactory.typeParameterList(['E', 'F']),
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter3("b")])));
+            AstTestFactory.identifier3('a'),
+            AstTestFactory.typeParameterList(['E', 'F']),
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter3("b")])));
   }
 
   void test_visitFieldFormalParameter_keyword() {
-    _assertSource(
-        "var this.a", AstFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
+    _assertSource("var this.a",
+        AstTestFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
   }
 
   void test_visitFieldFormalParameter_keywordAndType() {
     _assertSource(
         "final A this.a",
-        AstFactory.fieldFormalParameter(
-            Keyword.FINAL, AstFactory.typeName4("A"), "a"));
+        AstTestFactory.fieldFormalParameter(
+            Keyword.FINAL, AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitFieldFormalParameter_type() {
-    _assertSource("A this.a",
-        AstFactory.fieldFormalParameter(null, AstFactory.typeName4("A"), "a"));
+    _assertSource(
+        "A this.a",
+        AstTestFactory.fieldFormalParameter(
+            null, AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitForEachStatement_declared() {
     _assertSource(
         "for (var a in b) {}",
-        AstFactory.forEachStatement(AstFactory.declaredIdentifier3("a"),
-            AstFactory.identifier3("b"), AstFactory.block()));
+        AstTestFactory.forEachStatement(AstTestFactory.declaredIdentifier3("a"),
+            AstTestFactory.identifier3("b"), AstTestFactory.block()));
   }
 
   void test_visitForEachStatement_variable() {
@@ -1955,11 +1993,11 @@
             null,
             TokenFactory.tokenFromKeyword(Keyword.FOR),
             TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-            AstFactory.identifier3("a"),
+            AstTestFactory.identifier3("a"),
             TokenFactory.tokenFromKeyword(Keyword.IN),
-            AstFactory.identifier3("b"),
+            AstTestFactory.identifier3("b"),
             TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitForEachStatement_variable_await() {
@@ -1969,268 +2007,288 @@
             TokenFactory.tokenFromString("await"),
             TokenFactory.tokenFromKeyword(Keyword.FOR),
             TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-            AstFactory.identifier3("a"),
+            AstTestFactory.identifier3("a"),
             TokenFactory.tokenFromKeyword(Keyword.IN),
-            AstFactory.identifier3("b"),
+            AstTestFactory.identifier3("b"),
             TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitFormalParameterList_empty() {
-    _assertSource("()", AstFactory.formalParameterList());
+    _assertSource("()", AstTestFactory.formalParameterList());
   }
 
   void test_visitFormalParameterList_n() {
     _assertSource(
         "({a : 0})",
-        AstFactory.formalParameterList([
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0))
         ]));
   }
 
   void test_visitFormalParameterList_nn() {
     _assertSource(
         "({a : 0, b : 1})",
-        AstFactory.formalParameterList([
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0)),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_p() {
     _assertSource(
         "([a = 0])",
-        AstFactory.formalParameterList([
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0))
         ]));
   }
 
   void test_visitFormalParameterList_pp() {
     _assertSource(
         "([a = 0, b = 1])",
-        AstFactory.formalParameterList([
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0)),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_r() {
     _assertSource(
         "(a)",
-        AstFactory
-            .formalParameterList([AstFactory.simpleFormalParameter3("a")]));
+        AstTestFactory
+            .formalParameterList([AstTestFactory.simpleFormalParameter3("a")]));
   }
 
   void test_visitFormalParameterList_rn() {
     _assertSource(
         "(a, {b : 1})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_rnn() {
     _assertSource(
         "(a, {b : 1, c : 2})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(2))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1)),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(2))
         ]));
   }
 
   void test_visitFormalParameterList_rp() {
     _assertSource(
         "(a, [b = 1])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_rpp() {
     _assertSource(
         "(a, [b = 1, c = 2])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(2))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1)),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(2))
         ]));
   }
 
   void test_visitFormalParameterList_rr() {
     _assertSource(
         "(a, b)",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b")
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b")
         ]));
   }
 
   void test_visitFormalParameterList_rrn() {
     _assertSource(
         "(a, b, {c : 3})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3))
         ]));
   }
 
   void test_visitFormalParameterList_rrnn() {
     _assertSource(
         "(a, b, {c : 3, d : 4})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("d"), AstFactory.integer(4))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3)),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("d"),
+              AstTestFactory.integer(4))
         ]));
   }
 
   void test_visitFormalParameterList_rrp() {
     _assertSource(
         "(a, b, [c = 3])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3))
         ]));
   }
 
   void test_visitFormalParameterList_rrpp() {
     _assertSource(
         "(a, b, [c = 3, d = 4])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("d"), AstFactory.integer(4))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3)),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("d"),
+              AstTestFactory.integer(4))
         ]));
   }
 
   void test_visitForStatement_c() {
     _assertSource(
         "for (; c;) {}",
-        AstFactory.forStatement(
-            null, AstFactory.identifier3("c"), null, AstFactory.block()));
+        AstTestFactory.forStatement(null, AstTestFactory.identifier3("c"), null,
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_cu() {
     _assertSource(
         "for (; c; u) {}",
-        AstFactory.forStatement(null, AstFactory.identifier3("c"),
-            [AstFactory.identifier3("u")], AstFactory.block()));
+        AstTestFactory.forStatement(null, AstTestFactory.identifier3("c"),
+            [AstTestFactory.identifier3("u")], AstTestFactory.block()));
   }
 
   void test_visitForStatement_e() {
     _assertSource(
         "for (e;;) {}",
-        AstFactory.forStatement(
-            AstFactory.identifier3("e"), null, null, AstFactory.block()));
+        AstTestFactory.forStatement(AstTestFactory.identifier3("e"), null, null,
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_ec() {
     _assertSource(
         "for (e; c;) {}",
-        AstFactory.forStatement(AstFactory.identifier3("e"),
-            AstFactory.identifier3("c"), null, AstFactory.block()));
+        AstTestFactory.forStatement(AstTestFactory.identifier3("e"),
+            AstTestFactory.identifier3("c"), null, AstTestFactory.block()));
   }
 
   void test_visitForStatement_ecu() {
     _assertSource(
         "for (e; c; u) {}",
-        AstFactory.forStatement(
-            AstFactory.identifier3("e"),
-            AstFactory.identifier3("c"),
-            [AstFactory.identifier3("u")],
-            AstFactory.block()));
+        AstTestFactory.forStatement(
+            AstTestFactory.identifier3("e"),
+            AstTestFactory.identifier3("c"),
+            [AstTestFactory.identifier3("u")],
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_eu() {
     _assertSource(
         "for (e;; u) {}",
-        AstFactory.forStatement(AstFactory.identifier3("e"), null,
-            [AstFactory.identifier3("u")], AstFactory.block()));
+        AstTestFactory.forStatement(AstTestFactory.identifier3("e"), null,
+            [AstTestFactory.identifier3("u")], AstTestFactory.block()));
   }
 
   void test_visitForStatement_i() {
     _assertSource(
         "for (var i;;) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
             null,
             null,
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_ic() {
     _assertSource(
         "for (var i; c;) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
-            AstFactory.identifier3("c"),
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
+            AstTestFactory.identifier3("c"),
             null,
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_icu() {
     _assertSource(
         "for (var i; c; u) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
-            AstFactory.identifier3("c"),
-            [AstFactory.identifier3("u")],
-            AstFactory.block()));
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
+            AstTestFactory.identifier3("c"),
+            [AstTestFactory.identifier3("u")],
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_iu() {
     _assertSource(
         "for (var i;; u) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
             null,
-            [AstFactory.identifier3("u")],
-            AstFactory.block()));
+            [AstTestFactory.identifier3("u")],
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_u() {
     _assertSource(
         "for (;; u) {}",
-        AstFactory.forStatement(
-            null, null, [AstFactory.identifier3("u")], AstFactory.block()));
+        AstTestFactory.forStatement(null, null,
+            [AstTestFactory.identifier3("u")], AstTestFactory.block()));
   }
 
   void test_visitFunctionDeclaration_external() {
-    FunctionDeclaration functionDeclaration = AstFactory.functionDeclaration(
-        null,
-        null,
-        "f",
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList(), AstFactory.emptyFunctionBody()));
+    FunctionDeclaration functionDeclaration =
+        AstTestFactory.functionDeclaration(
+            null,
+            null,
+            "f",
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.emptyFunctionBody()));
     functionDeclaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
     _assertSource("external f();", functionDeclaration);
@@ -2239,158 +2297,168 @@
   void test_visitFunctionDeclaration_getter() {
     _assertSource(
         "get f() {}",
-        AstFactory.functionDeclaration(
-            null, Keyword.GET, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclaration(
+            null, Keyword.GET, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionDeclaration_local_blockBody() {
-    FunctionDeclaration f = AstFactory.functionDeclaration(
-        null, null, "f", AstFactory.functionExpression());
+    FunctionDeclaration f = AstTestFactory.functionDeclaration(
+        null, null, "f", AstTestFactory.functionExpression());
     FunctionDeclarationStatement fStatement =
         new FunctionDeclarationStatement(f);
     _assertSource(
         "main() {f() {} 42;}",
-        AstFactory.functionDeclaration(
+        AstTestFactory.functionDeclaration(
             null,
             null,
             "main",
-            AstFactory.functionExpression2(
-                AstFactory.formalParameterList(),
-                AstFactory.blockFunctionBody2([
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody2([
                   fStatement,
-                  AstFactory.expressionStatement(AstFactory.integer(42))
+                  AstTestFactory.expressionStatement(AstTestFactory.integer(42))
                 ]))));
   }
 
   void test_visitFunctionDeclaration_local_expressionBody() {
-    FunctionDeclaration f = AstFactory.functionDeclaration(
+    FunctionDeclaration f = AstTestFactory.functionDeclaration(
         null,
         null,
         "f",
-        AstFactory.functionExpression2(AstFactory.formalParameterList(),
-            AstFactory.expressionFunctionBody(AstFactory.integer(1))));
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.expressionFunctionBody(AstTestFactory.integer(1))));
     FunctionDeclarationStatement fStatement =
         new FunctionDeclarationStatement(f);
     _assertSource(
         "main() {f() => 1; 2;}",
-        AstFactory.functionDeclaration(
+        AstTestFactory.functionDeclaration(
             null,
             null,
             "main",
-            AstFactory.functionExpression2(
-                AstFactory.formalParameterList(),
-                AstFactory.blockFunctionBody2([
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody2([
                   fStatement,
-                  AstFactory.expressionStatement(AstFactory.integer(2))
+                  AstTestFactory.expressionStatement(AstTestFactory.integer(2))
                 ]))));
   }
 
   void test_visitFunctionDeclaration_normal() {
     _assertSource(
         "f() {}",
-        AstFactory.functionDeclaration(
-            null, null, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclaration(
+            null, null, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionDeclaration_setter() {
     _assertSource(
         "set f() {}",
-        AstFactory.functionDeclaration(
-            null, Keyword.SET, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclaration(
+            null, Keyword.SET, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionDeclaration_typeParameters() {
     _assertSource(
         "f<E>() {}",
-        AstFactory.functionDeclaration(
+        AstTestFactory.functionDeclaration(
             null,
             null,
             "f",
-            AstFactory.functionExpression3(
-                AstFactory.typeParameterList(['E']),
-                AstFactory.formalParameterList(),
-                AstFactory.blockFunctionBody2())));
+            AstTestFactory.functionExpression3(
+                AstTestFactory.typeParameterList(['E']),
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody2())));
   }
 
   void test_visitFunctionDeclaration_withMetadata() {
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        null, null, "f", AstFactory.functionExpression());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        null, null, "f", AstTestFactory.functionExpression());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated f() {}", declaration);
   }
 
   void test_visitFunctionDeclarationStatement() {
     _assertSource(
         "f() {}",
-        AstFactory.functionDeclarationStatement(
-            null, null, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclarationStatement(
+            null, null, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionExpression() {
-    _assertSource("() {}", AstFactory.functionExpression());
+    _assertSource("() {}", AstTestFactory.functionExpression());
   }
 
   void test_visitFunctionExpression_typeParameters() {
     _assertSource(
         "<E>() {}",
-        AstFactory.functionExpression3(AstFactory.typeParameterList(['E']),
-            AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+        AstTestFactory.functionExpression3(
+            AstTestFactory.typeParameterList(['E']),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitFunctionExpressionInvocation_minimal() {
-    _assertSource("f()",
-        AstFactory.functionExpressionInvocation(AstFactory.identifier3("f")));
+    _assertSource(
+        "f()",
+        AstTestFactory
+            .functionExpressionInvocation(AstTestFactory.identifier3("f")));
   }
 
   void test_visitFunctionExpressionInvocation_typeArguments() {
     _assertSource(
         "f<A>()",
-        AstFactory.functionExpressionInvocation2(AstFactory.identifier3("f"),
-            AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+        AstTestFactory.functionExpressionInvocation2(
+            AstTestFactory.identifier3("f"),
+            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')])));
   }
 
   void test_visitFunctionTypeAlias_generic() {
     _assertSource(
         "typedef A F<B>();",
-        AstFactory.typeAlias(
-            AstFactory.typeName4("A"),
+        AstTestFactory.typeAlias(
+            AstTestFactory.typeName4("A"),
             "F",
-            AstFactory.typeParameterList(["B"]),
-            AstFactory.formalParameterList()));
+            AstTestFactory.typeParameterList(["B"]),
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitFunctionTypeAlias_nonGeneric() {
     _assertSource(
         "typedef A F();",
-        AstFactory.typeAlias(AstFactory.typeName4("A"), "F", null,
-            AstFactory.formalParameterList()));
+        AstTestFactory.typeAlias(AstTestFactory.typeName4("A"), "F", null,
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitFunctionTypeAlias_withMetadata() {
-    FunctionTypeAlias declaration = AstFactory.typeAlias(
-        AstFactory.typeName4("A"), "F", null, AstFactory.formalParameterList());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    FunctionTypeAlias declaration = AstTestFactory.typeAlias(
+        AstTestFactory.typeName4("A"),
+        "F",
+        null,
+        AstTestFactory.formalParameterList());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated typedef A F();", declaration);
   }
 
   void test_visitFunctionTypedFormalParameter_annotation() {
     FunctionTypedFormalParameter parameter =
-        AstFactory.functionTypedFormalParameter(null, "f");
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+        AstTestFactory.functionTypedFormalParameter(null, "f");
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A f()', parameter);
   }
 
   void test_visitFunctionTypedFormalParameter_noType() {
-    _assertSource("f()", AstFactory.functionTypedFormalParameter(null, "f"));
+    _assertSource(
+        "f()", AstTestFactory.functionTypedFormalParameter(null, "f"));
   }
 
   void test_visitFunctionTypedFormalParameter_type() {
     _assertSource(
         "T f()",
-        AstFactory.functionTypedFormalParameter(
-            AstFactory.typeName4("T"), "f"));
+        AstTestFactory.functionTypedFormalParameter(
+            AstTestFactory.typeName4("T"), "f"));
   }
 
   void test_visitFunctionTypedFormalParameter_typeParameters() {
@@ -2399,939 +2467,971 @@
         new FunctionTypedFormalParameter(
             null,
             null,
-            AstFactory.typeName4("T"),
-            AstFactory.identifier3('f'),
-            AstFactory.typeParameterList(['E']),
-            AstFactory.formalParameterList([])));
+            AstTestFactory.typeName4("T"),
+            AstTestFactory.identifier3('f'),
+            AstTestFactory.typeParameterList(['E']),
+            AstTestFactory.formalParameterList([])));
   }
 
   void test_visitIfStatement_withElse() {
     _assertSource(
         "if (c) {} else {}",
-        AstFactory.ifStatement2(AstFactory.identifier3("c"), AstFactory.block(),
-            AstFactory.block()));
+        AstTestFactory.ifStatement2(AstTestFactory.identifier3("c"),
+            AstTestFactory.block(), AstTestFactory.block()));
   }
 
   void test_visitIfStatement_withoutElse() {
     _assertSource(
         "if (c) {}",
-        AstFactory.ifStatement(
-            AstFactory.identifier3("c"), AstFactory.block()));
+        AstTestFactory.ifStatement(
+            AstTestFactory.identifier3("c"), AstTestFactory.block()));
   }
 
   void test_visitImplementsClause_multiple() {
     _assertSource(
         "implements A, B",
-        AstFactory.implementsClause(
-            [AstFactory.typeName4("A"), AstFactory.typeName4("B")]));
+        AstTestFactory.implementsClause(
+            [AstTestFactory.typeName4("A"), AstTestFactory.typeName4("B")]));
   }
 
   void test_visitImplementsClause_single() {
     _assertSource("implements A",
-        AstFactory.implementsClause([AstFactory.typeName4("A")]));
+        AstTestFactory.implementsClause([AstTestFactory.typeName4("A")]));
   }
 
   void test_visitImportDirective_combinator() {
     _assertSource(
         "import 'a.dart' show A;",
-        AstFactory.importDirective3("a.dart", null, [
-          AstFactory.showCombinator([AstFactory.identifier3("A")])
+        AstTestFactory.importDirective3("a.dart", null, [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
         ]));
   }
 
   void test_visitImportDirective_combinators() {
     _assertSource(
         "import 'a.dart' show A hide B;",
-        AstFactory.importDirective3("a.dart", null, [
-          AstFactory.showCombinator([AstFactory.identifier3("A")]),
-          AstFactory.hideCombinator([AstFactory.identifier3("B")])
+        AstTestFactory.importDirective3("a.dart", null, [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
+          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
         ]));
   }
 
   void test_visitImportDirective_deferred() {
     _assertSource("import 'a.dart' deferred as p;",
-        AstFactory.importDirective2("a.dart", true, "p"));
+        AstTestFactory.importDirective2("a.dart", true, "p"));
   }
 
   void test_visitImportDirective_minimal() {
     _assertSource(
-        "import 'a.dart';", AstFactory.importDirective3("a.dart", null));
+        "import 'a.dart';", AstTestFactory.importDirective3("a.dart", null));
   }
 
   void test_visitImportDirective_prefix() {
-    _assertSource(
-        "import 'a.dart' as p;", AstFactory.importDirective3("a.dart", "p"));
+    _assertSource("import 'a.dart' as p;",
+        AstTestFactory.importDirective3("a.dart", "p"));
   }
 
   void test_visitImportDirective_prefix_combinator() {
     _assertSource(
         "import 'a.dart' as p show A;",
-        AstFactory.importDirective3("a.dart", "p", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")])
+        AstTestFactory.importDirective3("a.dart", "p", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
         ]));
   }
 
   void test_visitImportDirective_prefix_combinators() {
     _assertSource(
         "import 'a.dart' as p show A hide B;",
-        AstFactory.importDirective3("a.dart", "p", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")]),
-          AstFactory.hideCombinator([AstFactory.identifier3("B")])
+        AstTestFactory.importDirective3("a.dart", "p", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
+          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
         ]));
   }
 
   void test_visitImportDirective_withMetadata() {
-    ImportDirective directive = AstFactory.importDirective3("a.dart", null);
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    ImportDirective directive = AstTestFactory.importDirective3("a.dart", null);
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated import 'a.dart';", directive);
   }
 
   void test_visitImportHideCombinator_multiple() {
     _assertSource(
         "hide a, b",
-        AstFactory.hideCombinator(
-            [AstFactory.identifier3("a"), AstFactory.identifier3("b")]));
+        AstTestFactory.hideCombinator([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b")
+        ]));
   }
 
   void test_visitImportHideCombinator_single() {
-    _assertSource(
-        "hide a", AstFactory.hideCombinator([AstFactory.identifier3("a")]));
+    _assertSource("hide a",
+        AstTestFactory.hideCombinator([AstTestFactory.identifier3("a")]));
   }
 
   void test_visitImportShowCombinator_multiple() {
     _assertSource(
         "show a, b",
-        AstFactory.showCombinator(
-            [AstFactory.identifier3("a"), AstFactory.identifier3("b")]));
+        AstTestFactory.showCombinator([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b")
+        ]));
   }
 
   void test_visitImportShowCombinator_single() {
-    _assertSource(
-        "show a", AstFactory.showCombinator([AstFactory.identifier3("a")]));
+    _assertSource("show a",
+        AstTestFactory.showCombinator([AstTestFactory.identifier3("a")]));
   }
 
   void test_visitIndexExpression() {
     _assertSource(
         "a[i]",
-        AstFactory.indexExpression(
-            AstFactory.identifier3("a"), AstFactory.identifier3("i")));
+        AstTestFactory.indexExpression(
+            AstTestFactory.identifier3("a"), AstTestFactory.identifier3("i")));
   }
 
   void test_visitInstanceCreationExpression_const() {
     _assertSource(
         "const C()",
-        AstFactory.instanceCreationExpression2(
-            Keyword.CONST, AstFactory.typeName4("C")));
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.CONST, AstTestFactory.typeName4("C")));
   }
 
   void test_visitInstanceCreationExpression_named() {
     _assertSource(
         "new C.c()",
-        AstFactory.instanceCreationExpression3(
-            Keyword.NEW, AstFactory.typeName4("C"), "c"));
+        AstTestFactory.instanceCreationExpression3(
+            Keyword.NEW, AstTestFactory.typeName4("C"), "c"));
   }
 
   void test_visitInstanceCreationExpression_unnamed() {
     _assertSource(
         "new C()",
-        AstFactory.instanceCreationExpression2(
-            Keyword.NEW, AstFactory.typeName4("C")));
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.NEW, AstTestFactory.typeName4("C")));
   }
 
   void test_visitIntegerLiteral() {
-    _assertSource("42", AstFactory.integer(42));
+    _assertSource("42", AstTestFactory.integer(42));
   }
 
   void test_visitInterpolationExpression_expression() {
-    _assertSource("\${a}",
-        AstFactory.interpolationExpression(AstFactory.identifier3("a")));
+    _assertSource(
+        "\${a}",
+        AstTestFactory
+            .interpolationExpression(AstTestFactory.identifier3("a")));
   }
 
   void test_visitInterpolationExpression_identifier() {
-    _assertSource("\$a", AstFactory.interpolationExpression2("a"));
+    _assertSource("\$a", AstTestFactory.interpolationExpression2("a"));
   }
 
   void test_visitInterpolationString() {
-    _assertSource("'x", AstFactory.interpolationString("'x", "x"));
+    _assertSource("'x", AstTestFactory.interpolationString("'x", "x"));
   }
 
   void test_visitIsExpression_negated() {
     _assertSource(
         "a is! C",
-        AstFactory.isExpression(
-            AstFactory.identifier3("a"), true, AstFactory.typeName4("C")));
+        AstTestFactory.isExpression(AstTestFactory.identifier3("a"), true,
+            AstTestFactory.typeName4("C")));
   }
 
   void test_visitIsExpression_normal() {
     _assertSource(
         "a is C",
-        AstFactory.isExpression(
-            AstFactory.identifier3("a"), false, AstFactory.typeName4("C")));
+        AstTestFactory.isExpression(AstTestFactory.identifier3("a"), false,
+            AstTestFactory.typeName4("C")));
   }
 
   void test_visitLabel() {
-    _assertSource("a:", AstFactory.label2("a"));
+    _assertSource("a:", AstTestFactory.label2("a"));
   }
 
   void test_visitLabeledStatement_multiple() {
     _assertSource(
         "a: b: return;",
-        AstFactory.labeledStatement(
-            [AstFactory.label2("a"), AstFactory.label2("b")],
-            AstFactory.returnStatement()));
+        AstTestFactory.labeledStatement(
+            [AstTestFactory.label2("a"), AstTestFactory.label2("b")],
+            AstTestFactory.returnStatement()));
   }
 
   void test_visitLabeledStatement_single() {
     _assertSource(
         "a: return;",
-        AstFactory.labeledStatement(
-            [AstFactory.label2("a")], AstFactory.returnStatement()));
+        AstTestFactory.labeledStatement(
+            [AstTestFactory.label2("a")], AstTestFactory.returnStatement()));
   }
 
   void test_visitLibraryDirective() {
-    _assertSource("library l;", AstFactory.libraryDirective2("l"));
+    _assertSource("library l;", AstTestFactory.libraryDirective2("l"));
   }
 
   void test_visitLibraryDirective_withMetadata() {
-    LibraryDirective directive = AstFactory.libraryDirective2("l");
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    LibraryDirective directive = AstTestFactory.libraryDirective2("l");
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated library l;", directive);
   }
 
   void test_visitLibraryIdentifier_multiple() {
     _assertSource(
         "a.b.c",
-        AstFactory.libraryIdentifier([
-          AstFactory.identifier3("a"),
-          AstFactory.identifier3("b"),
-          AstFactory.identifier3("c")
+        AstTestFactory.libraryIdentifier([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b"),
+          AstTestFactory.identifier3("c")
         ]));
   }
 
   void test_visitLibraryIdentifier_single() {
-    _assertSource(
-        "a", AstFactory.libraryIdentifier([AstFactory.identifier3("a")]));
+    _assertSource("a",
+        AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("a")]));
   }
 
   void test_visitListLiteral_const() {
-    _assertSource("const []", AstFactory.listLiteral2(Keyword.CONST, null));
+    _assertSource("const []", AstTestFactory.listLiteral2(Keyword.CONST, null));
   }
 
   void test_visitListLiteral_empty() {
-    _assertSource("[]", AstFactory.listLiteral());
+    _assertSource("[]", AstTestFactory.listLiteral());
   }
 
   void test_visitListLiteral_nonEmpty() {
     _assertSource(
         "[a, b, c]",
-        AstFactory.listLiteral([
-          AstFactory.identifier3("a"),
-          AstFactory.identifier3("b"),
-          AstFactory.identifier3("c")
+        AstTestFactory.listLiteral([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b"),
+          AstTestFactory.identifier3("c")
         ]));
   }
 
   void test_visitMapLiteral_const() {
-    _assertSource("const {}", AstFactory.mapLiteral(Keyword.CONST, null));
+    _assertSource("const {}", AstTestFactory.mapLiteral(Keyword.CONST, null));
   }
 
   void test_visitMapLiteral_empty() {
-    _assertSource("{}", AstFactory.mapLiteral2());
+    _assertSource("{}", AstTestFactory.mapLiteral2());
   }
 
   void test_visitMapLiteral_nonEmpty() {
     _assertSource(
         "{'a' : a, 'b' : b, 'c' : c}",
-        AstFactory.mapLiteral2([
-          AstFactory.mapLiteralEntry("a", AstFactory.identifier3("a")),
-          AstFactory.mapLiteralEntry("b", AstFactory.identifier3("b")),
-          AstFactory.mapLiteralEntry("c", AstFactory.identifier3("c"))
+        AstTestFactory.mapLiteral2([
+          AstTestFactory.mapLiteralEntry("a", AstTestFactory.identifier3("a")),
+          AstTestFactory.mapLiteralEntry("b", AstTestFactory.identifier3("b")),
+          AstTestFactory.mapLiteralEntry("c", AstTestFactory.identifier3("c"))
         ]));
   }
 
   void test_visitMapLiteralEntry() {
     _assertSource("'a' : b",
-        AstFactory.mapLiteralEntry("a", AstFactory.identifier3("b")));
+        AstTestFactory.mapLiteralEntry("a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitMethodDeclaration_external() {
     _assertSource(
         "external m();",
-        AstFactory.methodDeclaration(null, null, null, null,
-            AstFactory.identifier3("m"), AstFactory.formalParameterList()));
+        AstTestFactory.methodDeclaration(
+            null,
+            null,
+            null,
+            null,
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitMethodDeclaration_external_returnType() {
     _assertSource(
         "external T m();",
-        AstFactory.methodDeclaration(
+        AstTestFactory.methodDeclaration(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitMethodDeclaration_getter() {
     _assertSource(
         "get m {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             Keyword.GET,
             null,
-            AstFactory.identifier3("m"),
+            AstTestFactory.identifier3("m"),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_getter_returnType() {
     _assertSource(
         "T get m {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             Keyword.GET,
             null,
-            AstFactory.identifier3("m"),
+            AstTestFactory.identifier3("m"),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_getter_seturnType() {
     _assertSource(
         "T set m(var v) {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             Keyword.SET,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter(Keyword.VAR, "v")]),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter(Keyword.VAR, "v")]),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_minimal() {
     _assertSource(
         "m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_multipleParameters() {
     _assertSource(
         "m(var a, var b) {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList([
-              AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-              AstFactory.simpleFormalParameter(Keyword.VAR, "b")
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList([
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "b")
             ]),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_operator() {
     _assertSource(
         "operator +() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             null,
             Keyword.OPERATOR,
-            AstFactory.identifier3("+"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("+"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_operator_returnType() {
     _assertSource(
         "T operator +() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             Keyword.OPERATOR,
-            AstFactory.identifier3("+"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("+"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_returnType() {
     _assertSource(
         "T m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_setter() {
     _assertSource(
         "set m(var v) {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             Keyword.SET,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter(Keyword.VAR, "v")]),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter(Keyword.VAR, "v")]),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_static() {
     _assertSource(
         "static m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             Keyword.STATIC,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_static_returnType() {
     _assertSource(
         "static T m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             Keyword.STATIC,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_typeParameters() {
     _assertSource(
         "m<E>() {}",
-        AstFactory.methodDeclaration3(
+        AstTestFactory.methodDeclaration3(
             null,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.typeParameterList(['E']),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.typeParameterList(['E']),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_withMetadata() {
-    MethodDeclaration declaration = AstFactory.methodDeclaration2(
+    MethodDeclaration declaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated m() {}", declaration);
   }
 
   void test_visitMethodInvocation_conditional() {
     _assertSource(
         "t?.m()",
-        AstFactory.methodInvocation(
-            AstFactory.identifier3("t"), "m", null, TokenType.QUESTION_PERIOD));
+        AstTestFactory.methodInvocation(AstTestFactory.identifier3("t"), "m",
+            null, TokenType.QUESTION_PERIOD));
   }
 
   void test_visitMethodInvocation_noTarget() {
-    _assertSource("m()", AstFactory.methodInvocation2("m"));
+    _assertSource("m()", AstTestFactory.methodInvocation2("m"));
   }
 
   void test_visitMethodInvocation_target() {
-    _assertSource(
-        "t.m()", AstFactory.methodInvocation(AstFactory.identifier3("t"), "m"));
+    _assertSource("t.m()",
+        AstTestFactory.methodInvocation(AstTestFactory.identifier3("t"), "m"));
   }
 
   void test_visitMethodInvocation_typeArguments() {
     _assertSource(
         "m<A>()",
-        AstFactory.methodInvocation3(null, "m",
-            AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+        AstTestFactory.methodInvocation3(null, "m",
+            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')])));
   }
 
   void test_visitNamedExpression() {
-    _assertSource(
-        "a: b", AstFactory.namedExpression2("a", AstFactory.identifier3("b")));
+    _assertSource("a: b",
+        AstTestFactory.namedExpression2("a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitNamedFormalParameter() {
     _assertSource(
         "var a : 0",
-        AstFactory.namedFormalParameter(
-            AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-            AstFactory.integer(0)));
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitNativeClause() {
-    _assertSource("native 'code'", AstFactory.nativeClause("code"));
+    _assertSource("native 'code'", AstTestFactory.nativeClause("code"));
   }
 
   void test_visitNativeFunctionBody() {
-    _assertSource("native 'str';", AstFactory.nativeFunctionBody("str"));
+    _assertSource("native 'str';", AstTestFactory.nativeFunctionBody("str"));
   }
 
   void test_visitNullLiteral() {
-    _assertSource("null", AstFactory.nullLiteral());
+    _assertSource("null", AstTestFactory.nullLiteral());
   }
 
   void test_visitParenthesizedExpression() {
     _assertSource(
-        "(a)", AstFactory.parenthesizedExpression(AstFactory.identifier3("a")));
+        "(a)",
+        AstTestFactory
+            .parenthesizedExpression(AstTestFactory.identifier3("a")));
   }
 
   void test_visitPartDirective() {
-    _assertSource("part 'a.dart';", AstFactory.partDirective2("a.dart"));
+    _assertSource("part 'a.dart';", AstTestFactory.partDirective2("a.dart"));
   }
 
   void test_visitPartDirective_withMetadata() {
-    PartDirective directive = AstFactory.partDirective2("a.dart");
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    PartDirective directive = AstTestFactory.partDirective2("a.dart");
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated part 'a.dart';", directive);
   }
 
   void test_visitPartOfDirective() {
-    _assertSource("part of l;",
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["l"])));
+    _assertSource(
+        "part of l;",
+        AstTestFactory
+            .partOfDirective(AstTestFactory.libraryIdentifier2(["l"])));
   }
 
   void test_visitPartOfDirective_withMetadata() {
-    PartOfDirective directive =
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["l"]));
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    PartOfDirective directive = AstTestFactory
+        .partOfDirective(AstTestFactory.libraryIdentifier2(["l"]));
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated part of l;", directive);
   }
 
   void test_visitPositionalFormalParameter() {
     _assertSource(
         "var a = 0",
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-            AstFactory.integer(0)));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitPostfixExpression() {
     _assertSource(
         "a++",
-        AstFactory.postfixExpression(
-            AstFactory.identifier3("a"), TokenType.PLUS_PLUS));
+        AstTestFactory.postfixExpression(
+            AstTestFactory.identifier3("a"), TokenType.PLUS_PLUS));
   }
 
   void test_visitPrefixedIdentifier() {
-    _assertSource("a.b", AstFactory.identifier5("a", "b"));
+    _assertSource("a.b", AstTestFactory.identifier5("a", "b"));
   }
 
   void test_visitPrefixExpression() {
     _assertSource(
         "-a",
-        AstFactory.prefixExpression(
-            TokenType.MINUS, AstFactory.identifier3("a")));
+        AstTestFactory.prefixExpression(
+            TokenType.MINUS, AstTestFactory.identifier3("a")));
   }
 
   void test_visitPropertyAccess() {
-    _assertSource(
-        "a.b", AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"));
+    _assertSource("a.b",
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("a"), "b"));
   }
 
   void test_visitPropertyAccess_conditional() {
     _assertSource(
         "a?.b",
-        AstFactory.propertyAccess2(
-            AstFactory.identifier3("a"), "b", TokenType.QUESTION_PERIOD));
+        AstTestFactory.propertyAccess2(
+            AstTestFactory.identifier3("a"), "b", TokenType.QUESTION_PERIOD));
   }
 
   void test_visitRedirectingConstructorInvocation_named() {
     _assertSource(
-        "this.c()", AstFactory.redirectingConstructorInvocation2("c"));
+        "this.c()", AstTestFactory.redirectingConstructorInvocation2("c"));
   }
 
   void test_visitRedirectingConstructorInvocation_unnamed() {
-    _assertSource("this()", AstFactory.redirectingConstructorInvocation());
+    _assertSource("this()", AstTestFactory.redirectingConstructorInvocation());
   }
 
   void test_visitRethrowExpression() {
-    _assertSource("rethrow", AstFactory.rethrowExpression());
+    _assertSource("rethrow", AstTestFactory.rethrowExpression());
   }
 
   void test_visitReturnStatement_expression() {
-    _assertSource(
-        "return a;", AstFactory.returnStatement2(AstFactory.identifier3("a")));
+    _assertSource("return a;",
+        AstTestFactory.returnStatement2(AstTestFactory.identifier3("a")));
   }
 
   void test_visitReturnStatement_noExpression() {
-    _assertSource("return;", AstFactory.returnStatement());
+    _assertSource("return;", AstTestFactory.returnStatement());
   }
 
   void test_visitScriptTag() {
     String scriptTag = "!#/bin/dart.exe";
-    _assertSource(scriptTag, AstFactory.scriptTag(scriptTag));
+    _assertSource(scriptTag, AstTestFactory.scriptTag(scriptTag));
   }
 
   void test_visitSimpleFormalParameter_annotation() {
-    SimpleFormalParameter parameter = AstFactory.simpleFormalParameter3('x');
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    SimpleFormalParameter parameter =
+        AstTestFactory.simpleFormalParameter3('x');
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A x', parameter);
   }
 
   void test_visitSimpleFormalParameter_keyword() {
-    _assertSource("var a", AstFactory.simpleFormalParameter(Keyword.VAR, "a"));
+    _assertSource(
+        "var a", AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"));
   }
 
   void test_visitSimpleFormalParameter_keyword_type() {
     _assertSource(
         "final A a",
-        AstFactory.simpleFormalParameter2(
-            Keyword.FINAL, AstFactory.typeName4("A"), "a"));
+        AstTestFactory.simpleFormalParameter2(
+            Keyword.FINAL, AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitSimpleFormalParameter_type() {
-    _assertSource("A a",
-        AstFactory.simpleFormalParameter4(AstFactory.typeName4("A"), "a"));
+    _assertSource(
+        "A a",
+        AstTestFactory.simpleFormalParameter4(
+            AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitSimpleIdentifier() {
-    _assertSource("a", AstFactory.identifier3("a"));
+    _assertSource("a", AstTestFactory.identifier3("a"));
   }
 
   void test_visitSimpleStringLiteral() {
-    _assertSource("'a'", AstFactory.string2("a"));
+    _assertSource("'a'", AstTestFactory.string2("a"));
   }
 
   void test_visitStringInterpolation() {
     _assertSource(
         "'a\${e}b'",
-        AstFactory.string([
-          AstFactory.interpolationString("'a", "a"),
-          AstFactory.interpolationExpression(AstFactory.identifier3("e")),
-          AstFactory.interpolationString("b'", "b")
+        AstTestFactory.string([
+          AstTestFactory.interpolationString("'a", "a"),
+          AstTestFactory
+              .interpolationExpression(AstTestFactory.identifier3("e")),
+          AstTestFactory.interpolationString("b'", "b")
         ]));
   }
 
   void test_visitSuperConstructorInvocation() {
-    _assertSource("super()", AstFactory.superConstructorInvocation());
+    _assertSource("super()", AstTestFactory.superConstructorInvocation());
   }
 
   void test_visitSuperConstructorInvocation_named() {
-    _assertSource("super.c()", AstFactory.superConstructorInvocation2("c"));
+    _assertSource("super.c()", AstTestFactory.superConstructorInvocation2("c"));
   }
 
   void test_visitSuperExpression() {
-    _assertSource("super", AstFactory.superExpression());
+    _assertSource("super", AstTestFactory.superExpression());
   }
 
   void test_visitSwitchCase_multipleLabels() {
     _assertSource(
         "l1: l2: case a: {}",
-        AstFactory.switchCase2(
-            [AstFactory.label2("l1"), AstFactory.label2("l2")],
-            AstFactory.identifier3("a"),
-            [AstFactory.block()]));
+        AstTestFactory.switchCase2(
+            [AstTestFactory.label2("l1"), AstTestFactory.label2("l2")],
+            AstTestFactory.identifier3("a"),
+            [AstTestFactory.block()]));
   }
 
   void test_visitSwitchCase_multipleStatements() {
     _assertSource(
         "case a: {} {}",
-        AstFactory.switchCase(AstFactory.identifier3("a"),
-            [AstFactory.block(), AstFactory.block()]));
+        AstTestFactory.switchCase(AstTestFactory.identifier3("a"),
+            [AstTestFactory.block(), AstTestFactory.block()]));
   }
 
   void test_visitSwitchCase_noLabels() {
     _assertSource(
         "case a: {}",
-        AstFactory
-            .switchCase(AstFactory.identifier3("a"), [AstFactory.block()]));
+        AstTestFactory.switchCase(
+            AstTestFactory.identifier3("a"), [AstTestFactory.block()]));
   }
 
   void test_visitSwitchCase_singleLabel() {
     _assertSource(
         "l1: case a: {}",
-        AstFactory.switchCase2([AstFactory.label2("l1")],
-            AstFactory.identifier3("a"), [AstFactory.block()]));
+        AstTestFactory.switchCase2([AstTestFactory.label2("l1")],
+            AstTestFactory.identifier3("a"), [AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_multipleLabels() {
     _assertSource(
         "l1: l2: default: {}",
-        AstFactory.switchDefault(
-            [AstFactory.label2("l1"), AstFactory.label2("l2")],
-            [AstFactory.block()]));
+        AstTestFactory.switchDefault(
+            [AstTestFactory.label2("l1"), AstTestFactory.label2("l2")],
+            [AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_multipleStatements() {
-    _assertSource("default: {} {}",
-        AstFactory.switchDefault2([AstFactory.block(), AstFactory.block()]));
+    _assertSource(
+        "default: {} {}",
+        AstTestFactory
+            .switchDefault2([AstTestFactory.block(), AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_noLabels() {
     _assertSource(
-        "default: {}", AstFactory.switchDefault2([AstFactory.block()]));
+        "default: {}", AstTestFactory.switchDefault2([AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_singleLabel() {
     _assertSource(
         "l1: default: {}",
-        AstFactory
-            .switchDefault([AstFactory.label2("l1")], [AstFactory.block()]));
+        AstTestFactory.switchDefault(
+            [AstTestFactory.label2("l1")], [AstTestFactory.block()]));
   }
 
   void test_visitSwitchStatement() {
     _assertSource(
         "switch (a) {case 'b': {} default: {}}",
-        AstFactory.switchStatement(AstFactory.identifier3("a"), [
-          AstFactory.switchCase(AstFactory.string2("b"), [AstFactory.block()]),
-          AstFactory.switchDefault2([AstFactory.block()])
+        AstTestFactory.switchStatement(AstTestFactory.identifier3("a"), [
+          AstTestFactory.switchCase(
+              AstTestFactory.string2("b"), [AstTestFactory.block()]),
+          AstTestFactory.switchDefault2([AstTestFactory.block()])
         ]));
   }
 
   void test_visitSymbolLiteral_multiple() {
-    _assertSource("#a.b.c", AstFactory.symbolLiteral(["a", "b", "c"]));
+    _assertSource("#a.b.c", AstTestFactory.symbolLiteral(["a", "b", "c"]));
   }
 
   void test_visitSymbolLiteral_single() {
-    _assertSource("#a", AstFactory.symbolLiteral(["a"]));
+    _assertSource("#a", AstTestFactory.symbolLiteral(["a"]));
   }
 
   void test_visitThisExpression() {
-    _assertSource("this", AstFactory.thisExpression());
+    _assertSource("this", AstTestFactory.thisExpression());
   }
 
   void test_visitThrowStatement() {
-    _assertSource(
-        "throw e", AstFactory.throwExpression2(AstFactory.identifier3("e")));
+    _assertSource("throw e",
+        AstTestFactory.throwExpression2(AstTestFactory.identifier3("e")));
   }
 
   void test_visitTopLevelVariableDeclaration_multiple() {
     _assertSource(
         "var a;",
-        AstFactory.topLevelVariableDeclaration2(
-            Keyword.VAR, [AstFactory.variableDeclaration("a")]));
+        AstTestFactory.topLevelVariableDeclaration2(
+            Keyword.VAR, [AstTestFactory.variableDeclaration("a")]));
   }
 
   void test_visitTopLevelVariableDeclaration_single() {
     _assertSource(
         "var a, b;",
-        AstFactory.topLevelVariableDeclaration2(Keyword.VAR, [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.topLevelVariableDeclaration2(Keyword.VAR, [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitTryStatement_catch() {
     _assertSource(
         "try {} on E {}",
-        AstFactory.tryStatement2(AstFactory.block(),
-            [AstFactory.catchClause3(AstFactory.typeName4("E"))]));
+        AstTestFactory.tryStatement2(AstTestFactory.block(),
+            [AstTestFactory.catchClause3(AstTestFactory.typeName4("E"))]));
   }
 
   void test_visitTryStatement_catches() {
     _assertSource(
         "try {} on E {} on F {}",
-        AstFactory.tryStatement2(AstFactory.block(), [
-          AstFactory.catchClause3(AstFactory.typeName4("E")),
-          AstFactory.catchClause3(AstFactory.typeName4("F"))
+        AstTestFactory.tryStatement2(AstTestFactory.block(), [
+          AstTestFactory.catchClause3(AstTestFactory.typeName4("E")),
+          AstTestFactory.catchClause3(AstTestFactory.typeName4("F"))
         ]));
   }
 
   void test_visitTryStatement_catchFinally() {
     _assertSource(
         "try {} on E {} finally {}",
-        AstFactory.tryStatement3(
-            AstFactory.block(),
-            [AstFactory.catchClause3(AstFactory.typeName4("E"))],
-            AstFactory.block()));
+        AstTestFactory.tryStatement3(
+            AstTestFactory.block(),
+            [AstTestFactory.catchClause3(AstTestFactory.typeName4("E"))],
+            AstTestFactory.block()));
   }
 
   void test_visitTryStatement_finally() {
-    _assertSource("try {} finally {}",
-        AstFactory.tryStatement(AstFactory.block(), AstFactory.block()));
+    _assertSource(
+        "try {} finally {}",
+        AstTestFactory.tryStatement(
+            AstTestFactory.block(), AstTestFactory.block()));
   }
 
   void test_visitTypeArgumentList_multiple() {
     _assertSource(
         "<E, F>",
-        AstFactory.typeArgumentList(
-            [AstFactory.typeName4("E"), AstFactory.typeName4("F")]));
+        AstTestFactory.typeArgumentList(
+            [AstTestFactory.typeName4("E"), AstTestFactory.typeName4("F")]));
   }
 
   void test_visitTypeArgumentList_single() {
-    _assertSource(
-        "<E>", AstFactory.typeArgumentList([AstFactory.typeName4("E")]));
+    _assertSource("<E>",
+        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("E")]));
   }
 
   void test_visitTypeName_multipleArgs() {
     _assertSource(
         "C<D, E>",
-        AstFactory.typeName4(
-            "C", [AstFactory.typeName4("D"), AstFactory.typeName4("E")]));
+        AstTestFactory.typeName4("C",
+            [AstTestFactory.typeName4("D"), AstTestFactory.typeName4("E")]));
   }
 
   void test_visitTypeName_nestedArg() {
     _assertSource(
         "C<D<E>>",
-        AstFactory.typeName4("C", [
-          AstFactory.typeName4("D", [AstFactory.typeName4("E")])
+        AstTestFactory.typeName4("C", [
+          AstTestFactory.typeName4("D", [AstTestFactory.typeName4("E")])
         ]));
   }
 
   void test_visitTypeName_noArgs() {
-    _assertSource("C", AstFactory.typeName4("C"));
+    _assertSource("C", AstTestFactory.typeName4("C"));
   }
 
   void test_visitTypeName_singleArg() {
     _assertSource(
-        "C<D>", AstFactory.typeName4("C", [AstFactory.typeName4("D")]));
+        "C<D>", AstTestFactory.typeName4("C", [AstTestFactory.typeName4("D")]));
   }
 
   void test_visitTypeParameter_withExtends() {
     _assertSource("E extends C",
-        AstFactory.typeParameter2("E", AstFactory.typeName4("C")));
+        AstTestFactory.typeParameter2("E", AstTestFactory.typeName4("C")));
   }
 
   void test_visitTypeParameter_withMetadata() {
-    TypeParameter parameter = AstFactory.typeParameter("E");
-    parameter.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    TypeParameter parameter = AstTestFactory.typeParameter("E");
+    parameter.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated E", parameter);
   }
 
   void test_visitTypeParameter_withoutExtends() {
-    _assertSource("E", AstFactory.typeParameter("E"));
+    _assertSource("E", AstTestFactory.typeParameter("E"));
   }
 
   void test_visitTypeParameterList_multiple() {
-    _assertSource("<E, F>", AstFactory.typeParameterList(["E", "F"]));
+    _assertSource("<E, F>", AstTestFactory.typeParameterList(["E", "F"]));
   }
 
   void test_visitTypeParameterList_single() {
-    _assertSource("<E>", AstFactory.typeParameterList(["E"]));
+    _assertSource("<E>", AstTestFactory.typeParameterList(["E"]));
   }
 
   void test_visitVariableDeclaration_initialized() {
-    _assertSource("a = b",
-        AstFactory.variableDeclaration2("a", AstFactory.identifier3("b")));
+    _assertSource(
+        "a = b",
+        AstTestFactory.variableDeclaration2(
+            "a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitVariableDeclaration_uninitialized() {
-    _assertSource("a", AstFactory.variableDeclaration("a"));
+    _assertSource("a", AstTestFactory.variableDeclaration("a"));
   }
 
   void test_visitVariableDeclaration_withMetadata() {
-    VariableDeclaration declaration = AstFactory.variableDeclaration("a");
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    VariableDeclaration declaration = AstTestFactory.variableDeclaration("a");
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated a", declaration);
   }
 
   void test_visitVariableDeclarationList_const_type() {
     _assertSource(
         "const C a, b",
-        AstFactory.variableDeclarationList(
-            Keyword.CONST, AstFactory.typeName4("C"), [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList(
+            Keyword.CONST, AstTestFactory.typeName4("C"), [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationList_final_noType() {
     _assertSource(
         "final a, b",
-        AstFactory.variableDeclarationList2(Keyword.FINAL, [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList2(Keyword.FINAL, [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationList_final_withMetadata() {
-    VariableDeclarationList declarationList = AstFactory
+    VariableDeclarationList declarationList = AstTestFactory
         .variableDeclarationList2(Keyword.FINAL, [
-      AstFactory.variableDeclaration("a"),
-      AstFactory.variableDeclaration("b")
+      AstTestFactory.variableDeclaration("a"),
+      AstTestFactory.variableDeclaration("b")
     ]);
-    declarationList.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    declarationList.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated final a, b", declarationList);
   }
 
   void test_visitVariableDeclarationList_type() {
     _assertSource(
         "C a, b",
-        AstFactory.variableDeclarationList(null, AstFactory.typeName4("C"), [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList(
+            null, AstTestFactory.typeName4("C"), [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationList_var() {
     _assertSource(
         "var a, b",
-        AstFactory.variableDeclarationList2(Keyword.VAR, [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList2(Keyword.VAR, [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationStatement() {
     _assertSource(
         "C c;",
-        AstFactory.variableDeclarationStatement(null, AstFactory.typeName4("C"),
-            [AstFactory.variableDeclaration("c")]));
+        AstTestFactory.variableDeclarationStatement(
+            null,
+            AstTestFactory.typeName4("C"),
+            [AstTestFactory.variableDeclaration("c")]));
   }
 
   void test_visitWhileStatement() {
     _assertSource(
         "while (c) {}",
-        AstFactory.whileStatement(
-            AstFactory.identifier3("c"), AstFactory.block()));
+        AstTestFactory.whileStatement(
+            AstTestFactory.identifier3("c"), AstTestFactory.block()));
   }
 
   void test_visitWithClause_multiple() {
     _assertSource(
         "with A, B, C",
-        AstFactory.withClause([
-          AstFactory.typeName4("A"),
-          AstFactory.typeName4("B"),
-          AstFactory.typeName4("C")
+        AstTestFactory.withClause([
+          AstTestFactory.typeName4("A"),
+          AstTestFactory.typeName4("B"),
+          AstTestFactory.typeName4("C")
         ]));
   }
 
   void test_visitWithClause_single() {
-    _assertSource("with A", AstFactory.withClause([AstFactory.typeName4("A")]));
+    _assertSource(
+        "with A", AstTestFactory.withClause([AstTestFactory.typeName4("A")]));
   }
 
   void test_visitYieldStatement() {
-    _assertSource(
-        "yield e;", AstFactory.yieldStatement(AstFactory.identifier3("e")));
+    _assertSource("yield e;",
+        AstTestFactory.yieldStatement(AstTestFactory.identifier3("e")));
   }
 
   void test_visitYieldStatement_each() {
     _assertSource("yield* e;",
-        AstFactory.yieldEachStatement(AstFactory.identifier3("e")));
+        AstTestFactory.yieldEachStatement(AstTestFactory.identifier3("e")));
   }
 
   /**
@@ -3351,246 +3451,257 @@
   void test_visitAdjacentStrings() {
     _assertSource(
         "'a' 'b'",
-        AstFactory.adjacentStrings(
-            [AstFactory.string2("a"), AstFactory.string2("b")]));
+        AstTestFactory.adjacentStrings(
+            [AstTestFactory.string2("a"), AstTestFactory.string2("b")]));
   }
 
   void test_visitAnnotation_constant() {
-    _assertSource("@A", AstFactory.annotation(AstFactory.identifier3("A")));
+    _assertSource(
+        "@A", AstTestFactory.annotation(AstTestFactory.identifier3("A")));
   }
 
   void test_visitAnnotation_constructor() {
     _assertSource(
         "@A.c()",
-        AstFactory.annotation2(AstFactory.identifier3("A"),
-            AstFactory.identifier3("c"), AstFactory.argumentList()));
+        AstTestFactory.annotation2(AstTestFactory.identifier3("A"),
+            AstTestFactory.identifier3("c"), AstTestFactory.argumentList()));
   }
 
   void test_visitArgumentList() {
     _assertSource(
         "(a, b)",
-        AstFactory.argumentList(
-            [AstFactory.identifier3("a"), AstFactory.identifier3("b")]));
+        AstTestFactory.argumentList([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b")
+        ]));
   }
 
   void test_visitAsExpression() {
     _assertSource(
         "e as T",
-        AstFactory.asExpression(
-            AstFactory.identifier3("e"), AstFactory.typeName4("T")));
+        AstTestFactory.asExpression(
+            AstTestFactory.identifier3("e"), AstTestFactory.typeName4("T")));
   }
 
   void test_visitAssertStatement() {
-    _assertSource(
-        "assert (a);", AstFactory.assertStatement(AstFactory.identifier3("a")));
+    _assertSource("assert (a);",
+        AstTestFactory.assertStatement(AstTestFactory.identifier3("a")));
   }
 
   void test_visitAssertStatement_withMessage() {
     _assertSource(
         "assert (a, b);",
-        AstFactory.assertStatement(
-            AstFactory.identifier3("a"), AstFactory.identifier3('b')));
+        AstTestFactory.assertStatement(
+            AstTestFactory.identifier3("a"), AstTestFactory.identifier3('b')));
   }
 
   void test_visitAssignmentExpression() {
     _assertSource(
         "a = b",
-        AstFactory.assignmentExpression(AstFactory.identifier3("a"),
-            TokenType.EQ, AstFactory.identifier3("b")));
+        AstTestFactory.assignmentExpression(AstTestFactory.identifier3("a"),
+            TokenType.EQ, AstTestFactory.identifier3("b")));
   }
 
   void test_visitAwaitExpression() {
-    _assertSource(
-        "await e", AstFactory.awaitExpression(AstFactory.identifier3("e")));
+    _assertSource("await e",
+        AstTestFactory.awaitExpression(AstTestFactory.identifier3("e")));
   }
 
   void test_visitBinaryExpression() {
     _assertSource(
         "a + b",
-        AstFactory.binaryExpression(AstFactory.identifier3("a"), TokenType.PLUS,
-            AstFactory.identifier3("b")));
+        AstTestFactory.binaryExpression(AstTestFactory.identifier3("a"),
+            TokenType.PLUS, AstTestFactory.identifier3("b")));
   }
 
   void test_visitBlock_empty() {
-    _assertSource("{}", AstFactory.block());
+    _assertSource("{}", AstTestFactory.block());
   }
 
   void test_visitBlock_nonEmpty() {
     _assertSource(
         "{break; break;}",
-        AstFactory
-            .block([AstFactory.breakStatement(), AstFactory.breakStatement()]));
+        AstTestFactory.block([
+          AstTestFactory.breakStatement(),
+          AstTestFactory.breakStatement()
+        ]));
   }
 
   void test_visitBlockFunctionBody_async() {
-    _assertSource("async {}", AstFactory.asyncBlockFunctionBody());
+    _assertSource("async {}", AstTestFactory.asyncBlockFunctionBody());
   }
 
   void test_visitBlockFunctionBody_async_star() {
-    _assertSource("async* {}", AstFactory.asyncGeneratorBlockFunctionBody());
+    _assertSource(
+        "async* {}", AstTestFactory.asyncGeneratorBlockFunctionBody());
   }
 
   void test_visitBlockFunctionBody_simple() {
-    _assertSource("{}", AstFactory.blockFunctionBody2());
+    _assertSource("{}", AstTestFactory.blockFunctionBody2());
   }
 
   void test_visitBlockFunctionBody_sync() {
-    _assertSource("sync {}", AstFactory.syncBlockFunctionBody());
+    _assertSource("sync {}", AstTestFactory.syncBlockFunctionBody());
   }
 
   void test_visitBlockFunctionBody_sync_star() {
-    _assertSource("sync* {}", AstFactory.syncGeneratorBlockFunctionBody());
+    _assertSource("sync* {}", AstTestFactory.syncGeneratorBlockFunctionBody());
   }
 
   void test_visitBooleanLiteral_false() {
-    _assertSource("false", AstFactory.booleanLiteral(false));
+    _assertSource("false", AstTestFactory.booleanLiteral(false));
   }
 
   void test_visitBooleanLiteral_true() {
-    _assertSource("true", AstFactory.booleanLiteral(true));
+    _assertSource("true", AstTestFactory.booleanLiteral(true));
   }
 
   void test_visitBreakStatement_label() {
-    _assertSource("break l;", AstFactory.breakStatement2("l"));
+    _assertSource("break l;", AstTestFactory.breakStatement2("l"));
   }
 
   void test_visitBreakStatement_noLabel() {
-    _assertSource("break;", AstFactory.breakStatement());
+    _assertSource("break;", AstTestFactory.breakStatement());
   }
 
   void test_visitCascadeExpression_field() {
     _assertSource(
         "a..b..c",
-        AstFactory.cascadeExpression(AstFactory.identifier3("a"), [
-          AstFactory.cascadedPropertyAccess("b"),
-          AstFactory.cascadedPropertyAccess("c")
+        AstTestFactory.cascadeExpression(AstTestFactory.identifier3("a"), [
+          AstTestFactory.cascadedPropertyAccess("b"),
+          AstTestFactory.cascadedPropertyAccess("c")
         ]));
   }
 
   void test_visitCascadeExpression_index() {
     _assertSource(
         "a..[0]..[1]",
-        AstFactory.cascadeExpression(AstFactory.identifier3("a"), [
-          AstFactory.cascadedIndexExpression(AstFactory.integer(0)),
-          AstFactory.cascadedIndexExpression(AstFactory.integer(1))
+        AstTestFactory.cascadeExpression(AstTestFactory.identifier3("a"), [
+          AstTestFactory.cascadedIndexExpression(AstTestFactory.integer(0)),
+          AstTestFactory.cascadedIndexExpression(AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitCascadeExpression_method() {
     _assertSource(
         "a..b()..c()",
-        AstFactory.cascadeExpression(AstFactory.identifier3("a"), [
-          AstFactory.cascadedMethodInvocation("b"),
-          AstFactory.cascadedMethodInvocation("c")
+        AstTestFactory.cascadeExpression(AstTestFactory.identifier3("a"), [
+          AstTestFactory.cascadedMethodInvocation("b"),
+          AstTestFactory.cascadedMethodInvocation("c")
         ]));
   }
 
   void test_visitCatchClause_catch_noStack() {
-    _assertSource("catch (e) {}", AstFactory.catchClause("e"));
+    _assertSource("catch (e) {}", AstTestFactory.catchClause("e"));
   }
 
   void test_visitCatchClause_catch_stack() {
-    _assertSource("catch (e, s) {}", AstFactory.catchClause2("e", "s"));
+    _assertSource("catch (e, s) {}", AstTestFactory.catchClause2("e", "s"));
   }
 
   void test_visitCatchClause_on() {
     _assertSource(
-        "on E {}", AstFactory.catchClause3(AstFactory.typeName4("E")));
+        "on E {}", AstTestFactory.catchClause3(AstTestFactory.typeName4("E")));
   }
 
   void test_visitCatchClause_on_catch() {
     _assertSource("on E catch (e) {}",
-        AstFactory.catchClause4(AstFactory.typeName4("E"), "e"));
+        AstTestFactory.catchClause4(AstTestFactory.typeName4("E"), "e"));
   }
 
   void test_visitClassDeclaration_abstract() {
     _assertSource(
         "abstract class C {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             Keyword.ABSTRACT, "C", null, null, null, null));
   }
 
   void test_visitClassDeclaration_empty() {
     _assertSource("class C {}",
-        AstFactory.classDeclaration(null, "C", null, null, null, null));
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null));
   }
 
   void test_visitClassDeclaration_extends() {
     _assertSource(
         "class C extends A {}",
-        AstFactory.classDeclaration(null, "C", null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")), null, null));
+        AstTestFactory.classDeclaration(
+            null,
+            "C",
+            null,
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            null,
+            null));
   }
 
   void test_visitClassDeclaration_extends_implements() {
     _assertSource(
         "class C extends A implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
             null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
             null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_extends_with() {
     _assertSource(
         "class C extends A with M {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
             null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
             null));
   }
 
   void test_visitClassDeclaration_extends_with_implements() {
     _assertSource(
         "class C extends A with M implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
             null,
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_implements() {
     _assertSource(
         "class C implements B {}",
-        AstFactory.classDeclaration(null, "C", null, null, null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+        AstTestFactory.classDeclaration(null, "C", null, null, null,
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_multipleMember() {
     _assertSource(
         "class C {var a; var b;}",
-        AstFactory.classDeclaration(null, "C", null, null, null, null, [
-          AstFactory.fieldDeclaration2(
-              false, Keyword.VAR, [AstFactory.variableDeclaration("a")]),
-          AstFactory.fieldDeclaration2(
-              false, Keyword.VAR, [AstFactory.variableDeclaration("b")])
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null, [
+          AstTestFactory.fieldDeclaration2(
+              false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]),
+          AstTestFactory.fieldDeclaration2(
+              false, Keyword.VAR, [AstTestFactory.variableDeclaration("b")])
         ]));
   }
 
   void test_visitClassDeclaration_parameters() {
     _assertSource(
         "class C<E> {}",
-        AstFactory.classDeclaration(
-            null, "C", AstFactory.typeParameterList(["E"]), null, null, null));
+        AstTestFactory.classDeclaration(null, "C",
+            AstTestFactory.typeParameterList(["E"]), null, null, null));
   }
 
   void test_visitClassDeclaration_parameters_extends() {
     _assertSource(
         "class C<E> extends A {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
             null,
             null));
   }
@@ -3598,102 +3709,102 @@
   void test_visitClassDeclaration_parameters_extends_implements() {
     _assertSource(
         "class C<E> extends A implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
             null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_parameters_extends_with() {
     _assertSource(
         "class C<E> extends A with M {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
             null));
   }
 
   void test_visitClassDeclaration_parameters_extends_with_implements() {
     _assertSource(
         "class C<E> extends A with M implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
-            AstFactory.extendsClause(AstFactory.typeName4("A")),
-            AstFactory.withClause([AstFactory.typeName4("M")]),
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.typeParameterList(["E"]),
+            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_parameters_implements() {
     _assertSource(
         "class C<E> implements B {}",
-        AstFactory.classDeclaration(
+        AstTestFactory.classDeclaration(
             null,
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             null,
             null,
-            AstFactory.implementsClause([AstFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
   }
 
   void test_visitClassDeclaration_singleMember() {
     _assertSource(
         "class C {var a;}",
-        AstFactory.classDeclaration(null, "C", null, null, null, null, [
-          AstFactory.fieldDeclaration2(
-              false, Keyword.VAR, [AstFactory.variableDeclaration("a")])
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null, [
+          AstTestFactory.fieldDeclaration2(
+              false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitClassDeclaration_withMetadata() {
     ClassDeclaration declaration =
-        AstFactory.classDeclaration(null, "C", null, null, null, null);
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+        AstTestFactory.classDeclaration(null, "C", null, null, null, null);
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated class C {}", declaration);
   }
 
   void test_visitClassTypeAlias_abstract() {
     _assertSource(
         "abstract class C = S with M1;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
             null,
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
             null));
   }
 
   void test_visitClassTypeAlias_abstract_implements() {
     _assertSource(
         "abstract class C = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
             null,
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_generic() {
     _assertSource(
         "class C<E> = S<E> with M1<E>;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             null,
-            AstFactory.typeName4("S", [AstFactory.typeName4("E")]),
-            AstFactory.withClause([
-              AstFactory.typeName4("M1", [AstFactory.typeName4("E")])
+            AstTestFactory.typeName4("S", [AstTestFactory.typeName4("E")]),
+            AstTestFactory.withClause([
+              AstTestFactory.typeName4("M1", [AstTestFactory.typeName4("E")])
             ]),
             null));
   }
@@ -3701,68 +3812,73 @@
   void test_visitClassTypeAlias_implements() {
     _assertSource(
         "class C = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
             null,
             null,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_minimal() {
     _assertSource(
         "class C = S with M1;",
-        AstFactory.classTypeAlias("C", null, null, AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]), null));
+        AstTestFactory.classTypeAlias(
+            "C",
+            null,
+            null,
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            null));
   }
 
   void test_visitClassTypeAlias_parameters_abstract() {
     _assertSource(
         "abstract class C<E> = S with M1;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
             null));
   }
 
   void test_visitClassTypeAlias_parameters_abstract_implements() {
     _assertSource(
         "abstract class C<E> = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             Keyword.ABSTRACT,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_parameters_implements() {
     _assertSource(
         "class C<E> = S with M1 implements I;",
-        AstFactory.classTypeAlias(
+        AstTestFactory.classTypeAlias(
             "C",
-            AstFactory.typeParameterList(["E"]),
+            AstTestFactory.typeParameterList(["E"]),
             null,
-            AstFactory.typeName4("S"),
-            AstFactory.withClause([AstFactory.typeName4("M1")]),
-            AstFactory.implementsClause([AstFactory.typeName4("I")])));
+            AstTestFactory.typeName4("S"),
+            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
   }
 
   void test_visitClassTypeAlias_withMetadata() {
-    ClassTypeAlias declaration = AstFactory.classTypeAlias(
+    ClassTypeAlias declaration = AstTestFactory.classTypeAlias(
         "C",
         null,
         null,
-        AstFactory.typeName4("S"),
-        AstFactory.withClause([AstFactory.typeName4("M1")]),
+        AstTestFactory.typeName4("S"),
+        AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
         null);
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated class C = S with M1;", declaration);
   }
 
@@ -3774,374 +3890,388 @@
   }
 
   void test_visitCommentReference() {
-    _assertSource("", new CommentReference(null, AstFactory.identifier3("a")));
+    _assertSource(
+        "", new CommentReference(null, AstTestFactory.identifier3("a")));
   }
 
   void test_visitCompilationUnit_declaration() {
     _assertSource(
         "var a;",
-        AstFactory.compilationUnit2([
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+        AstTestFactory.compilationUnit2([
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitCompilationUnit_directive() {
-    _assertSource("library l;",
-        AstFactory.compilationUnit3([AstFactory.libraryDirective2("l")]));
+    _assertSource(
+        "library l;",
+        AstTestFactory
+            .compilationUnit3([AstTestFactory.libraryDirective2("l")]));
   }
 
   void test_visitCompilationUnit_directive_declaration() {
     _assertSource(
         "library l; var a;",
-        AstFactory.compilationUnit4([
-          AstFactory.libraryDirective2("l")
+        AstTestFactory.compilationUnit4([
+          AstTestFactory.libraryDirective2("l")
         ], [
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitCompilationUnit_empty() {
-    _assertSource("", AstFactory.compilationUnit());
+    _assertSource("", AstTestFactory.compilationUnit());
   }
 
   void test_visitCompilationUnit_script() {
     _assertSource(
-        "!#/bin/dartvm", AstFactory.compilationUnit5("!#/bin/dartvm"));
+        "!#/bin/dartvm", AstTestFactory.compilationUnit5("!#/bin/dartvm"));
   }
 
   void test_visitCompilationUnit_script_declaration() {
     _assertSource(
         "!#/bin/dartvm var a;",
-        AstFactory.compilationUnit6("!#/bin/dartvm", [
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+        AstTestFactory.compilationUnit6("!#/bin/dartvm", [
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitCompilationUnit_script_directive() {
     _assertSource(
         "!#/bin/dartvm library l;",
-        AstFactory.compilationUnit7(
-            "!#/bin/dartvm", [AstFactory.libraryDirective2("l")]));
+        AstTestFactory.compilationUnit7(
+            "!#/bin/dartvm", [AstTestFactory.libraryDirective2("l")]));
   }
 
   void test_visitCompilationUnit_script_directives_declarations() {
     _assertSource(
         "!#/bin/dartvm library l; var a;",
-        AstFactory.compilationUnit8("!#/bin/dartvm", [
-          AstFactory.libraryDirective2("l")
+        AstTestFactory.compilationUnit8("!#/bin/dartvm", [
+          AstTestFactory.libraryDirective2("l")
         ], [
-          AstFactory.topLevelVariableDeclaration2(
-              Keyword.VAR, [AstFactory.variableDeclaration("a")])
+          AstTestFactory.topLevelVariableDeclaration2(
+              Keyword.VAR, [AstTestFactory.variableDeclaration("a")])
         ]));
   }
 
   void test_visitConditionalExpression() {
     _assertSource(
         "a ? b : c",
-        AstFactory.conditionalExpression(AstFactory.identifier3("a"),
-            AstFactory.identifier3("b"), AstFactory.identifier3("c")));
+        AstTestFactory.conditionalExpression(AstTestFactory.identifier3("a"),
+            AstTestFactory.identifier3("b"), AstTestFactory.identifier3("c")));
   }
 
   void test_visitConstructorDeclaration_const() {
     _assertSource(
         "const C() {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             Keyword.CONST,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_external() {
     _assertSource(
         "external C();",
-        AstFactory.constructorDeclaration(AstFactory.identifier3("C"), null,
-            AstFactory.formalParameterList(), null));
+        AstTestFactory.constructorDeclaration(AstTestFactory.identifier3("C"),
+            null, AstTestFactory.formalParameterList(), null));
   }
 
   void test_visitConstructorDeclaration_minimal() {
     _assertSource(
         "C() {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_multipleInitializers() {
     _assertSource(
         "C() : a = b, c = d {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             [
-              AstFactory.constructorFieldInitializer(
-                  false, "a", AstFactory.identifier3("b")),
-              AstFactory.constructorFieldInitializer(
-                  false, "c", AstFactory.identifier3("d"))
+              AstTestFactory.constructorFieldInitializer(
+                  false, "a", AstTestFactory.identifier3("b")),
+              AstTestFactory.constructorFieldInitializer(
+                  false, "c", AstTestFactory.identifier3("d"))
             ],
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_multipleParameters() {
     _assertSource(
         "C(var a, var b) {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList([
-              AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-              AstFactory.simpleFormalParameter(Keyword.VAR, "b")
+            AstTestFactory.formalParameterList([
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "b")
             ]),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_named() {
     _assertSource(
         "C.m() {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             "m",
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_singleInitializer() {
     _assertSource(
         "C() : a = b {}",
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             null,
             null,
-            AstFactory.identifier3("C"),
+            AstTestFactory.identifier3("C"),
             null,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             [
-              AstFactory.constructorFieldInitializer(
-                  false, "a", AstFactory.identifier3("b"))
+              AstTestFactory.constructorFieldInitializer(
+                  false, "a", AstTestFactory.identifier3("b"))
             ],
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitConstructorDeclaration_withMetadata() {
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+    ConstructorDeclaration declaration = AstTestFactory.constructorDeclaration2(
         null,
         null,
-        AstFactory.identifier3("C"),
+        AstTestFactory.identifier3("C"),
         null,
-        AstFactory.formalParameterList(),
+        AstTestFactory.formalParameterList(),
         null,
-        AstFactory.blockFunctionBody2());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+        AstTestFactory.blockFunctionBody2());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated C() {}", declaration);
   }
 
   void test_visitConstructorFieldInitializer_withoutThis() {
     _assertSource(
         "a = b",
-        AstFactory.constructorFieldInitializer(
-            false, "a", AstFactory.identifier3("b")));
+        AstTestFactory.constructorFieldInitializer(
+            false, "a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitConstructorFieldInitializer_withThis() {
     _assertSource(
         "this.a = b",
-        AstFactory.constructorFieldInitializer(
-            true, "a", AstFactory.identifier3("b")));
+        AstTestFactory.constructorFieldInitializer(
+            true, "a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitConstructorName_named_prefix() {
-    _assertSource("p.C.n",
-        AstFactory.constructorName(AstFactory.typeName4("p.C.n"), null));
+    _assertSource(
+        "p.C.n",
+        AstTestFactory.constructorName(
+            AstTestFactory.typeName4("p.C.n"), null));
   }
 
   void test_visitConstructorName_unnamed_noPrefix() {
-    _assertSource(
-        "C", AstFactory.constructorName(AstFactory.typeName4("C"), null));
+    _assertSource("C",
+        AstTestFactory.constructorName(AstTestFactory.typeName4("C"), null));
   }
 
   void test_visitConstructorName_unnamed_prefix() {
     _assertSource(
         "p.C",
-        AstFactory.constructorName(
-            AstFactory.typeName3(AstFactory.identifier5("p", "C")), null));
+        AstTestFactory.constructorName(
+            AstTestFactory.typeName3(AstTestFactory.identifier5("p", "C")),
+            null));
   }
 
   void test_visitContinueStatement_label() {
-    _assertSource("continue l;", AstFactory.continueStatement("l"));
+    _assertSource("continue l;", AstTestFactory.continueStatement("l"));
   }
 
   void test_visitContinueStatement_noLabel() {
-    _assertSource("continue;", AstFactory.continueStatement());
+    _assertSource("continue;", AstTestFactory.continueStatement());
   }
 
   void test_visitDefaultFormalParameter_annotation() {
-    DefaultFormalParameter parameter = AstFactory.positionalFormalParameter(
-        AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0));
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    DefaultFormalParameter parameter = AstTestFactory.positionalFormalParameter(
+        AstTestFactory.simpleFormalParameter3("p"), AstTestFactory.integer(0));
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A p = 0', parameter);
   }
 
   void test_visitDefaultFormalParameter_named_noValue() {
     _assertSource(
         "p",
-        AstFactory.namedFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), null));
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"), null));
   }
 
   void test_visitDefaultFormalParameter_named_value() {
     _assertSource(
         "p : 0",
-        AstFactory.namedFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0)));
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitDefaultFormalParameter_positional_noValue() {
     _assertSource(
         "p",
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), null));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"), null));
   }
 
   void test_visitDefaultFormalParameter_positional_value() {
     _assertSource(
         "p = 0",
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0)));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter3("p"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitDoStatement() {
     _assertSource(
         "do {} while (c);",
-        AstFactory.doStatement(
-            AstFactory.block(), AstFactory.identifier3("c")));
+        AstTestFactory.doStatement(
+            AstTestFactory.block(), AstTestFactory.identifier3("c")));
   }
 
   void test_visitDoubleLiteral() {
-    _assertSource("4.2", AstFactory.doubleLiteral(4.2));
+    _assertSource("4.2", AstTestFactory.doubleLiteral(4.2));
   }
 
   void test_visitEmptyFunctionBody() {
-    _assertSource(";", AstFactory.emptyFunctionBody());
+    _assertSource(";", AstTestFactory.emptyFunctionBody());
   }
 
   void test_visitEmptyStatement() {
-    _assertSource(";", AstFactory.emptyStatement());
+    _assertSource(";", AstTestFactory.emptyStatement());
   }
 
   void test_visitEnumDeclaration_multiple() {
-    _assertSource(
-        "enum E {ONE, TWO}", AstFactory.enumDeclaration2("E", ["ONE", "TWO"]));
+    _assertSource("enum E {ONE, TWO}",
+        AstTestFactory.enumDeclaration2("E", ["ONE", "TWO"]));
   }
 
   void test_visitEnumDeclaration_single() {
-    _assertSource("enum E {ONE}", AstFactory.enumDeclaration2("E", ["ONE"]));
+    _assertSource(
+        "enum E {ONE}", AstTestFactory.enumDeclaration2("E", ["ONE"]));
   }
 
   void test_visitExportDirective_combinator() {
     _assertSource(
         "export 'a.dart' show A;",
-        AstFactory.exportDirective2("a.dart", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")])
+        AstTestFactory.exportDirective2("a.dart", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
         ]));
   }
 
   void test_visitExportDirective_combinators() {
     _assertSource(
         "export 'a.dart' show A hide B;",
-        AstFactory.exportDirective2("a.dart", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")]),
-          AstFactory.hideCombinator([AstFactory.identifier3("B")])
+        AstTestFactory.exportDirective2("a.dart", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
+          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
         ]));
   }
 
   void test_visitExportDirective_minimal() {
-    _assertSource("export 'a.dart';", AstFactory.exportDirective2("a.dart"));
+    _assertSource(
+        "export 'a.dart';", AstTestFactory.exportDirective2("a.dart"));
   }
 
   void test_visitExportDirective_withMetadata() {
-    ExportDirective directive = AstFactory.exportDirective2("a.dart");
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    ExportDirective directive = AstTestFactory.exportDirective2("a.dart");
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated export 'a.dart';", directive);
   }
 
   void test_visitExpressionFunctionBody_async() {
-    _assertSource("async => a;",
-        AstFactory.asyncExpressionFunctionBody(AstFactory.identifier3("a")));
+    _assertSource(
+        "async => a;",
+        AstTestFactory
+            .asyncExpressionFunctionBody(AstTestFactory.identifier3("a")));
   }
 
   void test_visitExpressionFunctionBody_simple() {
     _assertSource("=> a;",
-        AstFactory.expressionFunctionBody(AstFactory.identifier3("a")));
+        AstTestFactory.expressionFunctionBody(AstTestFactory.identifier3("a")));
   }
 
   void test_visitExpressionStatement() {
-    _assertSource(
-        "a;", AstFactory.expressionStatement(AstFactory.identifier3("a")));
+    _assertSource("a;",
+        AstTestFactory.expressionStatement(AstTestFactory.identifier3("a")));
   }
 
   void test_visitExtendsClause() {
-    _assertSource(
-        "extends C", AstFactory.extendsClause(AstFactory.typeName4("C")));
+    _assertSource("extends C",
+        AstTestFactory.extendsClause(AstTestFactory.typeName4("C")));
   }
 
   void test_visitFieldDeclaration_instance() {
     _assertSource(
         "var a;",
-        AstFactory.fieldDeclaration2(
-            false, Keyword.VAR, [AstFactory.variableDeclaration("a")]));
+        AstTestFactory.fieldDeclaration2(
+            false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]));
   }
 
   void test_visitFieldDeclaration_static() {
     _assertSource(
         "static var a;",
-        AstFactory.fieldDeclaration2(
-            true, Keyword.VAR, [AstFactory.variableDeclaration("a")]));
+        AstTestFactory.fieldDeclaration2(
+            true, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]));
   }
 
   void test_visitFieldDeclaration_withMetadata() {
-    FieldDeclaration declaration = AstFactory.fieldDeclaration2(
-        false, Keyword.VAR, [AstFactory.variableDeclaration("a")]);
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    FieldDeclaration declaration = AstTestFactory.fieldDeclaration2(
+        false, Keyword.VAR, [AstTestFactory.variableDeclaration("a")]);
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated var a;", declaration);
   }
 
   void test_visitFieldFormalParameter_annotation() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('f');
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    FieldFormalParameter parameter = AstTestFactory.fieldFormalParameter2('f');
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A this.f', parameter);
   }
 
   void test_visitFieldFormalParameter_functionTyped() {
     _assertSource(
         "A this.a(b)",
-        AstFactory.fieldFormalParameter(
+        AstTestFactory.fieldFormalParameter(
             null,
-            AstFactory.typeName4("A"),
+            AstTestFactory.typeName4("A"),
             "a",
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter3("b")])));
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter3("b")])));
   }
 
   void test_visitFieldFormalParameter_functionTyped_typeParameters() {
@@ -4151,37 +4281,39 @@
             null,
             null,
             null,
-            AstFactory.typeName4('A'),
+            AstTestFactory.typeName4('A'),
             TokenFactory.tokenFromKeyword(Keyword.THIS),
             TokenFactory.tokenFromType(TokenType.PERIOD),
-            AstFactory.identifier3('a'),
-            AstFactory.typeParameterList(['E', 'F']),
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter3("b")])));
+            AstTestFactory.identifier3('a'),
+            AstTestFactory.typeParameterList(['E', 'F']),
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter3("b")])));
   }
 
   void test_visitFieldFormalParameter_keyword() {
-    _assertSource(
-        "var this.a", AstFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
+    _assertSource("var this.a",
+        AstTestFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
   }
 
   void test_visitFieldFormalParameter_keywordAndType() {
     _assertSource(
         "final A this.a",
-        AstFactory.fieldFormalParameter(
-            Keyword.FINAL, AstFactory.typeName4("A"), "a"));
+        AstTestFactory.fieldFormalParameter(
+            Keyword.FINAL, AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitFieldFormalParameter_type() {
-    _assertSource("A this.a",
-        AstFactory.fieldFormalParameter(null, AstFactory.typeName4("A"), "a"));
+    _assertSource(
+        "A this.a",
+        AstTestFactory.fieldFormalParameter(
+            null, AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitForEachStatement_declared() {
     _assertSource(
         "for (var a in b) {}",
-        AstFactory.forEachStatement(AstFactory.declaredIdentifier3("a"),
-            AstFactory.identifier3("b"), AstFactory.block()));
+        AstTestFactory.forEachStatement(AstTestFactory.declaredIdentifier3("a"),
+            AstTestFactory.identifier3("b"), AstTestFactory.block()));
   }
 
   void test_visitForEachStatement_variable() {
@@ -4191,11 +4323,11 @@
             null,
             TokenFactory.tokenFromKeyword(Keyword.FOR),
             TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-            AstFactory.identifier3("a"),
+            AstTestFactory.identifier3("a"),
             TokenFactory.tokenFromKeyword(Keyword.IN),
-            AstFactory.identifier3("b"),
+            AstTestFactory.identifier3("b"),
             TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitForEachStatement_variable_await() {
@@ -4205,268 +4337,288 @@
             TokenFactory.tokenFromString("await"),
             TokenFactory.tokenFromKeyword(Keyword.FOR),
             TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
-            AstFactory.identifier3("a"),
+            AstTestFactory.identifier3("a"),
             TokenFactory.tokenFromKeyword(Keyword.IN),
-            AstFactory.identifier3("b"),
+            AstTestFactory.identifier3("b"),
             TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitFormalParameterList_empty() {
-    _assertSource("()", AstFactory.formalParameterList());
+    _assertSource("()", AstTestFactory.formalParameterList());
   }
 
   void test_visitFormalParameterList_n() {
     _assertSource(
         "({a : 0})",
-        AstFactory.formalParameterList([
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0))
         ]));
   }
 
   void test_visitFormalParameterList_nn() {
     _assertSource(
         "({a : 0, b : 1})",
-        AstFactory.formalParameterList([
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0)),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_p() {
     _assertSource(
         "([a = 0])",
-        AstFactory.formalParameterList([
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0))
         ]));
   }
 
   void test_visitFormalParameterList_pp() {
     _assertSource(
         "([a = 0, b = 1])",
-        AstFactory.formalParameterList([
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("a"),
+              AstTestFactory.integer(0)),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_r() {
     _assertSource(
         "(a)",
-        AstFactory
-            .formalParameterList([AstFactory.simpleFormalParameter3("a")]));
+        AstTestFactory
+            .formalParameterList([AstTestFactory.simpleFormalParameter3("a")]));
   }
 
   void test_visitFormalParameterList_rn() {
     _assertSource(
         "(a, {b : 1})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_rnn() {
     _assertSource(
         "(a, {b : 1, c : 2})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(2))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1)),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(2))
         ]));
   }
 
   void test_visitFormalParameterList_rp() {
     _assertSource(
         "(a, [b = 1])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1))
         ]));
   }
 
   void test_visitFormalParameterList_rpp() {
     _assertSource(
         "(a, [b = 1, c = 2])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(2))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("b"),
+              AstTestFactory.integer(1)),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(2))
         ]));
   }
 
   void test_visitFormalParameterList_rr() {
     _assertSource(
         "(a, b)",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b")
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b")
         ]));
   }
 
   void test_visitFormalParameterList_rrn() {
     _assertSource(
         "(a, b, {c : 3})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3))
         ]));
   }
 
   void test_visitFormalParameterList_rrnn() {
     _assertSource(
         "(a, b, {c : 3, d : 4})",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)),
-          AstFactory.namedFormalParameter(
-              AstFactory.simpleFormalParameter3("d"), AstFactory.integer(4))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3)),
+          AstTestFactory.namedFormalParameter(
+              AstTestFactory.simpleFormalParameter3("d"),
+              AstTestFactory.integer(4))
         ]));
   }
 
   void test_visitFormalParameterList_rrp() {
     _assertSource(
         "(a, b, [c = 3])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3))
         ]));
   }
 
   void test_visitFormalParameterList_rrpp() {
     _assertSource(
         "(a, b, [c = 3, d = 4])",
-        AstFactory.formalParameterList([
-          AstFactory.simpleFormalParameter3("a"),
-          AstFactory.simpleFormalParameter3("b"),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)),
-          AstFactory.positionalFormalParameter(
-              AstFactory.simpleFormalParameter3("d"), AstFactory.integer(4))
+        AstTestFactory.formalParameterList([
+          AstTestFactory.simpleFormalParameter3("a"),
+          AstTestFactory.simpleFormalParameter3("b"),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("c"),
+              AstTestFactory.integer(3)),
+          AstTestFactory.positionalFormalParameter(
+              AstTestFactory.simpleFormalParameter3("d"),
+              AstTestFactory.integer(4))
         ]));
   }
 
   void test_visitForStatement_c() {
     _assertSource(
         "for (; c;) {}",
-        AstFactory.forStatement(
-            null, AstFactory.identifier3("c"), null, AstFactory.block()));
+        AstTestFactory.forStatement(null, AstTestFactory.identifier3("c"), null,
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_cu() {
     _assertSource(
         "for (; c; u) {}",
-        AstFactory.forStatement(null, AstFactory.identifier3("c"),
-            [AstFactory.identifier3("u")], AstFactory.block()));
+        AstTestFactory.forStatement(null, AstTestFactory.identifier3("c"),
+            [AstTestFactory.identifier3("u")], AstTestFactory.block()));
   }
 
   void test_visitForStatement_e() {
     _assertSource(
         "for (e;;) {}",
-        AstFactory.forStatement(
-            AstFactory.identifier3("e"), null, null, AstFactory.block()));
+        AstTestFactory.forStatement(AstTestFactory.identifier3("e"), null, null,
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_ec() {
     _assertSource(
         "for (e; c;) {}",
-        AstFactory.forStatement(AstFactory.identifier3("e"),
-            AstFactory.identifier3("c"), null, AstFactory.block()));
+        AstTestFactory.forStatement(AstTestFactory.identifier3("e"),
+            AstTestFactory.identifier3("c"), null, AstTestFactory.block()));
   }
 
   void test_visitForStatement_ecu() {
     _assertSource(
         "for (e; c; u) {}",
-        AstFactory.forStatement(
-            AstFactory.identifier3("e"),
-            AstFactory.identifier3("c"),
-            [AstFactory.identifier3("u")],
-            AstFactory.block()));
+        AstTestFactory.forStatement(
+            AstTestFactory.identifier3("e"),
+            AstTestFactory.identifier3("c"),
+            [AstTestFactory.identifier3("u")],
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_eu() {
     _assertSource(
         "for (e;; u) {}",
-        AstFactory.forStatement(AstFactory.identifier3("e"), null,
-            [AstFactory.identifier3("u")], AstFactory.block()));
+        AstTestFactory.forStatement(AstTestFactory.identifier3("e"), null,
+            [AstTestFactory.identifier3("u")], AstTestFactory.block()));
   }
 
   void test_visitForStatement_i() {
     _assertSource(
         "for (var i;;) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
             null,
             null,
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_ic() {
     _assertSource(
         "for (var i; c;) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
-            AstFactory.identifier3("c"),
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
+            AstTestFactory.identifier3("c"),
             null,
-            AstFactory.block()));
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_icu() {
     _assertSource(
         "for (var i; c; u) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
-            AstFactory.identifier3("c"),
-            [AstFactory.identifier3("u")],
-            AstFactory.block()));
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
+            AstTestFactory.identifier3("c"),
+            [AstTestFactory.identifier3("u")],
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_iu() {
     _assertSource(
         "for (var i;; u) {}",
-        AstFactory.forStatement2(
-            AstFactory.variableDeclarationList2(
-                Keyword.VAR, [AstFactory.variableDeclaration("i")]),
+        AstTestFactory.forStatement2(
+            AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration("i")]),
             null,
-            [AstFactory.identifier3("u")],
-            AstFactory.block()));
+            [AstTestFactory.identifier3("u")],
+            AstTestFactory.block()));
   }
 
   void test_visitForStatement_u() {
     _assertSource(
         "for (;; u) {}",
-        AstFactory.forStatement(
-            null, null, [AstFactory.identifier3("u")], AstFactory.block()));
+        AstTestFactory.forStatement(null, null,
+            [AstTestFactory.identifier3("u")], AstTestFactory.block()));
   }
 
   void test_visitFunctionDeclaration_external() {
-    FunctionDeclaration functionDeclaration = AstFactory.functionDeclaration(
-        null,
-        null,
-        "f",
-        AstFactory.functionExpression2(
-            AstFactory.formalParameterList(), AstFactory.emptyFunctionBody()));
+    FunctionDeclaration functionDeclaration =
+        AstTestFactory.functionDeclaration(
+            null,
+            null,
+            "f",
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.emptyFunctionBody()));
     functionDeclaration.externalKeyword =
         TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
     _assertSource("external f();", functionDeclaration);
@@ -4475,158 +4627,168 @@
   void test_visitFunctionDeclaration_getter() {
     _assertSource(
         "get f() {}",
-        AstFactory.functionDeclaration(
-            null, Keyword.GET, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclaration(
+            null, Keyword.GET, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionDeclaration_local_blockBody() {
-    FunctionDeclaration f = AstFactory.functionDeclaration(
-        null, null, "f", AstFactory.functionExpression());
+    FunctionDeclaration f = AstTestFactory.functionDeclaration(
+        null, null, "f", AstTestFactory.functionExpression());
     FunctionDeclarationStatement fStatement =
         new FunctionDeclarationStatement(f);
     _assertSource(
         "main() {f() {} 42;}",
-        AstFactory.functionDeclaration(
+        AstTestFactory.functionDeclaration(
             null,
             null,
             "main",
-            AstFactory.functionExpression2(
-                AstFactory.formalParameterList(),
-                AstFactory.blockFunctionBody2([
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody2([
                   fStatement,
-                  AstFactory.expressionStatement(AstFactory.integer(42))
+                  AstTestFactory.expressionStatement(AstTestFactory.integer(42))
                 ]))));
   }
 
   void test_visitFunctionDeclaration_local_expressionBody() {
-    FunctionDeclaration f = AstFactory.functionDeclaration(
+    FunctionDeclaration f = AstTestFactory.functionDeclaration(
         null,
         null,
         "f",
-        AstFactory.functionExpression2(AstFactory.formalParameterList(),
-            AstFactory.expressionFunctionBody(AstFactory.integer(1))));
+        AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
+            AstTestFactory.expressionFunctionBody(AstTestFactory.integer(1))));
     FunctionDeclarationStatement fStatement =
         new FunctionDeclarationStatement(f);
     _assertSource(
         "main() {f() => 1; 2;}",
-        AstFactory.functionDeclaration(
+        AstTestFactory.functionDeclaration(
             null,
             null,
             "main",
-            AstFactory.functionExpression2(
-                AstFactory.formalParameterList(),
-                AstFactory.blockFunctionBody2([
+            AstTestFactory.functionExpression2(
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody2([
                   fStatement,
-                  AstFactory.expressionStatement(AstFactory.integer(2))
+                  AstTestFactory.expressionStatement(AstTestFactory.integer(2))
                 ]))));
   }
 
   void test_visitFunctionDeclaration_normal() {
     _assertSource(
         "f() {}",
-        AstFactory.functionDeclaration(
-            null, null, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclaration(
+            null, null, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionDeclaration_setter() {
     _assertSource(
         "set f() {}",
-        AstFactory.functionDeclaration(
-            null, Keyword.SET, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclaration(
+            null, Keyword.SET, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionDeclaration_typeParameters() {
     _assertSource(
         "f<E>() {}",
-        AstFactory.functionDeclaration(
+        AstTestFactory.functionDeclaration(
             null,
             null,
             "f",
-            AstFactory.functionExpression3(
-                AstFactory.typeParameterList(['E']),
-                AstFactory.formalParameterList(),
-                AstFactory.blockFunctionBody2())));
+            AstTestFactory.functionExpression3(
+                AstTestFactory.typeParameterList(['E']),
+                AstTestFactory.formalParameterList(),
+                AstTestFactory.blockFunctionBody2())));
   }
 
   void test_visitFunctionDeclaration_withMetadata() {
-    FunctionDeclaration declaration = AstFactory.functionDeclaration(
-        null, null, "f", AstFactory.functionExpression());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+        null, null, "f", AstTestFactory.functionExpression());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated f() {}", declaration);
   }
 
   void test_visitFunctionDeclarationStatement() {
     _assertSource(
         "f() {}",
-        AstFactory.functionDeclarationStatement(
-            null, null, "f", AstFactory.functionExpression()));
+        AstTestFactory.functionDeclarationStatement(
+            null, null, "f", AstTestFactory.functionExpression()));
   }
 
   void test_visitFunctionExpression() {
-    _assertSource("() {}", AstFactory.functionExpression());
+    _assertSource("() {}", AstTestFactory.functionExpression());
   }
 
   void test_visitFunctionExpression_typeParameters() {
     _assertSource(
         "<E>() {}",
-        AstFactory.functionExpression3(AstFactory.typeParameterList(['E']),
-            AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+        AstTestFactory.functionExpression3(
+            AstTestFactory.typeParameterList(['E']),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitFunctionExpressionInvocation_minimal() {
-    _assertSource("f()",
-        AstFactory.functionExpressionInvocation(AstFactory.identifier3("f")));
+    _assertSource(
+        "f()",
+        AstTestFactory
+            .functionExpressionInvocation(AstTestFactory.identifier3("f")));
   }
 
   void test_visitFunctionExpressionInvocation_typeArguments() {
     _assertSource(
         "f<A>()",
-        AstFactory.functionExpressionInvocation2(AstFactory.identifier3("f"),
-            AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+        AstTestFactory.functionExpressionInvocation2(
+            AstTestFactory.identifier3("f"),
+            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')])));
   }
 
   void test_visitFunctionTypeAlias_generic() {
     _assertSource(
         "typedef A F<B>();",
-        AstFactory.typeAlias(
-            AstFactory.typeName4("A"),
+        AstTestFactory.typeAlias(
+            AstTestFactory.typeName4("A"),
             "F",
-            AstFactory.typeParameterList(["B"]),
-            AstFactory.formalParameterList()));
+            AstTestFactory.typeParameterList(["B"]),
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitFunctionTypeAlias_nonGeneric() {
     _assertSource(
         "typedef A F();",
-        AstFactory.typeAlias(AstFactory.typeName4("A"), "F", null,
-            AstFactory.formalParameterList()));
+        AstTestFactory.typeAlias(AstTestFactory.typeName4("A"), "F", null,
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitFunctionTypeAlias_withMetadata() {
-    FunctionTypeAlias declaration = AstFactory.typeAlias(
-        AstFactory.typeName4("A"), "F", null, AstFactory.formalParameterList());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    FunctionTypeAlias declaration = AstTestFactory.typeAlias(
+        AstTestFactory.typeName4("A"),
+        "F",
+        null,
+        AstTestFactory.formalParameterList());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated typedef A F();", declaration);
   }
 
   void test_visitFunctionTypedFormalParameter_annotation() {
     FunctionTypedFormalParameter parameter =
-        AstFactory.functionTypedFormalParameter(null, "f");
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+        AstTestFactory.functionTypedFormalParameter(null, "f");
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A f()', parameter);
   }
 
   void test_visitFunctionTypedFormalParameter_noType() {
-    _assertSource("f()", AstFactory.functionTypedFormalParameter(null, "f"));
+    _assertSource(
+        "f()", AstTestFactory.functionTypedFormalParameter(null, "f"));
   }
 
   void test_visitFunctionTypedFormalParameter_type() {
     _assertSource(
         "T f()",
-        AstFactory.functionTypedFormalParameter(
-            AstFactory.typeName4("T"), "f"));
+        AstTestFactory.functionTypedFormalParameter(
+            AstTestFactory.typeName4("T"), "f"));
   }
 
   void test_visitFunctionTypedFormalParameter_typeParameters() {
@@ -4635,939 +4797,971 @@
         new FunctionTypedFormalParameter(
             null,
             null,
-            AstFactory.typeName4("T"),
-            AstFactory.identifier3('f'),
-            AstFactory.typeParameterList(['E']),
-            AstFactory.formalParameterList([])));
+            AstTestFactory.typeName4("T"),
+            AstTestFactory.identifier3('f'),
+            AstTestFactory.typeParameterList(['E']),
+            AstTestFactory.formalParameterList([])));
   }
 
   void test_visitIfStatement_withElse() {
     _assertSource(
         "if (c) {} else {}",
-        AstFactory.ifStatement2(AstFactory.identifier3("c"), AstFactory.block(),
-            AstFactory.block()));
+        AstTestFactory.ifStatement2(AstTestFactory.identifier3("c"),
+            AstTestFactory.block(), AstTestFactory.block()));
   }
 
   void test_visitIfStatement_withoutElse() {
     _assertSource(
         "if (c) {}",
-        AstFactory.ifStatement(
-            AstFactory.identifier3("c"), AstFactory.block()));
+        AstTestFactory.ifStatement(
+            AstTestFactory.identifier3("c"), AstTestFactory.block()));
   }
 
   void test_visitImplementsClause_multiple() {
     _assertSource(
         "implements A, B",
-        AstFactory.implementsClause(
-            [AstFactory.typeName4("A"), AstFactory.typeName4("B")]));
+        AstTestFactory.implementsClause(
+            [AstTestFactory.typeName4("A"), AstTestFactory.typeName4("B")]));
   }
 
   void test_visitImplementsClause_single() {
     _assertSource("implements A",
-        AstFactory.implementsClause([AstFactory.typeName4("A")]));
+        AstTestFactory.implementsClause([AstTestFactory.typeName4("A")]));
   }
 
   void test_visitImportDirective_combinator() {
     _assertSource(
         "import 'a.dart' show A;",
-        AstFactory.importDirective3("a.dart", null, [
-          AstFactory.showCombinator([AstFactory.identifier3("A")])
+        AstTestFactory.importDirective3("a.dart", null, [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
         ]));
   }
 
   void test_visitImportDirective_combinators() {
     _assertSource(
         "import 'a.dart' show A hide B;",
-        AstFactory.importDirective3("a.dart", null, [
-          AstFactory.showCombinator([AstFactory.identifier3("A")]),
-          AstFactory.hideCombinator([AstFactory.identifier3("B")])
+        AstTestFactory.importDirective3("a.dart", null, [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
+          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
         ]));
   }
 
   void test_visitImportDirective_deferred() {
     _assertSource("import 'a.dart' deferred as p;",
-        AstFactory.importDirective2("a.dart", true, "p"));
+        AstTestFactory.importDirective2("a.dart", true, "p"));
   }
 
   void test_visitImportDirective_minimal() {
     _assertSource(
-        "import 'a.dart';", AstFactory.importDirective3("a.dart", null));
+        "import 'a.dart';", AstTestFactory.importDirective3("a.dart", null));
   }
 
   void test_visitImportDirective_prefix() {
-    _assertSource(
-        "import 'a.dart' as p;", AstFactory.importDirective3("a.dart", "p"));
+    _assertSource("import 'a.dart' as p;",
+        AstTestFactory.importDirective3("a.dart", "p"));
   }
 
   void test_visitImportDirective_prefix_combinator() {
     _assertSource(
         "import 'a.dart' as p show A;",
-        AstFactory.importDirective3("a.dart", "p", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")])
+        AstTestFactory.importDirective3("a.dart", "p", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")])
         ]));
   }
 
   void test_visitImportDirective_prefix_combinators() {
     _assertSource(
         "import 'a.dart' as p show A hide B;",
-        AstFactory.importDirective3("a.dart", "p", [
-          AstFactory.showCombinator([AstFactory.identifier3("A")]),
-          AstFactory.hideCombinator([AstFactory.identifier3("B")])
+        AstTestFactory.importDirective3("a.dart", "p", [
+          AstTestFactory.showCombinator([AstTestFactory.identifier3("A")]),
+          AstTestFactory.hideCombinator([AstTestFactory.identifier3("B")])
         ]));
   }
 
   void test_visitImportDirective_withMetadata() {
-    ImportDirective directive = AstFactory.importDirective3("a.dart", null);
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    ImportDirective directive = AstTestFactory.importDirective3("a.dart", null);
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated import 'a.dart';", directive);
   }
 
   void test_visitImportHideCombinator_multiple() {
     _assertSource(
         "hide a, b",
-        AstFactory.hideCombinator(
-            [AstFactory.identifier3("a"), AstFactory.identifier3("b")]));
+        AstTestFactory.hideCombinator([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b")
+        ]));
   }
 
   void test_visitImportHideCombinator_single() {
-    _assertSource(
-        "hide a", AstFactory.hideCombinator([AstFactory.identifier3("a")]));
+    _assertSource("hide a",
+        AstTestFactory.hideCombinator([AstTestFactory.identifier3("a")]));
   }
 
   void test_visitImportShowCombinator_multiple() {
     _assertSource(
         "show a, b",
-        AstFactory.showCombinator(
-            [AstFactory.identifier3("a"), AstFactory.identifier3("b")]));
+        AstTestFactory.showCombinator([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b")
+        ]));
   }
 
   void test_visitImportShowCombinator_single() {
-    _assertSource(
-        "show a", AstFactory.showCombinator([AstFactory.identifier3("a")]));
+    _assertSource("show a",
+        AstTestFactory.showCombinator([AstTestFactory.identifier3("a")]));
   }
 
   void test_visitIndexExpression() {
     _assertSource(
         "a[i]",
-        AstFactory.indexExpression(
-            AstFactory.identifier3("a"), AstFactory.identifier3("i")));
+        AstTestFactory.indexExpression(
+            AstTestFactory.identifier3("a"), AstTestFactory.identifier3("i")));
   }
 
   void test_visitInstanceCreationExpression_const() {
     _assertSource(
         "const C()",
-        AstFactory.instanceCreationExpression2(
-            Keyword.CONST, AstFactory.typeName4("C")));
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.CONST, AstTestFactory.typeName4("C")));
   }
 
   void test_visitInstanceCreationExpression_named() {
     _assertSource(
         "new C.c()",
-        AstFactory.instanceCreationExpression3(
-            Keyword.NEW, AstFactory.typeName4("C"), "c"));
+        AstTestFactory.instanceCreationExpression3(
+            Keyword.NEW, AstTestFactory.typeName4("C"), "c"));
   }
 
   void test_visitInstanceCreationExpression_unnamed() {
     _assertSource(
         "new C()",
-        AstFactory.instanceCreationExpression2(
-            Keyword.NEW, AstFactory.typeName4("C")));
+        AstTestFactory.instanceCreationExpression2(
+            Keyword.NEW, AstTestFactory.typeName4("C")));
   }
 
   void test_visitIntegerLiteral() {
-    _assertSource("42", AstFactory.integer(42));
+    _assertSource("42", AstTestFactory.integer(42));
   }
 
   void test_visitInterpolationExpression_expression() {
-    _assertSource("\${a}",
-        AstFactory.interpolationExpression(AstFactory.identifier3("a")));
+    _assertSource(
+        "\${a}",
+        AstTestFactory
+            .interpolationExpression(AstTestFactory.identifier3("a")));
   }
 
   void test_visitInterpolationExpression_identifier() {
-    _assertSource("\$a", AstFactory.interpolationExpression2("a"));
+    _assertSource("\$a", AstTestFactory.interpolationExpression2("a"));
   }
 
   void test_visitInterpolationString() {
-    _assertSource("'x", AstFactory.interpolationString("'x", "x"));
+    _assertSource("'x", AstTestFactory.interpolationString("'x", "x"));
   }
 
   void test_visitIsExpression_negated() {
     _assertSource(
         "a is! C",
-        AstFactory.isExpression(
-            AstFactory.identifier3("a"), true, AstFactory.typeName4("C")));
+        AstTestFactory.isExpression(AstTestFactory.identifier3("a"), true,
+            AstTestFactory.typeName4("C")));
   }
 
   void test_visitIsExpression_normal() {
     _assertSource(
         "a is C",
-        AstFactory.isExpression(
-            AstFactory.identifier3("a"), false, AstFactory.typeName4("C")));
+        AstTestFactory.isExpression(AstTestFactory.identifier3("a"), false,
+            AstTestFactory.typeName4("C")));
   }
 
   void test_visitLabel() {
-    _assertSource("a:", AstFactory.label2("a"));
+    _assertSource("a:", AstTestFactory.label2("a"));
   }
 
   void test_visitLabeledStatement_multiple() {
     _assertSource(
         "a: b: return;",
-        AstFactory.labeledStatement(
-            [AstFactory.label2("a"), AstFactory.label2("b")],
-            AstFactory.returnStatement()));
+        AstTestFactory.labeledStatement(
+            [AstTestFactory.label2("a"), AstTestFactory.label2("b")],
+            AstTestFactory.returnStatement()));
   }
 
   void test_visitLabeledStatement_single() {
     _assertSource(
         "a: return;",
-        AstFactory.labeledStatement(
-            [AstFactory.label2("a")], AstFactory.returnStatement()));
+        AstTestFactory.labeledStatement(
+            [AstTestFactory.label2("a")], AstTestFactory.returnStatement()));
   }
 
   void test_visitLibraryDirective() {
-    _assertSource("library l;", AstFactory.libraryDirective2("l"));
+    _assertSource("library l;", AstTestFactory.libraryDirective2("l"));
   }
 
   void test_visitLibraryDirective_withMetadata() {
-    LibraryDirective directive = AstFactory.libraryDirective2("l");
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    LibraryDirective directive = AstTestFactory.libraryDirective2("l");
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated library l;", directive);
   }
 
   void test_visitLibraryIdentifier_multiple() {
     _assertSource(
         "a.b.c",
-        AstFactory.libraryIdentifier([
-          AstFactory.identifier3("a"),
-          AstFactory.identifier3("b"),
-          AstFactory.identifier3("c")
+        AstTestFactory.libraryIdentifier([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b"),
+          AstTestFactory.identifier3("c")
         ]));
   }
 
   void test_visitLibraryIdentifier_single() {
-    _assertSource(
-        "a", AstFactory.libraryIdentifier([AstFactory.identifier3("a")]));
+    _assertSource("a",
+        AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("a")]));
   }
 
   void test_visitListLiteral_const() {
-    _assertSource("const []", AstFactory.listLiteral2(Keyword.CONST, null));
+    _assertSource("const []", AstTestFactory.listLiteral2(Keyword.CONST, null));
   }
 
   void test_visitListLiteral_empty() {
-    _assertSource("[]", AstFactory.listLiteral());
+    _assertSource("[]", AstTestFactory.listLiteral());
   }
 
   void test_visitListLiteral_nonEmpty() {
     _assertSource(
         "[a, b, c]",
-        AstFactory.listLiteral([
-          AstFactory.identifier3("a"),
-          AstFactory.identifier3("b"),
-          AstFactory.identifier3("c")
+        AstTestFactory.listLiteral([
+          AstTestFactory.identifier3("a"),
+          AstTestFactory.identifier3("b"),
+          AstTestFactory.identifier3("c")
         ]));
   }
 
   void test_visitMapLiteral_const() {
-    _assertSource("const {}", AstFactory.mapLiteral(Keyword.CONST, null));
+    _assertSource("const {}", AstTestFactory.mapLiteral(Keyword.CONST, null));
   }
 
   void test_visitMapLiteral_empty() {
-    _assertSource("{}", AstFactory.mapLiteral2());
+    _assertSource("{}", AstTestFactory.mapLiteral2());
   }
 
   void test_visitMapLiteral_nonEmpty() {
     _assertSource(
         "{'a' : a, 'b' : b, 'c' : c}",
-        AstFactory.mapLiteral2([
-          AstFactory.mapLiteralEntry("a", AstFactory.identifier3("a")),
-          AstFactory.mapLiteralEntry("b", AstFactory.identifier3("b")),
-          AstFactory.mapLiteralEntry("c", AstFactory.identifier3("c"))
+        AstTestFactory.mapLiteral2([
+          AstTestFactory.mapLiteralEntry("a", AstTestFactory.identifier3("a")),
+          AstTestFactory.mapLiteralEntry("b", AstTestFactory.identifier3("b")),
+          AstTestFactory.mapLiteralEntry("c", AstTestFactory.identifier3("c"))
         ]));
   }
 
   void test_visitMapLiteralEntry() {
     _assertSource("'a' : b",
-        AstFactory.mapLiteralEntry("a", AstFactory.identifier3("b")));
+        AstTestFactory.mapLiteralEntry("a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitMethodDeclaration_external() {
     _assertSource(
         "external m();",
-        AstFactory.methodDeclaration(null, null, null, null,
-            AstFactory.identifier3("m"), AstFactory.formalParameterList()));
+        AstTestFactory.methodDeclaration(
+            null,
+            null,
+            null,
+            null,
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitMethodDeclaration_external_returnType() {
     _assertSource(
         "external T m();",
-        AstFactory.methodDeclaration(
+        AstTestFactory.methodDeclaration(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList()));
   }
 
   void test_visitMethodDeclaration_getter() {
     _assertSource(
         "get m {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             Keyword.GET,
             null,
-            AstFactory.identifier3("m"),
+            AstTestFactory.identifier3("m"),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_getter_returnType() {
     _assertSource(
         "T get m {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             Keyword.GET,
             null,
-            AstFactory.identifier3("m"),
+            AstTestFactory.identifier3("m"),
             null,
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_getter_seturnType() {
     _assertSource(
         "T set m(var v) {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             Keyword.SET,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter(Keyword.VAR, "v")]),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter(Keyword.VAR, "v")]),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_minimal() {
     _assertSource(
         "m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_multipleParameters() {
     _assertSource(
         "m(var a, var b) {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList([
-              AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-              AstFactory.simpleFormalParameter(Keyword.VAR, "b")
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList([
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+              AstTestFactory.simpleFormalParameter(Keyword.VAR, "b")
             ]),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_operator() {
     _assertSource(
         "operator +() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             null,
             Keyword.OPERATOR,
-            AstFactory.identifier3("+"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("+"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_operator_returnType() {
     _assertSource(
         "T operator +() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             Keyword.OPERATOR,
-            AstFactory.identifier3("+"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("+"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_returnType() {
     _assertSource(
         "T m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_setter() {
     _assertSource(
         "set m(var v) {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             null,
             null,
             Keyword.SET,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(
-                [AstFactory.simpleFormalParameter(Keyword.VAR, "v")]),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter(Keyword.VAR, "v")]),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_static() {
     _assertSource(
         "static m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             Keyword.STATIC,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_static_returnType() {
     _assertSource(
         "static T m() {}",
-        AstFactory.methodDeclaration2(
+        AstTestFactory.methodDeclaration2(
             Keyword.STATIC,
-            AstFactory.typeName4("T"),
+            AstTestFactory.typeName4("T"),
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_typeParameters() {
     _assertSource(
         "m<E>() {}",
-        AstFactory.methodDeclaration3(
+        AstTestFactory.methodDeclaration3(
             null,
             null,
             null,
             null,
-            AstFactory.identifier3("m"),
-            AstFactory.typeParameterList(['E']),
-            AstFactory.formalParameterList(),
-            AstFactory.blockFunctionBody2()));
+            AstTestFactory.identifier3("m"),
+            AstTestFactory.typeParameterList(['E']),
+            AstTestFactory.formalParameterList(),
+            AstTestFactory.blockFunctionBody2()));
   }
 
   void test_visitMethodDeclaration_withMetadata() {
-    MethodDeclaration declaration = AstFactory.methodDeclaration2(
+    MethodDeclaration declaration = AstTestFactory.methodDeclaration2(
         null,
         null,
         null,
         null,
-        AstFactory.identifier3("m"),
-        AstFactory.formalParameterList(),
-        AstFactory.blockFunctionBody2());
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+        AstTestFactory.identifier3("m"),
+        AstTestFactory.formalParameterList(),
+        AstTestFactory.blockFunctionBody2());
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated m() {}", declaration);
   }
 
   void test_visitMethodInvocation_conditional() {
     _assertSource(
         "t?.m()",
-        AstFactory.methodInvocation(
-            AstFactory.identifier3("t"), "m", null, TokenType.QUESTION_PERIOD));
+        AstTestFactory.methodInvocation(AstTestFactory.identifier3("t"), "m",
+            null, TokenType.QUESTION_PERIOD));
   }
 
   void test_visitMethodInvocation_noTarget() {
-    _assertSource("m()", AstFactory.methodInvocation2("m"));
+    _assertSource("m()", AstTestFactory.methodInvocation2("m"));
   }
 
   void test_visitMethodInvocation_target() {
-    _assertSource(
-        "t.m()", AstFactory.methodInvocation(AstFactory.identifier3("t"), "m"));
+    _assertSource("t.m()",
+        AstTestFactory.methodInvocation(AstTestFactory.identifier3("t"), "m"));
   }
 
   void test_visitMethodInvocation_typeArguments() {
     _assertSource(
         "m<A>()",
-        AstFactory.methodInvocation3(null, "m",
-            AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+        AstTestFactory.methodInvocation3(null, "m",
+            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')])));
   }
 
   void test_visitNamedExpression() {
-    _assertSource(
-        "a: b", AstFactory.namedExpression2("a", AstFactory.identifier3("b")));
+    _assertSource("a: b",
+        AstTestFactory.namedExpression2("a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitNamedFormalParameter() {
     _assertSource(
         "var a : 0",
-        AstFactory.namedFormalParameter(
-            AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-            AstFactory.integer(0)));
+        AstTestFactory.namedFormalParameter(
+            AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitNativeClause() {
-    _assertSource("native 'code'", AstFactory.nativeClause("code"));
+    _assertSource("native 'code'", AstTestFactory.nativeClause("code"));
   }
 
   void test_visitNativeFunctionBody() {
-    _assertSource("native 'str';", AstFactory.nativeFunctionBody("str"));
+    _assertSource("native 'str';", AstTestFactory.nativeFunctionBody("str"));
   }
 
   void test_visitNullLiteral() {
-    _assertSource("null", AstFactory.nullLiteral());
+    _assertSource("null", AstTestFactory.nullLiteral());
   }
 
   void test_visitParenthesizedExpression() {
     _assertSource(
-        "(a)", AstFactory.parenthesizedExpression(AstFactory.identifier3("a")));
+        "(a)",
+        AstTestFactory
+            .parenthesizedExpression(AstTestFactory.identifier3("a")));
   }
 
   void test_visitPartDirective() {
-    _assertSource("part 'a.dart';", AstFactory.partDirective2("a.dart"));
+    _assertSource("part 'a.dart';", AstTestFactory.partDirective2("a.dart"));
   }
 
   void test_visitPartDirective_withMetadata() {
-    PartDirective directive = AstFactory.partDirective2("a.dart");
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    PartDirective directive = AstTestFactory.partDirective2("a.dart");
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated part 'a.dart';", directive);
   }
 
   void test_visitPartOfDirective() {
-    _assertSource("part of l;",
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["l"])));
+    _assertSource(
+        "part of l;",
+        AstTestFactory
+            .partOfDirective(AstTestFactory.libraryIdentifier2(["l"])));
   }
 
   void test_visitPartOfDirective_withMetadata() {
-    PartOfDirective directive =
-        AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["l"]));
-    directive.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    PartOfDirective directive = AstTestFactory
+        .partOfDirective(AstTestFactory.libraryIdentifier2(["l"]));
+    directive.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated part of l;", directive);
   }
 
   void test_visitPositionalFormalParameter() {
     _assertSource(
         "var a = 0",
-        AstFactory.positionalFormalParameter(
-            AstFactory.simpleFormalParameter(Keyword.VAR, "a"),
-            AstFactory.integer(0)));
+        AstTestFactory.positionalFormalParameter(
+            AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
+            AstTestFactory.integer(0)));
   }
 
   void test_visitPostfixExpression() {
     _assertSource(
         "a++",
-        AstFactory.postfixExpression(
-            AstFactory.identifier3("a"), TokenType.PLUS_PLUS));
+        AstTestFactory.postfixExpression(
+            AstTestFactory.identifier3("a"), TokenType.PLUS_PLUS));
   }
 
   void test_visitPrefixedIdentifier() {
-    _assertSource("a.b", AstFactory.identifier5("a", "b"));
+    _assertSource("a.b", AstTestFactory.identifier5("a", "b"));
   }
 
   void test_visitPrefixExpression() {
     _assertSource(
         "-a",
-        AstFactory.prefixExpression(
-            TokenType.MINUS, AstFactory.identifier3("a")));
+        AstTestFactory.prefixExpression(
+            TokenType.MINUS, AstTestFactory.identifier3("a")));
   }
 
   void test_visitPropertyAccess() {
-    _assertSource(
-        "a.b", AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b"));
+    _assertSource("a.b",
+        AstTestFactory.propertyAccess2(AstTestFactory.identifier3("a"), "b"));
   }
 
   void test_visitPropertyAccess_conditional() {
     _assertSource(
         "a?.b",
-        AstFactory.propertyAccess2(
-            AstFactory.identifier3("a"), "b", TokenType.QUESTION_PERIOD));
+        AstTestFactory.propertyAccess2(
+            AstTestFactory.identifier3("a"), "b", TokenType.QUESTION_PERIOD));
   }
 
   void test_visitRedirectingConstructorInvocation_named() {
     _assertSource(
-        "this.c()", AstFactory.redirectingConstructorInvocation2("c"));
+        "this.c()", AstTestFactory.redirectingConstructorInvocation2("c"));
   }
 
   void test_visitRedirectingConstructorInvocation_unnamed() {
-    _assertSource("this()", AstFactory.redirectingConstructorInvocation());
+    _assertSource("this()", AstTestFactory.redirectingConstructorInvocation());
   }
 
   void test_visitRethrowExpression() {
-    _assertSource("rethrow", AstFactory.rethrowExpression());
+    _assertSource("rethrow", AstTestFactory.rethrowExpression());
   }
 
   void test_visitReturnStatement_expression() {
-    _assertSource(
-        "return a;", AstFactory.returnStatement2(AstFactory.identifier3("a")));
+    _assertSource("return a;",
+        AstTestFactory.returnStatement2(AstTestFactory.identifier3("a")));
   }
 
   void test_visitReturnStatement_noExpression() {
-    _assertSource("return;", AstFactory.returnStatement());
+    _assertSource("return;", AstTestFactory.returnStatement());
   }
 
   void test_visitScriptTag() {
     String scriptTag = "!#/bin/dart.exe";
-    _assertSource(scriptTag, AstFactory.scriptTag(scriptTag));
+    _assertSource(scriptTag, AstTestFactory.scriptTag(scriptTag));
   }
 
   void test_visitSimpleFormalParameter_annotation() {
-    SimpleFormalParameter parameter = AstFactory.simpleFormalParameter3('x');
-    parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A")));
+    SimpleFormalParameter parameter =
+        AstTestFactory.simpleFormalParameter3('x');
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
     _assertSource('@A x', parameter);
   }
 
   void test_visitSimpleFormalParameter_keyword() {
-    _assertSource("var a", AstFactory.simpleFormalParameter(Keyword.VAR, "a"));
+    _assertSource(
+        "var a", AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"));
   }
 
   void test_visitSimpleFormalParameter_keyword_type() {
     _assertSource(
         "final A a",
-        AstFactory.simpleFormalParameter2(
-            Keyword.FINAL, AstFactory.typeName4("A"), "a"));
+        AstTestFactory.simpleFormalParameter2(
+            Keyword.FINAL, AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitSimpleFormalParameter_type() {
-    _assertSource("A a",
-        AstFactory.simpleFormalParameter4(AstFactory.typeName4("A"), "a"));
+    _assertSource(
+        "A a",
+        AstTestFactory.simpleFormalParameter4(
+            AstTestFactory.typeName4("A"), "a"));
   }
 
   void test_visitSimpleIdentifier() {
-    _assertSource("a", AstFactory.identifier3("a"));
+    _assertSource("a", AstTestFactory.identifier3("a"));
   }
 
   void test_visitSimpleStringLiteral() {
-    _assertSource("'a'", AstFactory.string2("a"));
+    _assertSource("'a'", AstTestFactory.string2("a"));
   }
 
   void test_visitStringInterpolation() {
     _assertSource(
         "'a\${e}b'",
-        AstFactory.string([
-          AstFactory.interpolationString("'a", "a"),
-          AstFactory.interpolationExpression(AstFactory.identifier3("e")),
-          AstFactory.interpolationString("b'", "b")
+        AstTestFactory.string([
+          AstTestFactory.interpolationString("'a", "a"),
+          AstTestFactory
+              .interpolationExpression(AstTestFactory.identifier3("e")),
+          AstTestFactory.interpolationString("b'", "b")
         ]));
   }
 
   void test_visitSuperConstructorInvocation() {
-    _assertSource("super()", AstFactory.superConstructorInvocation());
+    _assertSource("super()", AstTestFactory.superConstructorInvocation());
   }
 
   void test_visitSuperConstructorInvocation_named() {
-    _assertSource("super.c()", AstFactory.superConstructorInvocation2("c"));
+    _assertSource("super.c()", AstTestFactory.superConstructorInvocation2("c"));
   }
 
   void test_visitSuperExpression() {
-    _assertSource("super", AstFactory.superExpression());
+    _assertSource("super", AstTestFactory.superExpression());
   }
 
   void test_visitSwitchCase_multipleLabels() {
     _assertSource(
         "l1: l2: case a: {}",
-        AstFactory.switchCase2(
-            [AstFactory.label2("l1"), AstFactory.label2("l2")],
-            AstFactory.identifier3("a"),
-            [AstFactory.block()]));
+        AstTestFactory.switchCase2(
+            [AstTestFactory.label2("l1"), AstTestFactory.label2("l2")],
+            AstTestFactory.identifier3("a"),
+            [AstTestFactory.block()]));
   }
 
   void test_visitSwitchCase_multipleStatements() {
     _assertSource(
         "case a: {} {}",
-        AstFactory.switchCase(AstFactory.identifier3("a"),
-            [AstFactory.block(), AstFactory.block()]));
+        AstTestFactory.switchCase(AstTestFactory.identifier3("a"),
+            [AstTestFactory.block(), AstTestFactory.block()]));
   }
 
   void test_visitSwitchCase_noLabels() {
     _assertSource(
         "case a: {}",
-        AstFactory
-            .switchCase(AstFactory.identifier3("a"), [AstFactory.block()]));
+        AstTestFactory.switchCase(
+            AstTestFactory.identifier3("a"), [AstTestFactory.block()]));
   }
 
   void test_visitSwitchCase_singleLabel() {
     _assertSource(
         "l1: case a: {}",
-        AstFactory.switchCase2([AstFactory.label2("l1")],
-            AstFactory.identifier3("a"), [AstFactory.block()]));
+        AstTestFactory.switchCase2([AstTestFactory.label2("l1")],
+            AstTestFactory.identifier3("a"), [AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_multipleLabels() {
     _assertSource(
         "l1: l2: default: {}",
-        AstFactory.switchDefault(
-            [AstFactory.label2("l1"), AstFactory.label2("l2")],
-            [AstFactory.block()]));
+        AstTestFactory.switchDefault(
+            [AstTestFactory.label2("l1"), AstTestFactory.label2("l2")],
+            [AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_multipleStatements() {
-    _assertSource("default: {} {}",
-        AstFactory.switchDefault2([AstFactory.block(), AstFactory.block()]));
+    _assertSource(
+        "default: {} {}",
+        AstTestFactory
+            .switchDefault2([AstTestFactory.block(), AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_noLabels() {
     _assertSource(
-        "default: {}", AstFactory.switchDefault2([AstFactory.block()]));
+        "default: {}", AstTestFactory.switchDefault2([AstTestFactory.block()]));
   }
 
   void test_visitSwitchDefault_singleLabel() {
     _assertSource(
         "l1: default: {}",
-        AstFactory
-            .switchDefault([AstFactory.label2("l1")], [AstFactory.block()]));
+        AstTestFactory.switchDefault(
+            [AstTestFactory.label2("l1")], [AstTestFactory.block()]));
   }
 
   void test_visitSwitchStatement() {
     _assertSource(
         "switch (a) {case 'b': {} default: {}}",
-        AstFactory.switchStatement(AstFactory.identifier3("a"), [
-          AstFactory.switchCase(AstFactory.string2("b"), [AstFactory.block()]),
-          AstFactory.switchDefault2([AstFactory.block()])
+        AstTestFactory.switchStatement(AstTestFactory.identifier3("a"), [
+          AstTestFactory.switchCase(
+              AstTestFactory.string2("b"), [AstTestFactory.block()]),
+          AstTestFactory.switchDefault2([AstTestFactory.block()])
         ]));
   }
 
   void test_visitSymbolLiteral_multiple() {
-    _assertSource("#a.b.c", AstFactory.symbolLiteral(["a", "b", "c"]));
+    _assertSource("#a.b.c", AstTestFactory.symbolLiteral(["a", "b", "c"]));
   }
 
   void test_visitSymbolLiteral_single() {
-    _assertSource("#a", AstFactory.symbolLiteral(["a"]));
+    _assertSource("#a", AstTestFactory.symbolLiteral(["a"]));
   }
 
   void test_visitThisExpression() {
-    _assertSource("this", AstFactory.thisExpression());
+    _assertSource("this", AstTestFactory.thisExpression());
   }
 
   void test_visitThrowStatement() {
-    _assertSource(
-        "throw e", AstFactory.throwExpression2(AstFactory.identifier3("e")));
+    _assertSource("throw e",
+        AstTestFactory.throwExpression2(AstTestFactory.identifier3("e")));
   }
 
   void test_visitTopLevelVariableDeclaration_multiple() {
     _assertSource(
         "var a;",
-        AstFactory.topLevelVariableDeclaration2(
-            Keyword.VAR, [AstFactory.variableDeclaration("a")]));
+        AstTestFactory.topLevelVariableDeclaration2(
+            Keyword.VAR, [AstTestFactory.variableDeclaration("a")]));
   }
 
   void test_visitTopLevelVariableDeclaration_single() {
     _assertSource(
         "var a, b;",
-        AstFactory.topLevelVariableDeclaration2(Keyword.VAR, [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.topLevelVariableDeclaration2(Keyword.VAR, [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitTryStatement_catch() {
     _assertSource(
         "try {} on E {}",
-        AstFactory.tryStatement2(AstFactory.block(),
-            [AstFactory.catchClause3(AstFactory.typeName4("E"))]));
+        AstTestFactory.tryStatement2(AstTestFactory.block(),
+            [AstTestFactory.catchClause3(AstTestFactory.typeName4("E"))]));
   }
 
   void test_visitTryStatement_catches() {
     _assertSource(
         "try {} on E {} on F {}",
-        AstFactory.tryStatement2(AstFactory.block(), [
-          AstFactory.catchClause3(AstFactory.typeName4("E")),
-          AstFactory.catchClause3(AstFactory.typeName4("F"))
+        AstTestFactory.tryStatement2(AstTestFactory.block(), [
+          AstTestFactory.catchClause3(AstTestFactory.typeName4("E")),
+          AstTestFactory.catchClause3(AstTestFactory.typeName4("F"))
         ]));
   }
 
   void test_visitTryStatement_catchFinally() {
     _assertSource(
         "try {} on E {} finally {}",
-        AstFactory.tryStatement3(
-            AstFactory.block(),
-            [AstFactory.catchClause3(AstFactory.typeName4("E"))],
-            AstFactory.block()));
+        AstTestFactory.tryStatement3(
+            AstTestFactory.block(),
+            [AstTestFactory.catchClause3(AstTestFactory.typeName4("E"))],
+            AstTestFactory.block()));
   }
 
   void test_visitTryStatement_finally() {
-    _assertSource("try {} finally {}",
-        AstFactory.tryStatement(AstFactory.block(), AstFactory.block()));
+    _assertSource(
+        "try {} finally {}",
+        AstTestFactory.tryStatement(
+            AstTestFactory.block(), AstTestFactory.block()));
   }
 
   void test_visitTypeArgumentList_multiple() {
     _assertSource(
         "<E, F>",
-        AstFactory.typeArgumentList(
-            [AstFactory.typeName4("E"), AstFactory.typeName4("F")]));
+        AstTestFactory.typeArgumentList(
+            [AstTestFactory.typeName4("E"), AstTestFactory.typeName4("F")]));
   }
 
   void test_visitTypeArgumentList_single() {
-    _assertSource(
-        "<E>", AstFactory.typeArgumentList([AstFactory.typeName4("E")]));
+    _assertSource("<E>",
+        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("E")]));
   }
 
   void test_visitTypeName_multipleArgs() {
     _assertSource(
         "C<D, E>",
-        AstFactory.typeName4(
-            "C", [AstFactory.typeName4("D"), AstFactory.typeName4("E")]));
+        AstTestFactory.typeName4("C",
+            [AstTestFactory.typeName4("D"), AstTestFactory.typeName4("E")]));
   }
 
   void test_visitTypeName_nestedArg() {
     _assertSource(
         "C<D<E>>",
-        AstFactory.typeName4("C", [
-          AstFactory.typeName4("D", [AstFactory.typeName4("E")])
+        AstTestFactory.typeName4("C", [
+          AstTestFactory.typeName4("D", [AstTestFactory.typeName4("E")])
         ]));
   }
 
   void test_visitTypeName_noArgs() {
-    _assertSource("C", AstFactory.typeName4("C"));
+    _assertSource("C", AstTestFactory.typeName4("C"));
   }
 
   void test_visitTypeName_singleArg() {
     _assertSource(
-        "C<D>", AstFactory.typeName4("C", [AstFactory.typeName4("D")]));
+        "C<D>", AstTestFactory.typeName4("C", [AstTestFactory.typeName4("D")]));
   }
 
   void test_visitTypeParameter_withExtends() {
     _assertSource("E extends C",
-        AstFactory.typeParameter2("E", AstFactory.typeName4("C")));
+        AstTestFactory.typeParameter2("E", AstTestFactory.typeName4("C")));
   }
 
   void test_visitTypeParameter_withMetadata() {
-    TypeParameter parameter = AstFactory.typeParameter("E");
-    parameter.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    TypeParameter parameter = AstTestFactory.typeParameter("E");
+    parameter.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated E", parameter);
   }
 
   void test_visitTypeParameter_withoutExtends() {
-    _assertSource("E", AstFactory.typeParameter("E"));
+    _assertSource("E", AstTestFactory.typeParameter("E"));
   }
 
   void test_visitTypeParameterList_multiple() {
-    _assertSource("<E, F>", AstFactory.typeParameterList(["E", "F"]));
+    _assertSource("<E, F>", AstTestFactory.typeParameterList(["E", "F"]));
   }
 
   void test_visitTypeParameterList_single() {
-    _assertSource("<E>", AstFactory.typeParameterList(["E"]));
+    _assertSource("<E>", AstTestFactory.typeParameterList(["E"]));
   }
 
   void test_visitVariableDeclaration_initialized() {
-    _assertSource("a = b",
-        AstFactory.variableDeclaration2("a", AstFactory.identifier3("b")));
+    _assertSource(
+        "a = b",
+        AstTestFactory.variableDeclaration2(
+            "a", AstTestFactory.identifier3("b")));
   }
 
   void test_visitVariableDeclaration_uninitialized() {
-    _assertSource("a", AstFactory.variableDeclaration("a"));
+    _assertSource("a", AstTestFactory.variableDeclaration("a"));
   }
 
   void test_visitVariableDeclaration_withMetadata() {
-    VariableDeclaration declaration = AstFactory.variableDeclaration("a");
-    declaration.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    VariableDeclaration declaration = AstTestFactory.variableDeclaration("a");
+    declaration.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated a", declaration);
   }
 
   void test_visitVariableDeclarationList_const_type() {
     _assertSource(
         "const C a, b",
-        AstFactory.variableDeclarationList(
-            Keyword.CONST, AstFactory.typeName4("C"), [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList(
+            Keyword.CONST, AstTestFactory.typeName4("C"), [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationList_final_noType() {
     _assertSource(
         "final a, b",
-        AstFactory.variableDeclarationList2(Keyword.FINAL, [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList2(Keyword.FINAL, [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationList_final_withMetadata() {
-    VariableDeclarationList declarationList = AstFactory
+    VariableDeclarationList declarationList = AstTestFactory
         .variableDeclarationList2(Keyword.FINAL, [
-      AstFactory.variableDeclaration("a"),
-      AstFactory.variableDeclaration("b")
+      AstTestFactory.variableDeclaration("a"),
+      AstTestFactory.variableDeclaration("b")
     ]);
-    declarationList.metadata
-        .add(AstFactory.annotation(AstFactory.identifier3("deprecated")));
+    declarationList.metadata.add(
+        AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
     _assertSource("@deprecated final a, b", declarationList);
   }
 
   void test_visitVariableDeclarationList_type() {
     _assertSource(
         "C a, b",
-        AstFactory.variableDeclarationList(null, AstFactory.typeName4("C"), [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList(
+            null, AstTestFactory.typeName4("C"), [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationList_var() {
     _assertSource(
         "var a, b",
-        AstFactory.variableDeclarationList2(Keyword.VAR, [
-          AstFactory.variableDeclaration("a"),
-          AstFactory.variableDeclaration("b")
+        AstTestFactory.variableDeclarationList2(Keyword.VAR, [
+          AstTestFactory.variableDeclaration("a"),
+          AstTestFactory.variableDeclaration("b")
         ]));
   }
 
   void test_visitVariableDeclarationStatement() {
     _assertSource(
         "C c;",
-        AstFactory.variableDeclarationStatement(null, AstFactory.typeName4("C"),
-            [AstFactory.variableDeclaration("c")]));
+        AstTestFactory.variableDeclarationStatement(
+            null,
+            AstTestFactory.typeName4("C"),
+            [AstTestFactory.variableDeclaration("c")]));
   }
 
   void test_visitWhileStatement() {
     _assertSource(
         "while (c) {}",
-        AstFactory.whileStatement(
-            AstFactory.identifier3("c"), AstFactory.block()));
+        AstTestFactory.whileStatement(
+            AstTestFactory.identifier3("c"), AstTestFactory.block()));
   }
 
   void test_visitWithClause_multiple() {
     _assertSource(
         "with A, B, C",
-        AstFactory.withClause([
-          AstFactory.typeName4("A"),
-          AstFactory.typeName4("B"),
-          AstFactory.typeName4("C")
+        AstTestFactory.withClause([
+          AstTestFactory.typeName4("A"),
+          AstTestFactory.typeName4("B"),
+          AstTestFactory.typeName4("C")
         ]));
   }
 
   void test_visitWithClause_single() {
-    _assertSource("with A", AstFactory.withClause([AstFactory.typeName4("A")]));
+    _assertSource(
+        "with A", AstTestFactory.withClause([AstTestFactory.typeName4("A")]));
   }
 
   void test_visitYieldStatement() {
-    _assertSource(
-        "yield e;", AstFactory.yieldStatement(AstFactory.identifier3("e")));
+    _assertSource("yield e;",
+        AstTestFactory.yieldStatement(AstTestFactory.identifier3("e")));
   }
 
   void test_visitYieldStatement_each() {
     _assertSource("yield* e;",
-        AstFactory.yieldEachStatement(AstFactory.identifier3("e")));
+        AstTestFactory.yieldEachStatement(AstTestFactory.identifier3("e")));
   }
 
   /**
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 47ed912..43dfdf7 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -17,7 +17,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:path/path.dart';
@@ -1407,10 +1407,10 @@
 @reflectiveTest
 class ConstantVisitorTest extends ResolverTestCase {
   void test_visitBinaryExpression_questionQuestion_notNull_notNull() {
-    Expression left = AstFactory.string2('a');
-    Expression right = AstFactory.string2('b');
-    Expression expression =
-        AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
+    Expression left = AstTestFactory.string2('a');
+    Expression right = AstTestFactory.string2('b');
+    Expression expression = AstTestFactory.binaryExpression(
+        left, TokenType.QUESTION_QUESTION, right);
 
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
@@ -1423,10 +1423,10 @@
   }
 
   void test_visitBinaryExpression_questionQuestion_null_notNull() {
-    Expression left = AstFactory.nullLiteral();
-    Expression right = AstFactory.string2('b');
-    Expression expression =
-        AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
+    Expression left = AstTestFactory.nullLiteral();
+    Expression right = AstTestFactory.string2('b');
+    Expression expression = AstTestFactory.binaryExpression(
+        left, TokenType.QUESTION_QUESTION, right);
 
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
@@ -1439,10 +1439,10 @@
   }
 
   void test_visitBinaryExpression_questionQuestion_null_null() {
-    Expression left = AstFactory.nullLiteral();
-    Expression right = AstFactory.nullLiteral();
-    Expression expression =
-        AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
+    Expression left = AstTestFactory.nullLiteral();
+    Expression right = AstTestFactory.nullLiteral();
+    Expression expression = AstTestFactory.binaryExpression(
+        left, TokenType.QUESTION_QUESTION, right);
 
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
@@ -1454,10 +1454,10 @@
   }
 
   void test_visitConditionalExpression_false() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.integer(0);
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(false), thenExpression, elseExpression);
+    Expression thenExpression = AstTestFactory.integer(1);
+    Expression elseExpression = AstTestFactory.integer(0);
+    ConditionalExpression expression = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(false), thenExpression, elseExpression);
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
         new ErrorReporter(errorListener, _dummySource());
@@ -1466,10 +1466,10 @@
   }
 
   void test_visitConditionalExpression_nonBooleanCondition() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.integer(0);
-    NullLiteral conditionExpression = AstFactory.nullLiteral();
-    ConditionalExpression expression = AstFactory.conditionalExpression(
+    Expression thenExpression = AstTestFactory.integer(1);
+    Expression elseExpression = AstTestFactory.integer(0);
+    NullLiteral conditionExpression = AstTestFactory.nullLiteral();
+    ConditionalExpression expression = AstTestFactory.conditionalExpression(
         conditionExpression, thenExpression, elseExpression);
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
@@ -1481,10 +1481,10 @@
   }
 
   void test_visitConditionalExpression_nonConstantElse() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.identifier3("x");
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+    Expression thenExpression = AstTestFactory.integer(1);
+    Expression elseExpression = AstTestFactory.identifier3("x");
+    ConditionalExpression expression = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
         new ErrorReporter(errorListener, _dummySource());
@@ -1495,10 +1495,10 @@
   }
 
   void test_visitConditionalExpression_nonConstantThen() {
-    Expression thenExpression = AstFactory.identifier3("x");
-    Expression elseExpression = AstFactory.integer(0);
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+    Expression thenExpression = AstTestFactory.identifier3("x");
+    Expression elseExpression = AstTestFactory.integer(0);
+    ConditionalExpression expression = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
         new ErrorReporter(errorListener, _dummySource());
@@ -1509,10 +1509,10 @@
   }
 
   void test_visitConditionalExpression_true() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.integer(0);
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+    Expression thenExpression = AstTestFactory.integer(1);
+    Expression elseExpression = AstTestFactory.integer(0);
+    ConditionalExpression expression = AstTestFactory.conditionalExpression(
+        AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
     GatheringErrorListener errorListener = new GatheringErrorListener();
     ErrorReporter errorReporter =
         new ErrorReporter(errorListener, _dummySource());
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index b2e83e5..9920600 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -14,7 +14,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -56,17 +56,17 @@
         compilationUnitElement;
     ElementAnnotationImpl elementAnnotation =
         new ElementAnnotationImpl(compilationUnitElement);
-    _node = elementAnnotation.annotationAst = AstFactory.annotation(
-        AstFactory.identifier3('x'))..elementAnnotation = elementAnnotation;
+    _node = elementAnnotation.annotationAst = AstTestFactory.annotation(
+        AstTestFactory.identifier3('x'))..elementAnnotation = elementAnnotation;
     expect(_findAnnotations(), contains(_node));
   }
 
   void test_visitAnnotation_enumConstant() {
     // Analyzer ignores annotations on enum constant declarations.
-    Annotation annotation = AstFactory.annotation2(
-        AstFactory.identifier3('A'), null, AstFactory.argumentList());
+    Annotation annotation = AstTestFactory.annotation2(
+        AstTestFactory.identifier3('A'), null, AstTestFactory.argumentList());
     _node = new EnumConstantDeclaration(
-        null, <Annotation>[annotation], AstFactory.identifier3('C'));
+        null, <Annotation>[annotation], AstTestFactory.identifier3('C'));
     expect(_findConstants(), isEmpty);
   }
 
@@ -81,18 +81,18 @@
         compilationUnitElement;
     ElementAnnotationImpl elementAnnotation =
         new ElementAnnotationImpl(compilationUnitElement);
-    _node = elementAnnotation.annotationAst = AstFactory.annotation2(
-        AstFactory.identifier3('A'), null, AstFactory.argumentList())
+    _node = elementAnnotation.annotationAst = AstTestFactory.annotation2(
+        AstTestFactory.identifier3('A'), null, AstTestFactory.argumentList())
       ..elementAnnotation = elementAnnotation;
     expect(_findAnnotations(), contains(_node));
   }
 
   void test_visitAnnotation_partOf() {
     // Analyzer ignores annotations on "part of" directives.
-    Annotation annotation = AstFactory.annotation2(
-        AstFactory.identifier3('A'), null, AstFactory.argumentList());
-    _node = AstFactory.partOfDirective2(
-        <Annotation>[annotation], AstFactory.libraryIdentifier2(<String>['L']));
+    Annotation annotation = AstTestFactory.annotation2(
+        AstTestFactory.identifier3('A'), null, AstTestFactory.argumentList());
+    _node = AstTestFactory.partOfDirective2(<Annotation>[annotation],
+        AstTestFactory.libraryIdentifier2(<String>['L']));
     expect(_findConstants(), isEmpty);
   }
 
@@ -193,14 +193,14 @@
   ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
     Keyword constKeyword = isConst ? Keyword.CONST : null;
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration2(
+        AstTestFactory.constructorDeclaration2(
             constKeyword,
             null,
             null,
             name,
-            AstFactory.formalParameterList(),
+            AstTestFactory.formalParameterList(),
             null,
-            AstFactory.blockFunctionBody2());
+            AstTestFactory.blockFunctionBody2());
     ClassElement classElement = ElementFactory.classElement2(name);
     ConstructorElement element =
         ElementFactory.constructorElement(classElement, name, isConst);
@@ -215,8 +215,9 @@
       bool isStatic: false,
       bool hasConstConstructor: false}) {
     VariableDeclaration variableDeclaration = isInitialized
-        ? AstFactory.variableDeclaration2(fieldName, AstFactory.integer(0))
-        : AstFactory.variableDeclaration(fieldName);
+        ? AstTestFactory.variableDeclaration2(
+            fieldName, AstTestFactory.integer(0))
+        : AstTestFactory.variableDeclaration(fieldName);
     VariableElement fieldElement = ElementFactory.fieldElement(
         fieldName,
         isStatic,
@@ -224,10 +225,10 @@
         keyword == Keyword.CONST,
         _typeProvider.intType);
     variableDeclaration.name.staticElement = fieldElement;
-    FieldDeclaration fieldDeclaration = AstFactory.fieldDeclaration2(
+    FieldDeclaration fieldDeclaration = AstTestFactory.fieldDeclaration2(
         isStatic, keyword, <VariableDeclaration>[variableDeclaration]);
-    ClassDeclaration classDeclaration =
-        AstFactory.classDeclaration(null, className, null, null, null, null);
+    ClassDeclaration classDeclaration = AstTestFactory.classDeclaration(
+        null, className, null, null, null, null);
     classDeclaration.members.add(fieldDeclaration);
     _node = classDeclaration;
     ClassElementImpl classElement = ElementFactory.classElement2(className);
@@ -235,14 +236,14 @@
     classDeclaration.name.staticElement = classElement;
     if (hasConstConstructor) {
       ConstructorDeclaration constructorDeclaration =
-          AstFactory.constructorDeclaration2(
+          AstTestFactory.constructorDeclaration2(
               Keyword.CONST,
               null,
-              AstFactory.identifier3(className),
+              AstTestFactory.identifier3(className),
               null,
-              AstFactory.formalParameterList(),
+              AstTestFactory.formalParameterList(),
               null,
-              AstFactory.blockFunctionBody2());
+              AstTestFactory.blockFunctionBody2());
       classDeclaration.members.add(constructorDeclaration);
       ConstructorElement constructorElement =
           ElementFactory.constructorElement(classElement, '', true);
@@ -258,13 +259,13 @@
       String name, bool isConst, bool isInitialized,
       {isFinal: false}) {
     VariableDeclaration variableDeclaration = isInitialized
-        ? AstFactory.variableDeclaration2(name, AstFactory.integer(0))
-        : AstFactory.variableDeclaration(name);
+        ? AstTestFactory.variableDeclaration2(name, AstTestFactory.integer(0))
+        : AstTestFactory.variableDeclaration(name);
     SimpleIdentifier identifier = variableDeclaration.name;
     VariableElement element = ElementFactory.localVariableElement(identifier);
     identifier.staticElement = element;
     Keyword keyword = isConst ? Keyword.CONST : isFinal ? Keyword.FINAL : null;
-    AstFactory.variableDeclarationList2(keyword, [variableDeclaration]);
+    AstTestFactory.variableDeclarationList2(keyword, [variableDeclaration]);
     _node = variableDeclaration;
     return element;
   }
@@ -298,7 +299,7 @@
 
   void test_visitSuperConstructorInvocation_unresolved() {
     SuperConstructorInvocation superConstructorInvocation =
-        AstFactory.superConstructorInvocation();
+        AstTestFactory.superConstructorInvocation();
     _visitNode(superConstructorInvocation);
     _assertNoArcs();
   }
@@ -323,14 +324,14 @@
     List<ConstructorInitializer> initializers =
         new List<ConstructorInitializer>();
     ConstructorDeclaration constructorDeclaration =
-        AstFactory.constructorDeclaration(AstFactory.identifier3(name), null,
-            AstFactory.formalParameterList(), initializers);
+        AstTestFactory.constructorDeclaration(AstTestFactory.identifier3(name),
+            null, AstTestFactory.formalParameterList(), initializers);
     if (isConst) {
       constructorDeclaration.constKeyword = new KeywordToken(Keyword.CONST, 0);
     }
     ClassElementImpl classElement = ElementFactory.classElement2(name);
     SuperConstructorInvocation superConstructorInvocation =
-        AstFactory.superConstructorInvocation();
+        AstTestFactory.superConstructorInvocation();
     ConstructorElementImpl constructorElement =
         ElementFactory.constructorElement(classElement, name, isConst);
     _tail = constructorElement;
@@ -340,14 +341,14 @@
 
   SimpleIdentifier _makeTailVariable(String name, bool isConst) {
     VariableDeclaration variableDeclaration =
-        AstFactory.variableDeclaration(name);
+        AstTestFactory.variableDeclaration(name);
     ConstLocalVariableElementImpl variableElement =
         ElementFactory.constLocalVariableElement(name);
     _tail = variableElement;
     variableElement.isConst = isConst;
-    AstFactory.variableDeclarationList2(
+    AstTestFactory.variableDeclarationList2(
         isConst ? Keyword.CONST : Keyword.VAR, [variableDeclaration]);
-    SimpleIdentifier identifier = AstFactory.identifier3(name);
+    SimpleIdentifier identifier = AstTestFactory.identifier3(name);
     identifier.staticElement = variableElement;
     return identifier;
   }
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index f659b07..5c691e3 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -14,7 +14,7 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:test/test.dart';
@@ -1329,7 +1329,7 @@
   void test_creation() {
     expect(
         new FunctionTypeImpl(
-            new FunctionElementImpl.forNode(AstFactory.identifier3("f"))),
+            new FunctionElementImpl.forNode(AstTestFactory.identifier3("f"))),
         isNotNull);
   }
 
@@ -1353,7 +1353,7 @@
 
   void test_getElement() {
     FunctionElementImpl typeElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("f"));
     FunctionTypeImpl type = new FunctionTypeImpl(typeElement);
     expect(type.element, typeElement);
   }
@@ -1465,7 +1465,7 @@
   void test_getReturnType() {
     DartType expectedReturnType = VoidTypeImpl.instance;
     FunctionElementImpl functionElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("f"));
     functionElement.returnType = expectedReturnType;
     FunctionTypeImpl type = new FunctionTypeImpl(functionElement);
     DartType returnType = type.returnType;
@@ -1474,14 +1474,14 @@
 
   void test_getTypeArguments() {
     FunctionTypeImpl type = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("f")));
     List<DartType> types = type.typeArguments;
     expect(types, hasLength(0));
   }
 
   void test_hashCode_element() {
     FunctionTypeImpl type = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("f")));
     type.hashCode;
   }
 
@@ -1841,15 +1841,15 @@
     InterfaceType boolType = provider.boolType;
     InterfaceType stringType = provider.stringType;
     TypeParameterElementImpl parameterB =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("B"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("B"));
     parameterB.bound = boolType;
     TypeParameterTypeImpl typeB = new TypeParameterTypeImpl(parameterB);
     TypeParameterElementImpl parameterS =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("S"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("S"));
     parameterS.bound = stringType;
     TypeParameterTypeImpl typeS = new TypeParameterTypeImpl(parameterS);
     FunctionElementImpl functionAliasElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("func"));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("func"));
     functionAliasElement.parameters = <ParameterElement>[
       ElementFactory.requiredParameter2("a", typeB),
       ElementFactory.positionalParameter2("b", typeS)
@@ -1859,7 +1859,7 @@
         new FunctionTypeImpl(functionAliasElement);
     functionAliasElement.type = functionAliasType;
     FunctionElementImpl functionElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("f"));
     functionElement.parameters = <ParameterElement>[
       ElementFactory.requiredParameter2("c", boolType),
       ElementFactory.positionalParameter2("d", stringType)
@@ -2041,7 +2041,7 @@
     ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
     TypeParameterType parameterType = definingClass.typeParameters[0].type;
     MethodElementImpl functionElement =
-        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
+        new MethodElementImpl.forNode(AstTestFactory.identifier3("m"));
     String namedParameterName = "c";
     functionElement.parameters = <ParameterElement>[
       ElementFactory.requiredParameter2("a", parameterType),
@@ -2052,7 +2052,7 @@
     definingClass.methods = <MethodElement>[functionElement];
     FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
     InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("D")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("D")));
     FunctionType result = functionType
         .substitute2(<DartType>[argumentType], <DartType>[parameterType]);
     expect(result.returnType, argumentType);
@@ -2069,15 +2069,15 @@
 
   void test_substitute2_notEqual() {
     DartType returnType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("R")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("R")));
     DartType normalParameterType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("A")));
     DartType optionalParameterType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("B")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("B")));
     DartType namedParameterType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("C")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("C")));
     FunctionElementImpl functionElement =
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
+        new FunctionElementImpl.forNode(AstTestFactory.identifier3("f"));
     String namedParameterName = "c";
     functionElement.parameters = <ParameterElement>[
       ElementFactory.requiredParameter2("a", normalParameterType),
@@ -2087,9 +2087,9 @@
     functionElement.returnType = returnType;
     FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
     InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("D")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("D")));
     TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E")));
     FunctionType result = functionType
         .substitute2(<DartType>[argumentType], <DartType>[parameterType]);
     expect(result.returnType, returnType);
@@ -2251,7 +2251,7 @@
   void test_withTypeArguments() {
     ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
     MethodElementImpl methodElement =
-        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
+        new MethodElementImpl.forNode(AstTestFactory.identifier3("m"));
     enclosingClass.methods = <MethodElement>[methodElement];
     FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
     DartType expectedType = enclosingClass.typeParameters[0].type;
@@ -3180,7 +3180,7 @@
     InterfaceType typeA = classA.type;
     ClassElementImpl classB = ElementFactory.classElement2("B");
     TypeParameterElementImpl parameterEA =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     TypeParameterType parameterAEType = new TypeParameterTypeImpl(parameterEA);
     parameterEA.bound = typeA;
     parameterEA.type = parameterAEType;
@@ -3782,14 +3782,14 @@
     // implementation.
     ClassElementImpl classA = ElementFactory.classElement2("A");
     TypeParameterElementImpl parameterElement =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
     TypeParameterTypeImpl parameter =
         new TypeParameterTypeImpl(parameterElement);
     type.typeArguments = <DartType>[parameter];
     InterfaceType argumentType = ElementFactory.classElement2("B").type;
     TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("F")));
     InterfaceType result =
         type.substitute2(<DartType>[argumentType], <DartType>[parameterType]);
     expect(result.element, classA);
@@ -3804,7 +3804,7 @@
   void test_creation() {
     expect(
         new LibraryElementImpl.forNode(
-            createAnalysisContext(), AstFactory.libraryIdentifier2(["l"])),
+            createAnalysisContext(), AstTestFactory.libraryIdentifier2(["l"])),
         isNotNull);
   }
 
@@ -3815,9 +3815,9 @@
     LibraryElementImpl library3 = ElementFactory.library(context, "l3");
     LibraryElementImpl library4 = ElementFactory.library(context, "l4");
     PrefixElement prefixA =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
+        new PrefixElementImpl.forNode(AstTestFactory.identifier3("a"));
     PrefixElement prefixB =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
+        new PrefixElementImpl.forNode(AstTestFactory.identifier3("b"));
     List<ImportElementImpl> imports = [
       ElementFactory.importFor(library2, null),
       ElementFactory.importFor(library2, prefixB),
@@ -3836,9 +3836,9 @@
     AnalysisContext context = createAnalysisContext();
     LibraryElementImpl library = ElementFactory.library(context, "l1");
     PrefixElement prefixA =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
+        new PrefixElementImpl.forNode(AstTestFactory.identifier3("a"));
     PrefixElement prefixB =
-        new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
+        new PrefixElementImpl.forNode(AstTestFactory.identifier3("b"));
     List<ImportElementImpl> imports = [
       ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
       ElementFactory.importFor(ElementFactory.library(context, "l3"), null),
@@ -3891,7 +3891,7 @@
   void test_setImports() {
     AnalysisContext context = createAnalysisContext();
     LibraryElementImpl library = new LibraryElementImpl.forNode(
-        context, AstFactory.libraryIdentifier2(["l1"]));
+        context, AstTestFactory.libraryIdentifier2(["l1"]));
     List<ImportElementImpl> expectedImports = [
       ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
       ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
@@ -4247,21 +4247,21 @@
 class TypeParameterTypeImplTest extends EngineTestCase {
   void test_creation() {
     expect(
-        new TypeParameterTypeImpl(
-            new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))),
+        new TypeParameterTypeImpl(new TypeParameterElementImpl.forNode(
+            AstTestFactory.identifier3("E"))),
         isNotNull);
   }
 
   void test_getElement() {
     TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
     expect(type.element, element);
   }
 
   void test_isMoreSpecificThan_typeArguments_dynamic() {
     TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
     // E << dynamic
     expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
@@ -4269,7 +4269,7 @@
 
   void test_isMoreSpecificThan_typeArguments_object() {
     TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
     // E << Object
     expect(type.isMoreSpecificThan(ElementFactory.object.type), isTrue);
@@ -4278,11 +4278,11 @@
   void test_isMoreSpecificThan_typeArguments_recursive() {
     ClassElementImpl classS = ElementFactory.classElement2("A");
     TypeParameterElementImpl typeParameterU =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("U"));
     TypeParameterTypeImpl typeParameterTypeU =
         new TypeParameterTypeImpl(typeParameterU);
     TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("T"));
     TypeParameterTypeImpl typeParameterTypeT =
         new TypeParameterTypeImpl(typeParameterT);
     typeParameterT.bound = typeParameterTypeU;
@@ -4294,7 +4294,7 @@
 
   void test_isMoreSpecificThan_typeArguments_self() {
     TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
     // E << E
     expect(type.isMoreSpecificThan(type), isTrue);
@@ -4309,7 +4309,7 @@
     InterfaceType typeA = classA.type;
     InterfaceType typeB = classB.type;
     TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("T"));
     typeParameterT.bound = typeB;
     TypeParameterTypeImpl typeParameterTypeT =
         new TypeParameterTypeImpl(typeParameterT);
@@ -4321,12 +4321,12 @@
   void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() {
     ClassElementImpl classS = ElementFactory.classElement2("A");
     TypeParameterElementImpl typeParameterU =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("U"));
     typeParameterU.bound = classS.type;
     TypeParameterTypeImpl typeParameterTypeU =
         new TypeParameterTypeImpl(typeParameterU);
     TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("T"));
     typeParameterT.bound = typeParameterTypeU;
     TypeParameterTypeImpl typeParameterTypeT =
         new TypeParameterTypeImpl(typeParameterT);
@@ -4338,7 +4338,7 @@
   void test_isMoreSpecificThan_typeArguments_upperBound() {
     ClassElementImpl classS = ElementFactory.classElement2("A");
     TypeParameterElementImpl typeParameterT =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("T"));
     typeParameterT.bound = classS.type;
     TypeParameterTypeImpl typeParameterTypeT =
         new TypeParameterTypeImpl(typeParameterT);
@@ -4350,7 +4350,7 @@
   void test_resolveToBound_bound() {
     ClassElementImpl classS = ElementFactory.classElement2("A");
     TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     element.bound = classS.type;
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
     expect(type.resolveToBound(null), same(classS.type));
@@ -4359,11 +4359,11 @@
   void test_resolveToBound_nestedBound() {
     ClassElementImpl classS = ElementFactory.classElement2("A");
     TypeParameterElementImpl elementE =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     elementE.bound = classS.type;
     TypeParameterTypeImpl typeE = new TypeParameterTypeImpl(elementE);
     TypeParameterElementImpl elementF =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("F"));
     elementF.bound = typeE;
     TypeParameterTypeImpl typeF = new TypeParameterTypeImpl(elementE);
     expect(typeF.resolveToBound(null), same(classS.type));
@@ -4371,7 +4371,7 @@
 
   void test_resolveToBound_unbound() {
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E")));
     // Returns whatever type is passed to resolveToBound().
     expect(type.resolveToBound(VoidTypeImpl.instance),
         same(VoidTypeImpl.instance));
@@ -4379,10 +4379,10 @@
 
   void test_substitute_equal() {
     TypeParameterElementImpl element =
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
     InterfaceTypeImpl argument = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("A")));
     TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(element);
     expect(type.substitute2(<DartType>[argument], <DartType>[parameter]),
         same(argument));
@@ -4390,11 +4390,11 @@
 
   void test_substitute_notEqual() {
     TypeParameterTypeImpl type = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E")));
     InterfaceTypeImpl argument = new InterfaceTypeImpl(
-        new ClassElementImpl.forNode(AstFactory.identifier3("A")));
+        new ClassElementImpl.forNode(AstTestFactory.identifier3("A")));
     TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(
-        new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
+        new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("F")));
     expect(type.substitute2(<DartType>[argument], <DartType>[parameter]),
         same(type));
   }
diff --git a/pkg/analyzer/test/src/summary/in_summary_source_test.dart b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
index 91e662a..473d7e2 100644
--- a/pkg/analyzer/test/src/summary/in_summary_source_test.dart
+++ b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:path/path.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -21,23 +20,6 @@
 
 @reflectiveTest
 class InSummarySourceTest extends ReflectiveTest {
-  test_fallbackPath() {
-    String fooFallbackPath = absolute('path', 'to', 'foo.dart');
-    var sourceFactory = new SourceFactory([
-      new InSummaryUriResolver(
-          PhysicalResourceProvider.INSTANCE,
-          new MockSummaryDataStore.fake({
-            'package:foo/foo.dart': 'foo.sum',
-          }, uriToFallbackModePath: {
-            'package:foo/foo.dart': fooFallbackPath
-          }))
-    ]);
-
-    InSummarySource source = sourceFactory.forUri('package:foo/foo.dart');
-    expect(source, isNotNull);
-    expect(source.fullName, fooFallbackPath);
-  }
-
   test_InSummarySource() {
     var sourceFactory = new SourceFactory([
       new InSummaryUriResolver(
@@ -70,14 +52,12 @@
 
   MockSummaryDataStore(this.linkedMap, this.unlinkedMap, this.uriToSummaryPath);
 
-  factory MockSummaryDataStore.fake(Map<String, String> uriToSummary,
-      {Map<String, String> uriToFallbackModePath: const {}}) {
+  factory MockSummaryDataStore.fake(Map<String, String> uriToSummary) {
     // Create fake unlinked map.
     // We don't populate the values as it is not needed for the test.
     var unlinkedMap = new Map<String, UnlinkedUnit>.fromIterable(
         uriToSummary.keys,
-        value: (uri) => new UnlinkedUnitBuilder(
-            fallbackModePath: uriToFallbackModePath[uri]));
+        value: (uri) => new UnlinkedUnitBuilder());
     return new MockSummaryDataStore(null, unlinkedMap, uriToSummary);
   }
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 804e845..29e30d3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptionsImpl;
@@ -71,9 +72,8 @@
   DartSdk createDartSdk() => AbstractContextTest.SHARED_STRONG_MOCK_SDK;
 
   @override
-  AnalysisOptionsImpl createOptions() => new AnalysisOptionsImpl()
-    ..enableGenericMethods = true
-    ..strongMode = true;
+  AnalysisOptionsImpl createOptions() =>
+      new AnalysisOptionsImpl()..strongMode = true;
 
   @override
   @failingTest
@@ -619,6 +619,14 @@
   @override
   @failingTest
   void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2_comment() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2_comment();
+  }
+
+  @override
+  @failingTest
+  void
       test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2() {
     super
         .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2();
@@ -626,6 +634,14 @@
 
   @override
   @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2_comment() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2_comment();
+  }
+
+  @override
+  @failingTest
   void test_unsafeBlockClosureInference_functionCall_implicitTypeParam() {
     super.test_unsafeBlockClosureInference_functionCall_implicitTypeParam();
   }
@@ -633,6 +649,14 @@
   @override
   @failingTest
   void
+      test_unsafeBlockClosureInference_functionCall_implicitTypeParam_comment() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_implicitTypeParam_comment();
+  }
+
+  @override
+  @failingTest
+  void
       test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr() {
     super
         .test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr();
@@ -640,6 +664,14 @@
 
   @override
   @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr_comment() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr_comment();
+  }
+
+  @override
+  @failingTest
   void test_unsafeBlockClosureInference_functionCall_noTypeParam_viaExpr() {
     super.test_unsafeBlockClosureInference_functionCall_noTypeParam_viaExpr();
   }
@@ -662,6 +694,13 @@
     super.test_unsafeBlockClosureInference_methodCall_implicitTypeParam();
   }
 
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_methodCall_implicitTypeParam_comment() {
+    super
+        .test_unsafeBlockClosureInference_methodCall_implicitTypeParam_comment();
+  }
+
   LibraryElementImpl _checkSource(
       SummaryResynthesizer resynthesizer, Source source) {
     LibraryElementImpl resynthesized =
@@ -882,6 +921,12 @@
     Source source = addTestSource(text);
     LibraryElementImpl resynthesized = _encodeDecodeLibraryElement(source);
     LibraryElementImpl original = context.computeLibraryElement(source);
+    if (!allowErrors) {
+      List<AnalysisError> errors = context.computeErrors(source);
+      if (errors.where((e) => e.message.startsWith('unused')).isNotEmpty) {
+        fail('Analysis errors: $errors');
+      }
+    }
     checkLibraryElements(original, resynthesized);
     return resynthesized;
   }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index be1ba73..48293c1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -19,7 +19,7 @@
 import 'package:analyzer/src/generated/resolver.dart' show Namespace;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:test/test.dart';
@@ -410,7 +410,9 @@
         PrefixedIdentifier oTarget = o.target;
         checkElidablePrefix(oTarget.prefix);
         compareConstAsts(
-            r, AstFactory.identifier(oTarget.identifier, o.propertyName), desc);
+            r,
+            AstTestFactory.identifier(oTarget.identifier, o.propertyName),
+            desc);
       } else if (o is PrefixedIdentifier && r is PrefixedIdentifier) {
         compareConstAsts(r.prefix, o.prefix, desc);
         compareConstAsts(r.identifier, o.identifier, desc);
@@ -1116,8 +1118,7 @@
   /**
    * Determine the analysis options that should be used for this test.
    */
-  AnalysisOptionsImpl createOptions() =>
-      new AnalysisOptionsImpl()..enableGenericMethods = true;
+  AnalysisOptionsImpl createOptions() => new AnalysisOptionsImpl();
 
   ElementImpl getActualElement(Element element, String desc) {
     if (element == null) {
@@ -2303,6 +2304,12 @@
 ''');
   }
 
+  test_const_topLevel_ifNull() {
+    checkLibrary(r'''
+const vIfNull = 1 ?? 2.0;
+''');
+  }
+
   test_const_topLevel_literal() {
     checkLibrary(r'''
 const vNull = null;
@@ -3231,12 +3238,12 @@
   }
 
   test_function_type_parameter() {
-    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
+    prepareAnalysisContext(createOptions());
     checkLibrary('T f<T, U>(U u) => null;');
   }
 
   test_function_type_parameter_with_function_typed_parameter() {
-    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
+    prepareAnalysisContext(createOptions());
     checkLibrary('void f<T, U>(T x(U u)) {}');
   }
 
@@ -3245,7 +3252,7 @@
   }
 
   test_generic_gClass_gMethodStatic() {
-    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
+    prepareAnalysisContext(createOptions());
     checkLibrary('''
 class C<T, U> {
   static void m<V, W>(V v, W w) {
@@ -3434,6 +3441,12 @@
   }
 
   test_import_short_absolute() {
+    if (resourceProvider.pathContext.separator == '\\') {
+      // This test fails on Windows due to
+      // https://github.com/dart-lang/path/issues/18
+      // TODO(paulberry): reenable once that bug is addressed.
+      return;
+    }
     testFile = '/my/project/bin/test.dart';
     addLibrarySource('/a.dart', 'class C {}');
     checkLibrary('import "/a.dart"; C c;');
@@ -4072,17 +4085,17 @@
   }
 
   test_method_type_parameter() {
-    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
+    prepareAnalysisContext(createOptions());
     checkLibrary('class C { T f<T, U>(U u) => null; }');
   }
 
   test_method_type_parameter_in_generic_class() {
-    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
+    prepareAnalysisContext(createOptions());
     checkLibrary('class C<T, U> { V f<V, W>(T t, U u, W w) => null; }');
   }
 
   test_method_type_parameter_with_function_typed_parameter() {
-    prepareAnalysisContext(createOptions()..enableGenericMethods = true);
+    prepareAnalysisContext(createOptions());
     checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
   }
 
@@ -4535,47 +4548,51 @@
   }
 
   test_unresolved_annotation_namedConstructorCall_noClass() {
-    checkLibrary('@foo.bar() class C {}');
+    checkLibrary('@foo.bar() class C {}', allowErrors: true);
   }
 
   test_unresolved_annotation_namedConstructorCall_noConstructor() {
-    checkLibrary('@String.foo() class C {}');
+    checkLibrary('@String.foo() class C {}', allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedIdentifier_badPrefix() {
-    checkLibrary('@foo.bar class C {}');
+    checkLibrary('@foo.bar class C {}', allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedIdentifier_noDeclaration() {
-    checkLibrary('import "dart:async" as foo; @foo.bar class C {}');
+    checkLibrary('import "dart:async" as foo; @foo.bar class C {}',
+        allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedNamedConstructorCall_badPrefix() {
-    checkLibrary('@foo.bar.baz() class C {}');
+    checkLibrary('@foo.bar.baz() class C {}', allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedNamedConstructorCall_noClass() {
-    checkLibrary('import "dart:async" as foo; @foo.bar.baz() class C {}');
+    checkLibrary('import "dart:async" as foo; @foo.bar.baz() class C {}',
+        allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedNamedConstructorCall_noConstructor() {
-    checkLibrary('import "dart:async" as foo; @foo.Future.bar() class C {}');
+    checkLibrary('import "dart:async" as foo; @foo.Future.bar() class C {}',
+        allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedUnnamedConstructorCall_badPrefix() {
-    checkLibrary('@foo.bar() class C {}');
+    checkLibrary('@foo.bar() class C {}', allowErrors: true);
   }
 
   test_unresolved_annotation_prefixedUnnamedConstructorCall_noClass() {
-    checkLibrary('import "dart:async" as foo; @foo.bar() class C {}');
+    checkLibrary('import "dart:async" as foo; @foo.bar() class C {}',
+        allowErrors: true);
   }
 
   test_unresolved_annotation_simpleIdentifier() {
-    checkLibrary('@foo class C {}');
+    checkLibrary('@foo class C {}', allowErrors: true);
   }
 
   test_unresolved_annotation_unnamedConstructorCall_noClass() {
-    checkLibrary('@foo() class C {}');
+    checkLibrary('@foo() class C {}', allowErrors: true);
   }
 
   test_unresolved_export() {
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index 1a02706..e0083e0 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -315,7 +315,6 @@
         new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
-    parser.parseGenericMethods = true;
     CompilationUnit unit = parser.parseCompilationUnit(token);
     unit.lineInfo = new LineInfo(scanner.lineStarts);
     return unit;
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 018d86d..16f3f3c 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -74,7 +74,6 @@
   Scanner scanner =
       new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
   Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
-  parser.parseGenericMethods = true;
   CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
   UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
       public_namespace.computePublicNamespace(unit).toBuffer());
@@ -1756,6 +1755,18 @@
     ]);
   }
 
+  test_constExpr_binary_qq() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 ?? 2;');
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.ifNull
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
   test_constExpr_binary_subtract() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;');
     _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 428ae9c..4041961 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -797,6 +797,7 @@
   LibraryElement libraryElement;
 
   test_perform() {
+    enableUriInPartOf();
     _performBuildTask({
       '/lib.dart': '''
 library lib;
@@ -807,7 +808,7 @@
 part of lib;
 ''',
       '/part2.dart': '''
-part of lib;
+part of 'lib.dart';
 '''
     });
     expect(outputs, hasLength(3));
@@ -3544,9 +3545,7 @@
 class ReferencedNamesBuilderTest extends _AbstractDartTaskTest {
   void setUp() {
     super.setUp();
-    context.analysisOptions = new AnalysisOptionsImpl()
-      ..enableGenericMethods = true
-      ..strongMode = true;
+    context.analysisOptions = new AnalysisOptionsImpl()..strongMode = true;
   }
 
   test_class_constructor() {
@@ -5650,6 +5649,16 @@
     context.analysisOptions = options;
   }
 
+  /**
+   * Enable the use of URIs in part-of directives in the current analysis
+   * context.
+   */
+  void enableUriInPartOf() {
+    AnalysisOptionsImpl options = context.analysisOptions;
+    options.enableUriInPartOf = true;
+    context.analysisOptions = options;
+  }
+
   void setUp() {
     super.setUp();
     emptySource = newSource('/test.dart');
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index ff2092c..feb7238 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -19,7 +19,7 @@
         InternalAnalysisContext;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/dart_work_manager.dart';
 import 'package:analyzer/task/dart.dart';
@@ -531,7 +531,7 @@
   void test_onAnalysisOptionsChanged() {
     when(context.exists(anyObject)).thenReturn(true);
     // set cache values
-    entry1.setValue(PARSED_UNIT, AstFactory.compilationUnit(), []);
+    entry1.setValue(PARSED_UNIT, AstTestFactory.compilationUnit(), []);
     entry1.setValue(IMPORTED_LIBRARIES, <Source>[], []);
     entry1.setValue(EXPLICITLY_IMPORTED_LIBRARIES, <Source>[], []);
     entry1.setValue(EXPORTED_LIBRARIES, <Source>[], []);
@@ -575,7 +575,7 @@
   void test_onSourceFactoryChanged() {
     when(context.exists(anyObject)).thenReturn(true);
     // set cache values
-    entry1.setValue(PARSED_UNIT, AstFactory.compilationUnit(), []);
+    entry1.setValue(PARSED_UNIT, AstTestFactory.compilationUnit(), []);
     entry1.setValue(IMPORTED_LIBRARIES, <Source>[], []);
     entry1.setValue(EXPLICITLY_IMPORTED_LIBRARIES, <Source>[], []);
     entry1.setValue(EXPORTED_LIBRARIES, <Source>[], []);
@@ -619,7 +619,7 @@
         .setValue(VERIFY_ERRORS, <AnalysisError>[error2], []);
     // RESOLVED_UNIT is ready, set errors
     manager.resultsComputed(
-        unitTarget, {RESOLVED_UNIT: AstFactory.compilationUnit()});
+        unitTarget, {RESOLVED_UNIT: AstTestFactory.compilationUnit()});
     // all of the errors are included
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.errors, unorderedEquals([error1, error2]));
@@ -639,8 +639,8 @@
     entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
     entry1.setValue(PARSE_ERRORS, <AnalysisError>[error2], []);
     // PARSED_UNIT is ready, set errors
-    manager
-        .resultsComputed(source1, {PARSED_UNIT: AstFactory.compilationUnit()});
+    manager.resultsComputed(
+        source1, {PARSED_UNIT: AstTestFactory.compilationUnit()});
     // all of the errors are included
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.errors, unorderedEquals([error1, error2]));
@@ -724,7 +724,7 @@
     when(context.getErrors(source1))
         .thenReturn(new AnalysisErrorInfoImpl([], lineInfo));
     entry1.setValue(LINE_INFO, lineInfo, []);
-    CompilationUnit unit = AstFactory.compilationUnit();
+    CompilationUnit unit = AstTestFactory.compilationUnit();
     manager.resultsComputed(source1, {PARSED_UNIT: unit});
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.parsedDartUnit, unit);
@@ -738,7 +738,7 @@
     when(context.getErrors(source2))
         .thenReturn(new AnalysisErrorInfoImpl([], lineInfo));
     entry2.setValue(LINE_INFO, lineInfo, []);
-    CompilationUnit unit = AstFactory.compilationUnit();
+    CompilationUnit unit = AstTestFactory.compilationUnit();
     manager.resultsComputed(
         new LibrarySpecificUnit(source1, source2), {RESOLVED_UNIT: unit});
     ChangeNoticeImpl notice = context.getNotice(source2);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index be0798c..b8f717a 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -7,11 +7,8 @@
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/options.dart'
-    show CONFIGURED_ERROR_PROCESSORS;
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
@@ -54,14 +51,14 @@
     expect(analysisOptions.strongMode, false);
   }
 
-  test_configure_enableGenericMethods() {
-    expect(analysisOptions.enableGenericMethods, false);
+  test_configure_enableLazyAssignmentOperators() {
+    expect(analysisOptions.enableStrictCallChecks, false);
     configureContext('''
 analyzer:
   language:
-    enableGenericMethods: true
+    enableStrictCallChecks: true
 ''');
-    expect(analysisOptions.enableGenericMethods, true);
+    expect(analysisOptions.enableStrictCallChecks, true);
   }
 
   test_configure_enableStrictCallChecks() {
@@ -90,8 +87,7 @@
     unused_local_variable: error
 ''');
 
-    List<ErrorProcessor> processors =
-        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    List<ErrorProcessor> processors = context.analysisOptions.errorProcessors;
     expect(processors, hasLength(2));
 
     var unused_local = new AnalysisError(
@@ -122,7 +118,7 @@
     - 'test/**'
 ''');
 
-    List<String> excludes = context.getConfigurationData(CONTEXT_EXCLUDES);
+    List<String> excludes = context.analysisOptions.excludePatterns;
     expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
   }
 
@@ -240,7 +236,9 @@
   }
 
   test_perform_include_bad_value() {
-    newSource('/other_options.yaml', '''
+    newSource(
+        '/other_options.yaml',
+        '''
 analyzer:
   errors:
     unused_local_variable: ftw
@@ -252,7 +250,7 @@
     computeResult(target, ANALYSIS_OPTIONS_ERRORS);
     expect(task, isGenerateOptionsErrorsTask);
     List<AnalysisError> errors =
-    outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
+        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
     expect(errors, hasLength(1));
     AnalysisError error = errors[0];
     expect(error.errorCode, AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING);
@@ -271,7 +269,7 @@
     computeResult(target, ANALYSIS_OPTIONS_ERRORS);
     expect(task, isGenerateOptionsErrorsTask);
     List<AnalysisError> errors =
-    outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
+        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
     expect(errors, hasLength(1));
     AnalysisError error = errors[0];
     expect(error.errorCode, AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR);
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index ae546d5..7979880 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1067,6 +1067,28 @@
     checkFile('''
 void main () {
   {
+    T f<T>(T x) => null;
+    var v1 = f;
+    v1 = /*info:INFERRED_TYPE_CLOSURE*/<S>(x) => x;
+  }
+  {
+    List<T> f<T>(T x) => null;
+    var v2 = f;
+    v2 = /*info:INFERRED_TYPE_CLOSURE*/<S>(x) => /*info:INFERRED_TYPE_LITERAL*/[x];
+    Iterable<int> r = v2(42);
+    Iterable<String> s = v2('hello');
+    Iterable<List<int>> t = v2(<int>[]);
+    Iterable<num> u = v2(42);
+    Iterable<num> v = v2<num>(42);
+  }
+}
+''');
+  }
+
+  void test_downwardsInferenceOnFunctionOfTUsingTheT_comment() {
+    checkFile('''
+void main () {
+  {
     /*=T*/ f/*<T>*/(/*=T*/ x) => null;
     var v1 = f;
     v1 = /*info:INFERRED_TYPE_CLOSURE*//*<S>*/(x) => x;
@@ -1150,6 +1172,53 @@
     checkFile('''
 void main () {
   {
+    String f<S>(int x) => null;
+    var v = f;
+    v = /*info:INFERRED_TYPE_CLOSURE*/<T>(int x) => null;
+    v = <T>(int x) => "hello";
+    v = /*error:INVALID_ASSIGNMENT*/<T>(String x) => "hello";
+    v = /*error:INVALID_ASSIGNMENT*/<T>(int x) => 3;
+    v = /*info:INFERRED_TYPE_CLOSURE*/<T>(int x) {return /*error:RETURN_OF_INVALID_TYPE*/3;};
+  }
+  {
+    String f<S>(int x) => null;
+    var v = f;
+    v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/<T>(x) => null;
+    v = /*info:INFERRED_TYPE_CLOSURE*/<T>(x) => "hello";
+    v = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*/<T>(x) => 3;
+    v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/<T>(x) {return /*error:RETURN_OF_INVALID_TYPE*/3;};
+    v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/<T>(x) {return /*error:RETURN_OF_INVALID_TYPE*/x;};
+  }
+  {
+    List<String> f<S>(int x) => null;
+    var v = f;
+    v = /*info:INFERRED_TYPE_CLOSURE*/<T>(int x) => null;
+    v = <T>(int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+    v = /*error:INVALID_ASSIGNMENT*/<T>(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+    v = <T>(int x) => /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
+    v = /*info:INFERRED_TYPE_CLOSURE*/<T>(int x) {return /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
+  }
+  {
+    int int2int<S>(int x) => null;
+    String int2String<T>(int x) => null;
+    String string2String<T>(String x) => null;
+    var x = int2int;
+    x = /*info:INFERRED_TYPE_CLOSURE*/<T>(x) => x;
+    x = /*info:INFERRED_TYPE_CLOSURE*/<T>(x) => x+1;
+    var y = int2String;
+    y = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*/<T>(x) => x;
+    y = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/<T>(x) => /*info:DYNAMIC_INVOKE, info:DYNAMIC_CAST*/x.substring(3);
+    var z = string2String;
+    z = /*info:INFERRED_TYPE_CLOSURE*/<T>(x) => x.substring(3);
+  }
+}
+''');
+  }
+
+  void test_downwardsInferenceOnGenericFunctionExpressions_comment() {
+    checkFile('''
+void main () {
+  {
     String f/*<S>*/(int x) => null;
     var v = f;
     v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) => null;
@@ -1537,6 +1606,46 @@
   MyFuture() {}
   MyFuture.value(T x) {}
   dynamic noSuchMethod(invocation);
+  MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+  $declared f;
+  $downwards<int> t1 = f.then((_) async => await new $upwards<int>.value(3));
+  $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async {
+     return await new $upwards<int>.value(3);});
+  $downwards<int> t3 = f.then((_) async => 3);
+  $downwards<int> t4 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async {
+    return 3;});
+  $downwards<int> t5 = f.then((_) => new $upwards<int>.value(3));
+  $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) {return new $upwards<int>.value(3);});
+  $downwards<int> t7 = f.then((_) async => new $upwards<int>.value(3));
+  $downwards<int> t8 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async {
+    return new $upwards<int>.value(3);});
+}
+''';
+
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future"));
+    checkFile(build(
+        declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+  }
+
+  void test_futureThen_comment() {
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
   MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
 }
 
@@ -1577,6 +1686,42 @@
   MyFuture() {}
   MyFuture.value(T x) {}
   dynamic noSuchMethod(invocation);
+  MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+  $declared<bool> f;
+  $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+      (x) async => x ? 2 : await new $upwards<int>.value(3));
+  $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) async { // TODO(leafp): Why the duplicate here?
+    return await x ? 2 : new $upwards<int>.value(3);});
+  $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+      (x) => x ? 2 : new $upwards<int>.value(3));
+  $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+      (x) {return x ? 2 : new $upwards<int>.value(3);});
+}
+''';
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future"));
+    checkFile(build(
+        declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+  }
+
+  void test_futureThen_conditional_comment() {
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
   MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
 }
 
@@ -1625,6 +1770,17 @@
 import "dart:async";
 main() {
   Future<int> f;
+  var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/[]);
+  Future<List<int>> y = x;
+}
+    ''');
+  }
+
+  void test_futureThen_explicitFuture_comment() {
+    checkFile(r'''
+import "dart:async";
+main() {
+  Future<int> f;
   var x = f.then/*<Future<List<int>>>*/(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/[]);
   Future<List<int>> y = x;
 }
@@ -1639,6 +1795,36 @@
   MyFuture() {}
   MyFuture.value(T x) {}
   dynamic noSuchMethod(invocation);
+  MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+  var f = foo().then((_) => 2.3);
+  $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f;
+
+  // The unnecessary cast is to illustrate that we inferred <double> for
+  // the generic type args, even though we had a return type context.
+  $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then(
+      (_) => 2.3) as $upwards<double>;
+}
+$declared foo() => new $declared<int>.value(1);
+    ''';
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(build(
+        declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+  }
+
+  void test_futureThen_upwards_comment() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/27088.
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
   MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
 }
 
@@ -1682,6 +1868,29 @@
   MyFuture() {}
   MyFuture.value(T x) {}
   dynamic noSuchMethod(invocation);
+  MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+$downwards<int> g1(bool x) async {
+  return x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42); }
+$downwards<int> g2(bool x) async =>
+  x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42);
+$downwards<int> g3(bool x) async {
+  var y = x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42);
+  return y;
+}
+    ''';
+    checkFile(build(downwards: "Future", upwards: "Future"));
+    checkFile(build(downwards: "Future", upwards: "MyFuture"));
+  }
+
+  void test_futureUnion_asyncConditional_comment() {
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
   MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
 }
 
@@ -1711,6 +1920,48 @@
   MyFuture() {}
   MyFuture.value([T x]) {}
   dynamic noSuchMethod(invocation);
+  MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+$declared f;
+// Instantiates Future<int>
+$downwards<int> t1 = f.then((_) =>
+   ${allocInfo}new /*error:COULD_NOT_INFER*/$upwards.value(
+     /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'));
+
+// Instantiates List<int>
+$downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]);
+$downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; }
+$downwards<List<int>> g3() async {
+  return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(
+      /*info:INFERRED_TYPE_LITERAL*/[3]); }
+''';
+    }
+
+    ;
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
+  }
+
+  void test_futureUnion_downwards_comment() {
+    String build({String declared, String downwards, String upwards}) {
+      // TODO(leafp): The use of matchTypes in visitInstanceCreationExpression
+      // in the resolver visitor isn't powerful enough to catch this for the
+      // subclass.  See the TODO there.
+      var allocInfo =
+          (upwards == "Future") ? "/*info:INFERRED_TYPE_ALLOCATION*/" : "";
+      return '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([T x]) {}
+  dynamic noSuchMethod(invocation);
   MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
 }
 
@@ -1763,6 +2014,20 @@
     checkFile(r'''
 import 'dart:async';
 
+T id<T>(T x) => x;
+
+main() async {
+  Future<String> f;
+  String s = await id(f);
+}
+    ''');
+  }
+
+  void test_futureUnion_downwardsGenericMethodWithGenericReturn_comment() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/27284
+    checkFile(r'''
+import 'dart:async';
+
 /*=T*/ id/*<T>*/(/*=T*/ x) => x;
 
 main() async {
@@ -1798,6 +2063,20 @@
 typedef void ToValue<T>(T value);
 
 main() {
+  ToValue<T> f<T>(T x) => null;
+  var x = f<int>(42);
+  var y = f(42);
+  ToValue<int> takesInt = x;
+  takesInt = y;
+}
+    ''');
+  }
+
+  void test_genericFunctions_returnTypedef_comment() {
+    checkFile(r'''
+typedef void ToValue<T>(T value);
+
+main() {
   ToValue/*<T>*/ f/*<T>*/(dynamic /*=T*/ x) => null;
   var x = f/*<int>*/(42);
   var y = f(42);
@@ -1809,6 +2088,16 @@
 
   void test_genericMethods_basicDownwardInference() {
     checkFile(r'''
+T f<S, T>(S s) => null;
+main() {
+  String x = f(42);
+  String y = (f)(42);
+}
+''');
+  }
+
+  void test_genericMethods_basicDownwardInference_comment() {
+    checkFile(r'''
 /*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
 main() {
   String x = f(42);
@@ -1821,6 +2110,28 @@
     // Regression test for https://github.com/dart-lang/sdk/issues/25740.
     checkFile(r'''
 class Foo<T extends Pattern> {
+  U method<U extends T>(U u) => u;
+}
+main() {
+  String s;
+  var a = new Foo().method<String>("str");
+  s = a;
+  new Foo();
+
+  var b = new Foo<String>().method("str");
+  s = b;
+  var c = new Foo().method("str");
+  s = c;
+
+  new Foo<String>()./*error:COULD_NOT_INFER*/method(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/42);
+}
+''');
+  }
+
+  void test_genericMethods_correctlyRecognizeGenericUpperBound_comment() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
+    checkFile(r'''
+class Foo<T extends Pattern> {
   /*=U*/ method/*<U extends T>*/(/*=U*/ u) => u;
 }
 main() {
@@ -1877,6 +2188,21 @@
   void test_genericMethods_doNotInferInvalidOverrideOfGenericMethod() {
     checkFile('''
 class C {
+T m<T>(T x) => x;
+}
+class D extends C {
+/*error:INVALID_METHOD_OVERRIDE*/m(x) => x;
+}
+main() {
+  int y = /*info:DYNAMIC_CAST*/new D()./*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/m<int>(42);
+  print(y);
+}
+''');
+  }
+
+  void test_genericMethods_doNotInferInvalidOverrideOfGenericMethod_comment() {
+    checkFile('''
+class C {
 /*=T*/ m/*<T>*/(/*=T*/ x) => x;
 }
 class D extends C {
@@ -1891,6 +2217,16 @@
 
   void test_genericMethods_downwardsInferenceAffectsArguments() {
     checkFile(r'''
+T f<T>(List<T> s) => null;
+main() {
+  String x = f(/*info:INFERRED_TYPE_LITERAL*/['hi']);
+  String y = f(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]);
+}
+''');
+  }
+
+  void test_genericMethods_downwardsInferenceAffectsArguments_comment() {
+    checkFile(r'''
 /*=T*/ f/*<T>*/(List/*<T>*/ s) => null;
 main() {
   String x = f(/*info:INFERRED_TYPE_LITERAL*/['hi']);
@@ -1927,6 +2263,24 @@
   dynamic g(int x) => x;
 }
 class D extends C {
+  T m<T>(T x) => x;
+  T g<T>(T x) => x;
+}
+main() {
+  int y = /*info:DYNAMIC_CAST*/(/*info:UNNECESSARY_CAST*/new D() as C).m(42);
+  print(y);
+}
+  ''');
+  }
+
+  void test_genericMethods_handleOverrideOfNonGenericWithGeneric_comment() {
+    // Regression test for crash when adding genericity
+    checkFile('''
+class C {
+  m(x) => x;
+  dynamic g(int x) => x;
+}
+class D extends C {
   /*=T*/ m/*<T>*/(/*=T*/ x) => x;
   /*=T*/ g/*<T>*/(/*=T*/ x) => x;
 }
@@ -1949,10 +2303,10 @@
   void test_genericMethods_inferGenericFunctionParameterType() {
     var mainUnit = checkFile('''
 class C<T> extends D<T> {
-  f/*<U>*/(x) {}
+  f<U>(x) {}
 }
 class D<T> {
-  F/*<U>*/ f/*<U>*/(/*=U*/ u) => null;
+  F<U> f<U>(U u) => null;
 }
 typedef void F<V>(V v);
 ''');
@@ -1963,6 +2317,20 @@
   void test_genericMethods_inferGenericFunctionParameterType2() {
     var mainUnit = checkFile('''
 class C<T> extends D<T> {
+  f<U>(g) => null;
+}
+abstract class D<T> {
+  void f<U>(G<U> g);
+}
+typedef List<V> G<V>();
+''');
+    var f = mainUnit.getType('C').methods[0];
+    expect(f.type.toString(), '<U>(() → List<U>) → void');
+  }
+
+  void test_genericMethods_inferGenericFunctionParameterType2_comment() {
+    var mainUnit = checkFile('''
+class C<T> extends D<T> {
   f/*<U>*/(g) => null;
 }
 abstract class D<T> {
@@ -1974,9 +2342,37 @@
     expect(f.type.toString(), '<U>(() → List<U>) → void');
   }
 
+  void test_genericMethods_inferGenericFunctionParameterType_comment() {
+    var mainUnit = checkFile('''
+class C<T> extends D<T> {
+  f/*<U>*/(x) {}
+}
+class D<T> {
+  F/*<U>*/ f/*<U>*/(/*=U*/ u) => null;
+}
+typedef void F<V>(V v);
+''');
+    var f = mainUnit.getType('C').methods[0];
+    expect(f.type.toString(), '<U>(U) → (U) → void');
+  }
+
   void test_genericMethods_inferGenericFunctionReturnType() {
     var mainUnit = checkFile('''
 class C<T> extends D<T> {
+  f<U>(x) {}
+}
+class D<T> {
+  F<U> f<U>(U u) => null;
+}
+typedef V F<V>();
+''');
+    var f = mainUnit.getType('C').methods[0];
+    expect(f.type.toString(), '<U>(U) → () → U');
+  }
+
+  void test_genericMethods_inferGenericFunctionReturnType_comment() {
+    var mainUnit = checkFile('''
+class C<T> extends D<T> {
   f/*<U>*/(x) {}
 }
 class D<T> {
@@ -1994,6 +2390,96 @@
 import 'dart:math' show min;
 
 class C {
+T m<T extends num>(T x, T y) => null;
+}
+
+main() {
+takeIII(math.max);
+takeDDD(math.max);
+takeNNN(math.max);
+takeIDN(math.max);
+takeDIN(math.max);
+takeIIN(math.max);
+takeDDN(math.max);
+takeIIO(math.max);
+takeDDO(math.max);
+
+takeOOI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeIDI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeDID(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOON(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOOO(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+
+// Also test SimpleIdentifier
+takeIII(min);
+takeDDD(min);
+takeNNN(min);
+takeIDN(min);
+takeDIN(min);
+takeIIN(min);
+takeDDN(min);
+takeIIO(min);
+takeDDO(min);
+
+takeOOI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeIDI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeDID(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOON(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOOO(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+
+// Also PropertyAccess
+takeIII(new C().m);
+takeDDD(new C().m);
+takeNNN(new C().m);
+takeIDN(new C().m);
+takeDIN(new C().m);
+takeIIN(new C().m);
+takeDDN(new C().m);
+takeIIO(new C().m);
+takeDDO(new C().m);
+
+// Note: this is a warning because a downcast of a method tear-off could work
+// (derived method can be a subtype):
+//
+//     class D extends C {
+//       S m<S extends num>(Object x, Object y);
+//     }
+//
+// That's legal because we're loosening parameter types.
+//
+takeOON(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOOO(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+
+// Note: this is a warning because a downcast of a method tear-off could work
+// in "normal" Dart, due to bivariance.
+takeOOI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeIDI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeDID(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+}
+
+void takeIII(int fn(int a, int b)) {}
+void takeDDD(double fn(double a, double b)) {}
+void takeIDI(int fn(double a, int b)) {}
+void takeDID(double fn(int a, double b)) {}
+void takeIDN(num fn(double a, int b)) {}
+void takeDIN(num fn(int a, double b)) {}
+void takeIIN(num fn(int a, int b)) {}
+void takeDDN(num fn(double a, double b)) {}
+void takeNNN(num fn(num a, num b)) {}
+void takeOON(num fn(Object a, Object b)) {}
+void takeOOO(num fn(Object a, Object b)) {}
+void takeOOI(int fn(Object a, Object b)) {}
+void takeIIO(Object fn(int a, int b)) {}
+void takeDDO(Object fn(double a, double b)) {}
+''');
+  }
+
+  void test_genericMethods_inferGenericInstantiation_comment() {
+    checkFile('''
+import 'dart:math' as math;
+import 'dart:math' show min;
+
+class C {
 /*=T*/ m/*<T extends num>*/(/*=T*/ x, /*=T*/ y) => null;
 }
 
@@ -2082,6 +2568,22 @@
     // Regression test for https://github.com/dart-lang/sdk/issues/25668
     checkFile('''
 class C {
+  T m<T>(T x) => x;
+}
+class D extends C {
+  m<S>(x) => x;
+}
+main() {
+  int y = new D().m<int>(42);
+  print(y);
+}
+  ''');
+  }
+
+  void test_genericMethods_inferGenericMethodType_comment() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25668
+    checkFile('''
+class C {
   /*=T*/ m/*<T>*/(/*=T*/ x) => x;
 }
 class D extends C {
@@ -2128,6 +2630,19 @@
 typedef Iterable<num> F(int x);
 typedef List<int> G(double x);
 
+T generic<T>(a(T _), b(T _)) => null;
+
+var v = generic((F f) => null, (G g) => null);
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), '(num) → List<int>');
+  }
+
+  void test_genericMethods_usesGreatestLowerBound_comment() {
+    var mainUnit = checkFile(r'''
+typedef Iterable<num> F(int x);
+typedef List<int> G(double x);
+
 /*=T*/ generic/*<T>*/(a(/*=T*/ _), b(/*=T*/ _)) => null;
 
 var v = generic((F f) => null, (G g) => null);
@@ -2712,6 +3227,16 @@
   void test_inferGenericMethodType_named() {
     var unit = checkFile('''
 class C {
+  T m<T>(int a, {String b, T c}) => null;
+}
+var y = new C().m(1, b: 'bbb', c: 2.0);
+  ''');
+    expect(unit.topLevelVariables[0].type.toString(), 'double');
+  }
+
+  void test_inferGenericMethodType_named_comment() {
+    var unit = checkFile('''
+class C {
   /*=T*/ m/*<T>*/(int a, {String b, /*=T*/ c}) => null;
 }
 var y = new C().m(1, b: 'bbb', c: 2.0);
@@ -2722,7 +3247,7 @@
   void test_inferGenericMethodType_positional() {
     var unit = checkFile('''
 class C {
-  /*=T*/ m/*<T>*/(int a, [/*=T*/ b]) => null;
+  T m<T>(int a, [T b]) => null;
 }
 var y = new C().m(1, 2.0);
   ''');
@@ -2732,6 +3257,16 @@
   void test_inferGenericMethodType_positional2() {
     var unit = checkFile('''
 class C {
+  T m<T>(int a, [String b, T c]) => null;
+}
+var y = new C().m(1, 'bbb', 2.0);
+  ''');
+    expect(unit.topLevelVariables[0].type.toString(), 'double');
+  }
+
+  void test_inferGenericMethodType_positional2_comment() {
+    var unit = checkFile('''
+class C {
   /*=T*/ m/*<T>*/(int a, [String b, /*=T*/ c]) => null;
 }
 var y = new C().m(1, 'bbb', 2.0);
@@ -2739,9 +3274,29 @@
     expect(unit.topLevelVariables[0].type.toString(), 'double');
   }
 
+  void test_inferGenericMethodType_positional_comment() {
+    var unit = checkFile('''
+class C {
+  /*=T*/ m/*<T>*/(int a, [/*=T*/ b]) => null;
+}
+var y = new C().m(1, 2.0);
+  ''');
+    expect(unit.topLevelVariables[0].type.toString(), 'double');
+  }
+
   void test_inferGenericMethodType_required() {
     var unit = checkFile('''
 class C {
+  T m<T>(T x) => x;
+}
+var y = new C().m(42);
+  ''');
+    expect(unit.topLevelVariables[0].type.toString(), 'int');
+  }
+
+  void test_inferGenericMethodType_required_comment() {
+    var unit = checkFile('''
+class C {
   /*=T*/ m/*<T>*/(/*=T*/ x) => x;
 }
 var y = new C().m(42);
@@ -3958,6 +4513,18 @@
   void test_methodCall_withTypeArguments_instanceMethod() {
     var mainUnit = checkFile('''
 class C {
+  D<T> f<T>() => null;
+}
+class D<T> {}
+var f = new C().f<int>();
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'D<int>');
+  }
+
+  void test_methodCall_withTypeArguments_instanceMethod_comment() {
+    var mainUnit = checkFile('''
+class C {
   D/*<T>*/ f/*<T>*/() => null;
 }
 class D<T> {}
@@ -3970,6 +4537,21 @@
   void test_methodCall_withTypeArguments_instanceMethod_identifierSequence() {
     var mainUnit = checkFile('''
 class C {
+  D<T> f<T>() => null;
+}
+class D<T> {}
+C c;
+var f = c.f<int>();
+''');
+    var v = mainUnit.topLevelVariables[1];
+    expect(v.name, 'f');
+    expect(v.type.toString(), 'D<int>');
+  }
+
+  void
+      test_methodCall_withTypeArguments_instanceMethod_identifierSequence_comment() {
+    var mainUnit = checkFile('''
+class C {
   D/*<T>*/ f/*<T>*/() => null;
 }
 class D<T> {}
@@ -3984,6 +4566,18 @@
   void test_methodCall_withTypeArguments_staticMethod() {
     var mainUnit = checkFile('''
 class C {
+  static D<T> f<T>() => null;
+}
+class D<T> {}
+var f = C.f<int>();
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'D<int>');
+  }
+
+  void test_methodCall_withTypeArguments_staticMethod_comment() {
+    var mainUnit = checkFile('''
+class C {
   static D/*<T>*/ f/*<T>*/() => null;
 }
 class D<T> {}
@@ -3995,6 +4589,16 @@
 
   void test_methodCall_withTypeArguments_topLevelFunction() {
     var mainUnit = checkFile('''
+D<T> f<T>() => null;
+class D<T> {}
+var g = f<int>();
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'D<int>');
+  }
+
+  void test_methodCall_withTypeArguments_topLevelFunction_comment() {
+    var mainUnit = checkFile('''
 D/*<T>*/ f/*<T>*/() => null;
 class D<T> {}
 var g = f/*<int>*/();
@@ -4381,6 +4985,17 @@
 
   void test_unsafeBlockClosureInference_functionCall_explicitDynamicParam() {
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = f<dynamic>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_comment() {
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = f/*<dynamic>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
 ''');
@@ -4395,6 +5010,20 @@
     // Note: (f/*<dynamic>*/) is nort properly resulting in an instantiated
     // function type due to dartbug.com/25824.
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f<dynamic>)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1_comment() {
+    // Note: (f/*<dynamic>*/) is nort properly resulting in an instantiated
+    // function type due to dartbug.com/25824.
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = (f/*<dynamic>*/)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
 ''');
@@ -4406,6 +5035,17 @@
   void
       test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2() {
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)<dynamic>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2_comment() {
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = (f)/*<dynamic>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
 ''');
@@ -4416,6 +5056,17 @@
 
   void test_unsafeBlockClosureInference_functionCall_explicitTypeParam() {
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = f<int>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_comment() {
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = f/*<int>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
 ''');
@@ -4430,6 +5081,20 @@
     // TODO(paulberry): for some reason (f/*<int>) is nort properly resulting
     // in an instantiated function type.
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f/int>)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1_comment() {
+    // TODO(paulberry): for some reason (f/*<int>) is nort properly resulting
+    // in an instantiated function type.
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = (f/*<int>*/)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
 ''');
@@ -4441,6 +5106,17 @@
   void
       test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2() {
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)<int>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2_comment() {
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = (f)/*<int>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
 ''');
@@ -4451,6 +5127,20 @@
 
   void test_unsafeBlockClosureInference_functionCall_implicitTypeParam() {
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = f(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_implicitTypeParam_comment() {
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = f(
   /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
@@ -4465,6 +5155,20 @@
   void
       test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr() {
     var mainUnit = checkFile('''
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr_comment() {
+    var mainUnit = checkFile('''
 dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 var v = (f)(
   /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
@@ -4561,6 +5265,19 @@
   void test_unsafeBlockClosureInference_methodCall_explicitDynamicParam() {
     var mainUnit = checkFile('''
 class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+var v = new C().f<dynamic>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_methodCall_explicitDynamicParam_comment() {
+    var mainUnit = checkFile('''
+class C {
   dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 }
 var v = new C().f/*<dynamic>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
@@ -4573,6 +5290,18 @@
   void test_unsafeBlockClosureInference_methodCall_explicitTypeParam() {
     var mainUnit = checkFile('''
 class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+var v = new C().f<int>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void test_unsafeBlockClosureInference_methodCall_explicitTypeParam_comment() {
+    var mainUnit = checkFile('''
+class C {
   dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 }
 var v = new C().f/*<int>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
@@ -4585,6 +5314,21 @@
   void test_unsafeBlockClosureInference_methodCall_implicitTypeParam() {
     var mainUnit = checkFile('''
 class C {
+  List<T> f<T>(T g()) => <T>[g()];
+}
+var v = new C().f(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void test_unsafeBlockClosureInference_methodCall_implicitTypeParam_comment() {
+    var mainUnit = checkFile('''
+class C {
   dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
 }
 var v = new C().f(
@@ -4611,6 +5355,37 @@
 
   void test_voidReturnTypeSubtypesDynamic() {
     var unit = checkFile(r'''
+T run<T>(T f()) {
+  print("running");
+  var t = f();
+  print("done running");
+  return t;
+}
+
+
+void printRunning() { print("running"); }
+var x = run<dynamic>(printRunning);
+var y = run(printRunning);
+
+main() {
+  void printRunning() { print("running"); }
+  var x = run<dynamic>(printRunning);
+  var y = run(printRunning);
+  x = 123;
+  x = 'hi';
+  y = 123;
+  y = 'hi';
+}
+    ''');
+
+    var x = unit.topLevelVariables[0];
+    var y = unit.topLevelVariables[1];
+    expect(x.type.toString(), 'dynamic');
+    expect(y.type.toString(), 'dynamic');
+  }
+
+  void test_voidReturnTypeSubtypesDynamic_comment() {
+    var unit = checkFile(r'''
 /*=T*/ run/*<T>*/(/*=T*/ f()) {
   print("running");
   var t = f();
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index aef2211..386a95d 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -415,6 +415,7 @@
     } else {
       // The embedder uri resolver has mappings, use it instead of the default
       // Dart SDK uri resolver.
+      embedderSdk.analysisOptions = _context.analysisOptions;
       resolvers.add(new DartUriResolver(embedderSdk));
     }
 
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index b0875ab..222d96d 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:path/path.dart' as path;
@@ -427,7 +426,7 @@
 Driver driver;
 
 List<ErrorProcessor> get processors =>
-    driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    driver.context.analysisOptions.errorProcessors;
 
 /// Convert a file specification from a relative path to an absolute path.
 /// Handles the case where the file specification is of the form "$uri|$path".
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 8d7b735..81248d9 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -74,9 +74,12 @@
   // https://gist.github.com/eernstg/4353d7b4f669745bed3a5423e04a453c.
   static const String genericMethodSyntax = '--generic-method-syntax';
 
+  // Initializing-formal access is enabled by default and cannot be disabled.
+  // For backward compatibility the option is still accepted, but it is ignored.
+  static const String initializingFormalAccess = '--initializing-formal-access';
+
   // Experimental flags.
   static const String resolveOnly = '--resolve-only';
-  static const String initializingFormalAccess = '--initializing-formal-access';
 }
 
 class Option {
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index aeec588..9012c82 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -28,7 +28,7 @@
 import '../enqueue.dart' show ResolutionEnqueuer;
 import '../id_generator.dart';
 import '../mirrors_used.dart';
-import '../options.dart' show CompilerOptions, ParserOptions;
+import '../options.dart' show CompilerOptions;
 import '../parser/element_listener.dart' show ScannerOptions;
 import '../parser/parser_task.dart';
 import '../patch_parser.dart';
@@ -212,13 +212,11 @@
 abstract class ParsingContext {
   factory ParsingContext(
       DiagnosticReporter reporter,
-      ParserOptions parserOptions,
       ParserTask parser,
       PatchParserTask patchParser,
       Backend backend) = _ParsingContext;
 
   DiagnosticReporter get reporter;
-  ParserOptions get parserOptions;
   ParserTask get parser;
   PatchParserTask get patchParser;
 
@@ -236,12 +234,11 @@
 
 class _ParsingContext implements ParsingContext {
   final DiagnosticReporter reporter;
-  final ParserOptions parserOptions;
   final ParserTask parser;
   final PatchParserTask patchParser;
   final Backend backend;
 
-  _ParsingContext(this.reporter, this.parserOptions, this.parser,
+  _ParsingContext(this.reporter, this.parser,
       this.patchParser, this.backend);
 
   @override
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index a8f3a89..a1d62a2 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -1241,13 +1241,10 @@
       if (parameter.isInitializingFormal) {
         InitializingFormalElement initializingFormal = parameter;
         updateFieldValue(node, initializingFormal.fieldElement, argument);
-        if (compiler.options.enableInitializingFormalAccess) {
-          definitions[parameter] = argument;
-        }
       } else {
         potentiallyCheckType(parameter, argument);
-        definitions[parameter] = argument;
       }
+      definitions[parameter] = argument;
     });
   }
 
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index c7bdcdf..7b4d9ce 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -257,7 +257,7 @@
 
     tasks = [
       dietParser =
-          new DietParserTask(options, idGenerator, backend, reporter, measurer),
+          new DietParserTask(idGenerator, backend, reporter, measurer),
       scanner = createScannerTask(),
       serialization = new SerializationTask(this),
       libraryLoader = new LibraryLoaderTask(
@@ -271,8 +271,8 @@
           environment,
           reporter,
           measurer),
-      parser = new ParserTask(this, options),
-      patchParser = new PatchParserTask(this, options),
+      parser = new ParserTask(this),
+      patchParser = new PatchParserTask(this),
       resolver = createResolverTask(),
       closureToClassMapper = new closureMapping.ClosureTask(this),
       checker = new TypeCheckerTask(this),
@@ -291,7 +291,7 @@
     }
 
     _parsingContext =
-        new ParsingContext(reporter, options, parser, patchParser, backend);
+        new ParsingContext(reporter, parser, patchParser, backend);
 
     tasks.addAll(backend.tasks);
   }
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 352fc9f..cb39e78 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -138,6 +138,8 @@
 
   void passThrough(String argument) => options.add(argument);
 
+  void ignoreOption(String argument) {}
+
   if (BUILD_ID != null) {
     passThrough("--build-id=$BUILD_ID");
   }
@@ -332,8 +334,8 @@
     new OptionHandler('--out=.+|-o.*', setOutput, multipleArguments: true),
     new OptionHandler(Flags.allowMockCompilation, passThrough),
     new OptionHandler(Flags.fastStartup, passThrough),
-    new OptionHandler(Flags.genericMethodSyntax, passThrough),
-    new OptionHandler(Flags.initializingFormalAccess, passThrough),
+    new OptionHandler(Flags.genericMethodSyntax, ignoreOption),
+    new OptionHandler(Flags.initializingFormalAccess, ignoreOption),
     new OptionHandler('${Flags.minify}|-m', implyCompilation),
     new OptionHandler(Flags.preserveUris, passThrough),
     new OptionHandler('--force-strip=.*', setStrip),
diff --git a/pkg/compiler/lib/src/kernel/kernel.dart b/pkg/compiler/lib/src/kernel/kernel.dart
index 3b403b7..3bcad71 100644
--- a/pkg/compiler/lib/src/kernel/kernel.dart
+++ b/pkg/compiler/lib/src/kernel/kernel.dart
@@ -6,7 +6,7 @@
 import 'dart:collection' show Queue;
 
 import 'package:kernel/ast.dart' as ir;
-import 'package:kernel/checks.dart' show CheckParentPointers;
+import 'package:kernel/verifier.dart' show CheckParentPointers;
 
 import '../common.dart';
 import '../common/names.dart';
@@ -73,6 +73,7 @@
 
   final Map<ir.Node, Element> nodeToElement = <ir.Node, Element>{};
   final Map<ir.Node, Node> nodeToAst = <ir.Node, Node>{};
+  final Map<ir.Node, Node> nodeToAstOperator = <ir.Node, Node>{};
 
   /// FIFO queue of work that needs to be completed before the returned AST
   /// nodes are correct.
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index d4d6216..664388d 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -1230,6 +1230,7 @@
   @override
   ir.Expression visitCompoundIndexSet(SendSet node, Node receiver, Node index,
       AssignmentOperator operator, Node rhs, _) {
+    // TODO(sra): Find binary operator.
     return buildIndexAccessor(receiver, index).buildCompoundAssignment(
         kernel.irName(operator.selectorName, currentElement),
         visitForValue(rhs),
@@ -1289,7 +1290,8 @@
         receiver == null ? new ir.ThisExpression() : visitForValue(receiver);
     ir.Expression compound = buildCompound(
         PropertyAccessor.make(receiverNode, nameToIrName(name), null, null),
-        rhs);
+        rhs,
+        node);
     if (compound is ir.VariableSet) {
       associateNode(compound.value, node);
     } else {
@@ -1720,19 +1722,32 @@
     return buildLocalGet(element);
   }
 
-  ir.Expression buildCompound(Accessor accessor, CompoundRhs rhs) {
+  ir.Expression buildCompound(
+      Accessor accessor, CompoundRhs rhs, SendSet node) {
     ir.Name name = kernel.irName(rhs.operator.selectorName, currentElement);
+    ir.Expression result;
     switch (rhs.kind) {
       case CompoundKind.POSTFIX:
-        return accessor.buildPostfixIncrement(name, voidContext: isVoidContext);
+        result =
+            accessor.buildPostfixIncrement(name, voidContext: isVoidContext);
+        break;
 
       case CompoundKind.PREFIX:
-        return accessor.buildPrefixIncrement(name, voidContext: isVoidContext);
+        result =
+            accessor.buildPrefixIncrement(name, voidContext: isVoidContext);
+        break;
 
       case CompoundKind.ASSIGNMENT:
-        return accessor.buildCompoundAssignment(name, visitForValue(rhs.rhs),
+        result = accessor.buildCompoundAssignment(name, visitForValue(rhs.rhs),
             voidContext: isVoidContext);
+        break;
     }
+    assert(accessor.builtBinary != null);
+    kernel.nodeToAstOperator[accessor.builtBinary] = node;
+    if (accessor.builtGetter != null) {
+      kernel.nodeToAst[accessor.builtGetter] = node;
+    }
+    return result;
   }
 
   @override
@@ -1740,7 +1755,7 @@
       SendSet node, LocalElement local, CompoundRhs rhs, _,
       {bool isSetterValid}) {
     ir.Expression compound =
-        buildCompound(new VariableAccessor(getLocal(local)), rhs);
+        buildCompound(new VariableAccessor(getLocal(local)), rhs, node);
     if (compound is ir.VariableSet) {
       associateNode(compound.value, node);
     } else {
@@ -1997,7 +2012,6 @@
           positionalParameters.add(variable);
         }
       });
-      namedParameters.sort();
       signature.forEachParameter((ParameterElement parameter) {
         if (!parameter.isOptional) return;
         ir.Expression initializer = visitForValue(parameter.initializer);
@@ -2236,6 +2250,7 @@
       AssignmentOperator operator,
       Node rhs,
       _) {
+    // TODO(sra): Find binary operator.
     return buildSuperIndexAccessor(index, getter, setter)
         .buildCompoundAssignment(
             kernel.irName(operator.selectorName, currentElement),
@@ -2287,7 +2302,7 @@
     if (setterKind == CompoundSetter.INVALID) {
       setter = null;
     }
-    return buildCompound(buildSuperPropertyAccessor(getter, setter), rhs);
+    return buildCompound(buildSuperPropertyAccessor(getter, setter), rhs, node);
   }
 
   @override
@@ -2302,13 +2317,14 @@
     if (setterKind == CompoundSetter.INVALID) {
       setter = null;
     }
-    return buildCompound(buildStaticAccessor(getter, setter), rhs);
+    return buildCompound(buildStaticAccessor(getter, setter), rhs, node);
   }
 
   @override
   ir.Expression handleTypeLiteralConstantCompounds(
       SendSet node, ConstantExpression constant, CompoundRhs rhs, _) {
-    return buildCompound(new ReadOnlyAccessor(buildTypeLiteral(constant)), rhs);
+    return buildCompound(
+        new ReadOnlyAccessor(buildTypeLiteral(constant)), rhs, node);
   }
 
   ir.TypeLiteral buildTypeVariable(TypeVariableElement element) {
@@ -2318,7 +2334,8 @@
   @override
   ir.Expression handleTypeVariableTypeLiteralCompounds(
       SendSet node, TypeVariableElement element, CompoundRhs rhs, _) {
-    return buildCompound(new ReadOnlyAccessor(buildTypeVariable(element)), rhs);
+    return buildCompound(
+        new ReadOnlyAccessor(buildTypeVariable(element)), rhs, node);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index f490329..70594dc 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -7,18 +7,6 @@
 import '../compiler.dart' show PackagesDiscoveryProvider;
 import 'commandline_options.dart' show Flags;
 
-/// Options used for parsing.
-///
-/// Use this to conditionally support certain constructs, e.g.,
-/// experimental ones.
-abstract class ParserOptions {
-  const ParserOptions();
-
-  /// Support parsing of generic method declarations, and invocations of
-  /// methods where type arguments are passed.
-  bool get enableGenericMethodSyntax;
-}
-
 /// Options used for controlling diagnostic messages.
 abstract class DiagnosticOptions {
   const DiagnosticOptions();
@@ -48,7 +36,7 @@
 /// Object for passing options to the compiler. Superclasses are used to select
 /// subsets of these options, enabling each part of the compiler to depend on
 /// as few as possible.
-class CompilerOptions implements DiagnosticOptions, ParserOptions {
+class CompilerOptions implements DiagnosticOptions {
   /// The entry point of the application that is being compiled.
   final Uri entryPoint;
 
@@ -145,14 +133,6 @@
   /// reason for why an assertion fails. (experimental)
   final bool enableAssertMessage;
 
-  /// Support parsing of generic method declarations, and invocations of
-  /// methods where type arguments are passed.
-  final bool enableGenericMethodSyntax;
-
-  /// Support access to initializing formal constructor arguments, e.g., the
-  /// use of `x` to initialize `y` in `C(this.x) : y = x`.
-  final bool enableInitializingFormalAccess;
-
   /// Whether the user specified a flag to allow the use of dart:mirrors. This
   /// silences a warning produced by the compiler.
   final bool enableExperimentalMirrors;
@@ -288,10 +268,6 @@
         disableTypeInference: _hasOption(options, Flags.disableTypeInference),
         dumpInfo: _hasOption(options, Flags.dumpInfo),
         enableAssertMessage: _hasOption(options, Flags.enableAssertMessage),
-        enableGenericMethodSyntax:
-            true, // No check for `Flags.genericMethodSyntax`: always enabled.
-        enableInitializingFormalAccess:
-            _hasOption(options, Flags.initializingFormalAccess),
         enableExperimentalMirrors:
             _hasOption(options, Flags.enableExperimentalMirrors),
         enableMinification: _hasOption(options, Flags.minify),
@@ -358,8 +334,6 @@
       bool disableTypeInference: false,
       bool dumpInfo: false,
       bool enableAssertMessage: false,
-      bool enableGenericMethodSyntax: false,
-      bool enableInitializingFormalAccess: false,
       bool enableExperimentalMirrors: false,
       bool enableMinification: false,
       bool enableNativeLiveTypeAnalysis: true,
@@ -430,8 +404,6 @@
         disableTypeInference: disableTypeInference,
         dumpInfo: dumpInfo,
         enableAssertMessage: enableAssertMessage,
-        enableGenericMethodSyntax: enableGenericMethodSyntax,
-        enableInitializingFormalAccess: enableInitializingFormalAccess,
         enableExperimentalMirrors: enableExperimentalMirrors,
         enableMinification: enableMinification,
         enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis,
@@ -481,8 +453,6 @@
       this.disableTypeInference: false,
       this.dumpInfo: false,
       this.enableAssertMessage: false,
-      this.enableGenericMethodSyntax: false,
-      this.enableInitializingFormalAccess: false,
       this.enableExperimentalMirrors: false,
       this.enableMinification: false,
       this.enableNativeLiveTypeAnalysis: false,
@@ -539,8 +509,6 @@
       disableTypeInference,
       dumpInfo,
       enableAssertMessage,
-      enableGenericMethodSyntax,
-      enableInitializingFormalAccess,
       enableExperimentalMirrors,
       enableMinification,
       enableNativeLiveTypeAnalysis,
@@ -598,10 +566,6 @@
             disableTypeInference ?? options.disableTypeInference,
         dumpInfo: dumpInfo ?? options.dumpInfo,
         enableAssertMessage: enableAssertMessage ?? options.enableAssertMessage,
-        enableGenericMethodSyntax:
-            enableGenericMethodSyntax ?? options.enableGenericMethodSyntax,
-        enableInitializingFormalAccess: enableInitializingFormalAccess ??
-            options.enableInitializingFormalAccess,
         enableExperimentalMirrors:
             enableExperimentalMirrors ?? options.enableExperimentalMirrors,
         enableMinification: enableMinification ?? options.enableMinification,
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart
index 3d3cd27..851873a 100644
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart
@@ -4,14 +4,12 @@
 
 library dart2js.parser.classes;
 
-import '../options.dart' show ParserOptions;
 import '../tokens/token.dart' show Token;
 import 'listener.dart' show Listener;
 import 'partial_parser.dart' show PartialParser;
 
 class ClassElementParser extends PartialParser {
-  ClassElementParser(Listener listener, ParserOptions options)
-      : super(listener, options);
+  ClassElementParser(Listener listener): super(listener);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 002bba0..e975a83 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -9,20 +9,18 @@
 import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../elements/elements.dart' show CompilationUnitElement;
 import '../id_generator.dart';
-import '../options.dart' show ParserOptions;
 import '../tokens/token.dart' show Token;
 import 'element_listener.dart' show ElementListener, ScannerOptions;
 import 'listener.dart' show ParserError;
 import 'partial_parser.dart' show PartialParser;
 
 class DietParserTask extends CompilerTask {
-  final ParserOptions _parserOptions;
   final IdGenerator _idGenerator;
   final Backend _backend;
   final DiagnosticReporter _reporter;
 
-  DietParserTask(this._parserOptions, this._idGenerator, this._backend,
-      this._reporter, Measurer measurer)
+  DietParserTask(this._idGenerator, this._backend, this._reporter,
+      Measurer measurer)
       : super(measurer);
 
   final String name = 'Diet Parser';
@@ -33,7 +31,7 @@
           canUseNative: _backend.canLibraryUseNative(compilationUnit.library));
       ElementListener listener = new ElementListener(
           scannerOptions, _reporter, compilationUnit, _idGenerator);
-      PartialParser parser = new PartialParser(listener, _parserOptions);
+      PartialParser parser = new PartialParser(listener);
       try {
         parser.parseUnit(tokens);
       } on ParserError catch (_) {
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index 3cac037..8d6f580 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -5,7 +5,6 @@
 library dart2js.parser;
 
 import '../common.dart';
-import '../options.dart' show ParserOptions;
 import '../tokens/keyword.dart' show Keyword;
 import '../tokens/precedence.dart' show PrecedenceInfo;
 import '../tokens/precedence_constants.dart'
@@ -96,16 +95,10 @@
  */
 class Parser {
   final Listener listener;
-  final ParserOptions parserOptions;
   bool mayParseFunctionExpressions = true;
   bool asyncAwaitKeywordsEnabled;
 
-  final bool enableGenericMethodSyntax;
-
-  Parser(this.listener, ParserOptions parserOptions,
-      {this.asyncAwaitKeywordsEnabled: false})
-      : parserOptions = parserOptions,
-        enableGenericMethodSyntax = parserOptions.enableGenericMethodSyntax;
+  Parser(this.listener, {this.asyncAwaitKeywordsEnabled: false});
 
   Token parseUnit(Token token) {
     listener.beginCompilationUnit(token);
@@ -466,7 +459,7 @@
       listener.handleNoTypeVariables(token);
       token = parseFormalParameters(token);
       listener.handleFunctionTypedFormalParameter(token);
-    } else if (enableGenericMethodSyntax && optional('<', token)) {
+    } else if (optional('<', token)) {
       token = parseTypeVariablesOpt(token);
       token = parseFormalParameters(token);
       listener.handleFunctionTypedFormalParameter(token);
@@ -783,8 +776,7 @@
     listener.beginTypeVariable(token);
     token = parseIdentifier(token);
     Token extendsOrSuper = null;
-    if (optional('extends', token) ||
-        (enableGenericMethodSyntax && optional('super', token))) {
+    if (optional('extends', token) || optional('super', token)) {
       extendsOrSuper = token;
       token = parseType(token.next);
     } else {
@@ -1099,7 +1091,7 @@
     }
     Token token = parseIdentifier(name);
 
-    if (enableGenericMethodSyntax && getOrSet == null) {
+    if (getOrSet == null) {
       token = parseTypeVariablesOpt(token);
     } else {
       listener.handleNoTypeVariables(token);
@@ -1412,7 +1404,7 @@
           (identical(value, '.')) ||
           (identical(value, '{')) ||
           (identical(value, '=>')) ||
-          (enableGenericMethodSyntax && identical(value, '<'))) {
+          (identical(value, '<'))) {
         isField = false;
         break;
       } else if (identical(value, ';')) {
@@ -1507,7 +1499,7 @@
     }
 
     token = parseQualifiedRestOpt(token);
-    if (enableGenericMethodSyntax && getOrSet == null) {
+    if (getOrSet == null) {
       token = parseTypeVariablesOpt(token);
     } else {
       listener.handleNoTypeVariables(token);
@@ -1598,7 +1590,7 @@
     }
     token = parseQualifiedRestOpt(token);
     listener.endFunctionName(token);
-    if (enableGenericMethodSyntax && getOrSet == null) {
+    if (getOrSet == null) {
       token = parseTypeVariablesOpt(token);
     } else {
       listener.handleNoTypeVariables(token);
@@ -1643,11 +1635,7 @@
     listener.beginFunctionName(token);
     token = parseIdentifier(token);
     listener.endFunctionName(token);
-    if (enableGenericMethodSyntax) {
-      token = parseTypeVariablesOpt(token);
-    } else {
-      listener.handleNoTypeVariables(token);
-    }
+    token = parseTypeVariablesOpt(token);
     token = parseFormalParameters(token);
     listener.handleNoInitializers();
     bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
@@ -1879,8 +1867,7 @@
           // by '{', '=>', 'async', or 'sync'.
           return parseFunctionDeclaration(token);
         }
-      } else if (enableGenericMethodSyntax &&
-          identical(afterIdKind, LT_TOKEN)) {
+      } else if (identical(afterIdKind, LT_TOKEN)) {
         // We are looking at "type identifier '<'".
         BeginGroupToken beginAngle = afterId;
         Token endAngle = beginAngle.endGroup;
@@ -1915,7 +1902,7 @@
             identical(afterParens, 'sync')) {
           return parseFunctionDeclaration(token);
         }
-      } else if (enableGenericMethodSyntax && optional('<', token.next)) {
+      } else if (optional('<', token.next)) {
         BeginGroupToken beginAngle = token.next;
         Token endAngle = beginAngle.endGroup;
         if (endAngle != null &&
@@ -2360,8 +2347,7 @@
   Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) {
     assert(optional('<', token));
     BeginGroupToken begin = token;
-    if (enableGenericMethodSyntax &&
-        constKeyword == null &&
+    if (constKeyword == null &&
         begin.endGroup != null &&
         identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) {
       token = parseTypeVariablesOpt(token);
@@ -2404,7 +2390,7 @@
   }
 
   bool isFunctionDeclaration(Token token) {
-    if (enableGenericMethodSyntax && optional('<', token)) {
+    if (optional('<', token)) {
       BeginGroupToken begin = token;
       if (begin.endGroup == null) return false;
       token = begin.endGroup.next;
@@ -2553,7 +2539,7 @@
   Token parseSend(Token token) {
     listener.beginSend(token);
     token = parseIdentifier(token);
-    if (enableGenericMethodSyntax && isValidMethodTypeArguments(token)) {
+    if (isValidMethodTypeArguments(token)) {
       token = parseTypeArgumentsOpt(token);
     } else {
       listener.handleNoTypeArguments(token);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 07734b9..e6e8bfe 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -8,7 +8,6 @@
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart' show Compiler;
 import '../elements/modelx.dart' show ElementX;
-import '../options.dart' show ParserOptions;
 import '../tokens/token.dart' show Token;
 import '../tree/tree.dart' show Node;
 import 'element_listener.dart' show ScannerOptions;
@@ -17,12 +16,9 @@
 import 'parser.dart' show Parser;
 
 class ParserTask extends CompilerTask {
-  final ParserOptions parserOptions;
   final Compiler compiler;
 
-  ParserTask(Compiler compiler, this.parserOptions)
-      : compiler = compiler,
-        super(compiler.measurer);
+  ParserTask(Compiler compiler): compiler = compiler, super(compiler.measurer);
 
   String get name => 'Parser';
 
@@ -34,7 +30,7 @@
     return measure(() {
       NodeListener listener =
           new NodeListener(const ScannerOptions(), compiler.reporter, null);
-      Parser parser = new Parser(listener, parserOptions);
+      Parser parser = new Parser(listener);
       try {
         parser.parseUnit(token);
       } on ParserError catch (_) {
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
index 87cb2f1..1f37ff3 100644
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ b/pkg/compiler/lib/src/parser/partial_elements.dart
@@ -374,7 +374,7 @@
       parsing.measure(() {
         MemberListener listener = new MemberListener(
             parsing.getScannerOptionsFor(this), reporter, this);
-        Parser parser = new ClassElementParser(listener, parsing.parserOptions);
+        Parser parser = new ClassElementParser(listener);
         try {
           Token token = parser.parseTopLevelDeclaration(beginToken);
           assert(identical(token, endToken.next));
@@ -440,7 +440,7 @@
         if (partial.hasParseError) {
           listener.suppressParseErrors = true;
         }
-        doParse(new Parser(listener, parsing.parserOptions));
+        doParse(new Parser(listener));
       } on ParserError catch (e) {
         partial.hasParseError = true;
         return new ErrorNode(element.position, e.reason);
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 3e2c025..c5d9d62 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -5,7 +5,6 @@
 library dart2js.parser.partial;
 
 import '../common.dart';
-import '../options.dart' show ParserOptions;
 import '../tokens/token.dart' show BeginGroupToken, ErrorToken, Token;
 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
 import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
@@ -13,8 +12,7 @@
 import 'parser.dart' show Parser;
 
 class PartialParser extends Parser {
-  PartialParser(Listener listener, ParserOptions options)
-      : super(listener, options);
+  PartialParser(Listener listener): super(listener);
 
   Token parseClassBody(Token token) => skipClassBody(token);
 
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 4e6ea8c..da76073 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -133,7 +133,6 @@
 import 'id_generator.dart';
 import 'js_backend/js_backend.dart' show JavaScriptBackend;
 import 'library_loader.dart' show LibraryLoader;
-import 'options.dart' show ParserOptions;
 import 'parser/element_listener.dart' show ElementListener;
 import 'parser/listener.dart' show Listener, ParserError;
 import 'parser/member_listener.dart' show MemberListener;
@@ -146,13 +145,11 @@
 
 class PatchParserTask extends CompilerTask {
   final String name = "Patching Parser";
-  final ParserOptions parserOptions;
   final Compiler compiler;
   DiagnosticReporter get reporter => compiler.reporter;
 
-  PatchParserTask(Compiler compiler, this.parserOptions)
-      : compiler = compiler,
-        super(compiler.measurer);
+  PatchParserTask(Compiler compiler)
+      : compiler = compiler, super(compiler.measurer);
 
   /**
    * Scans a library patch file, applies the method patches and
@@ -184,7 +181,7 @@
       Listener patchListener = new PatchElementListener(
           compiler, compilationUnit, compiler.idGenerator);
       try {
-        new PartialParser(patchListener, parserOptions).parseUnit(tokens);
+        new PartialParser(patchListener).parseUnit(tokens);
       } on ParserError catch (e) {
         // No need to recover from a parser error in platform libraries, user
         // will never see this if the libraries are tested correctly.
@@ -201,7 +198,7 @@
 
     measure(() => reporter.withCurrentElement(cls, () {
           MemberListener listener = new PatchMemberListener(compiler, cls);
-          Parser parser = new PatchClassElementParser(listener, parserOptions);
+          Parser parser = new PatchClassElementParser(listener);
           try {
             Token token = parser.parseTopLevelDeclaration(cls.beginToken);
             assert(identical(token, cls.endToken.next));
@@ -251,8 +248,7 @@
  * declarations.
  */
 class PatchClassElementParser extends PartialParser {
-  PatchClassElementParser(Listener listener, ParserOptions options)
-      : super(listener, options);
+  PatchClassElementParser(Listener listener): super(listener);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 4a37428..ae51c80 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -294,8 +294,7 @@
    * Resolve all initializers of this constructor. In the case of a redirecting
    * constructor, the resolved constructor's function element is returned.
    */
-  ConstructorElement resolveInitializers(
-      {bool enableInitializingFormalAccess: false}) {
+  ConstructorElement resolveInitializers() {
     Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
         <dynamic /*String|int*/, ConstantExpression>{};
     ConstructedConstantExpression constructorInvocation;
@@ -303,12 +302,10 @@
     // that we can ensure that fields are initialized only once.
     FunctionSignature functionParameters = constructor.functionSignature;
     Scope oldScope = visitor.scope;
-    if (enableInitializingFormalAccess) {
-      // In order to get the correct detection of name clashes between all
-      // parameters (regular ones and initializing formals) we must extend
-      // the parameter scope rather than adding a new nested scope.
-      visitor.scope = new ExtensionScope(visitor.scope);
-    }
+    // In order to get the correct detection of name clashes between all
+    // parameters (regular ones and initializing formals) we must extend
+    // the parameter scope rather than adding a new nested scope.
+    visitor.scope = new ExtensionScope(visitor.scope);
     Link<Node> parameterNodes = (functionNode.parameters == null)
         ? const Link<Node>()
         : functionNode.parameters.nodes;
@@ -349,10 +346,8 @@
           registry.registerStaticUse(new StaticUse.fieldInit(field));
         }
         checkForDuplicateInitializers(field, element.initializer);
-        if (enableInitializingFormalAccess) {
-          visitor.defineLocalVariable(parameterNode, initializingFormal);
-          visitor.addToScope(initializingFormal);
-        }
+        visitor.defineLocalVariable(parameterNode, initializingFormal);
+        visitor.addToScope(initializingFormal);
         if (isConst) {
           if (element.isNamed) {
             fieldInitializers[field] = new NamedArgumentReference(element.name);
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 27f164f..f566e40 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -2573,8 +2573,7 @@
       } else {
         semantics = new StaticAccess.parameter(element);
       }
-    } else if (element.isInitializingFormal &&
-        options.enableInitializingFormalAccess) {
+    } else if (element.isInitializingFormal) {
       error = reportAndCreateErroneousElement(node.selector, name.text,
           MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
       semantics = new StaticAccess.finalParameter(element);
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index ebea1af..d5334f1 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -247,9 +247,7 @@
         // resolution in case there is an implicit super constructor call.
         InitializerResolver resolver =
             new InitializerResolver(visitor, element, tree);
-        FunctionElement redirection = resolver.resolveInitializers(
-            enableInitializingFormalAccess:
-                options.enableInitializingFormalAccess);
+        FunctionElement redirection = resolver.resolveInitializers();
         if (redirection != null) {
           resolveRedirectingConstructor(resolver, tree, element, redirection);
         }
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index c3ef366..c839c95 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -400,7 +400,7 @@
               parsing.getScannerOptionsFor(element), reporter, null);
           listener.memberErrors = listener.memberErrors.prepend(false);
           try {
-            Parser parser = new Parser(listener, parsing.parserOptions);
+            Parser parser = new Parser(listener);
             parse(parser);
           } on ParserError catch (e) {
             reporter.internalError(element, '$e');
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 8ea98e3..3addf4b 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -9,7 +9,12 @@
 import '../common/names.dart';
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart';
-import '../constants/values.dart' show StringConstantValue;
+import '../constants/values.dart'
+    show
+        ConstantValue,
+        InterceptorConstantValue,
+        StringConstantValue,
+        TypeConstantValue;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../io/source_information.dart';
@@ -81,6 +86,9 @@
   LoopHandler<ir.Node> loopHandler;
   TypeBuilder typeBuilder;
 
+  final Map<ir.VariableDeclaration, HInstruction> letBindings =
+      <ir.VariableDeclaration, HInstruction>{};
+
   KernelSsaBuilder(
       this.targetElement,
       this.resolvedAst,
@@ -868,6 +876,24 @@
   }
 
   @override
+  void visitTypeLiteral(ir.TypeLiteral typeLiteral) {
+    ir.DartType type = typeLiteral.type;
+    if (type is ir.InterfaceType) {
+      ConstantValue constant = astAdapter.getConstantForType(type);
+      stack.add(graph.addConstant(constant, compiler));
+      return;
+    }
+    if (type is ir.TypeParameterType) {
+      // TODO(27394): Load type parameter from current 'this' object.
+      defaultExpression(typeLiteral);
+      return;
+    }
+    // TODO(27394): 'dynamic' and function types observed. Where are they from?
+    defaultExpression(typeLiteral);
+    return;
+  }
+
+  @override
   void visitStaticGet(ir.StaticGet staticGet) {
     ir.Member staticTarget = staticGet.target;
     if (staticTarget is ir.Procedure &&
@@ -916,11 +942,32 @@
 
   @override
   void visitVariableGet(ir.VariableGet variableGet) {
+    ir.VariableDeclaration variable = variableGet.variable;
+    HInstruction letBinding = letBindings[variable];
+    if (letBinding != null) {
+      stack.add(letBinding);
+      return;
+    }
+
     Local local = astAdapter.getLocal(variableGet.variable);
     stack.add(localsHandler.readLocal(local));
   }
 
   @override
+  void visitPropertySet(ir.PropertySet propertySet) {
+    propertySet.receiver.accept(this);
+    HInstruction receiver = pop();
+    propertySet.value.accept(this);
+    HInstruction value = pop();
+
+    _pushDynamicInvocation(propertySet, astAdapter.typeOfSet(propertySet),
+        <HInstruction>[receiver, value]);
+
+    pop();
+    stack.add(value);
+  }
+
+  @override
   void visitVariableSet(ir.VariableSet variableSet) {
     variableSet.value.accept(this);
     HInstruction value = pop();
@@ -961,6 +1008,16 @@
             value, astAdapter.getDartType(variable.type)));
   }
 
+  @override
+  void visitLet(ir.Let let) {
+    ir.VariableDeclaration variable = let.variable;
+    variable.initializer.accept(this);
+    HInstruction initializedValue = pop();
+    // TODO(sra): Apply inferred type information.
+    letBindings[variable] = initializedValue;
+    let.body.accept(this);
+  }
+
   // TODO(het): Also extract type arguments
   /// Extracts the list of instructions for the expressions in the arguments.
   List<HInstruction> _visitArguments(ir.Arguments arguments) {
@@ -1311,7 +1368,30 @@
   }
 
   void handleJsInterceptorConstant(ir.StaticInvocation invocation) {
-    unhandledForeign(invocation);
+    // Single argument must be a TypeConstant which is converted into a
+    // InterceptorConstant.
+    if (_unexpectedForeignArguments(invocation, 1, 1)) {
+      stack.add(graph.addConstantNull(compiler)); // Result expected on stack.
+      return;
+    }
+    ir.Expression argument = invocation.arguments.positional.single;
+    argument.accept(this);
+    HInstruction argumentInstruction = pop();
+    if (argumentInstruction is HConstant) {
+      ConstantValue argumentConstant = argumentInstruction.constant;
+      if (argumentConstant is TypeConstantValue) {
+        // TODO(sra): Check that type is a subclass of [Interceptor].
+        ConstantValue constant =
+            new InterceptorConstantValue(argumentConstant.representedType);
+        HInstruction instruction = graph.addConstant(constant, compiler);
+        stack.add(instruction);
+        return;
+      }
+    }
+
+    compiler.reporter.reportErrorMessage(astAdapter.getNode(invocation),
+        MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
+    stack.add(graph.addConstantNull(compiler));
   }
 
   void handleForeignJs(ir.StaticInvocation invocation) {
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
index 028b7a8..6d8943d 100644
--- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -96,7 +96,8 @@
 
   ast.Node getNode(ir.Node node) {
     ast.Node result = _nodeToAst[node];
-    assert(result != null);
+    assert(invariant(CURRENT_ELEMENT_SPANNABLE, result != null,
+        message: "No node found for $node"));
     return result;
   }
 
@@ -144,6 +145,7 @@
 
   Selector getSelector(ir.Expression node) {
     if (node is ir.PropertyGet) return getGetterSelector(node);
+    if (node is ir.PropertySet) return getSetterSelector(node);
     if (node is ir.InvocationExpression) return getInvocationSelector(node);
     _compiler.reporter.internalError(getNode(node),
         "Can only get the selector for a property get or an invocation.");
@@ -174,7 +176,18 @@
     return new Selector.getter(name);
   }
 
+  Selector getSetterSelector(ir.PropertySet setter) {
+    ir.Name irName = setter.name;
+    Name name = new Name(
+        irName.name, irName.isPrivate ? getElement(irName.library) : null);
+    return new Selector.setter(name);
+  }
+
   TypeMask typeOfInvocation(ir.Expression send) {
+    ast.Node operatorNode = kernel.nodeToAstOperator[send];
+    if (operatorNode != null) {
+      return _resultOf(_target).typeOfOperator(operatorNode);
+    }
     return _resultOf(_target).typeOfSend(getNode(send));
   }
 
@@ -182,6 +195,10 @@
     return _resultOf(_target).typeOfSend(getNode(getter));
   }
 
+  TypeMask typeOfSet(ir.PropertySet setter) {
+    return _compiler.closedWorld.commonMasks.dynamicType;
+  }
+
   TypeMask typeOfSend(ir.Expression send) {
     assert(send is ir.InvocationExpression || send is ir.PropertyGet);
     return _resultOf(_target).typeOfSend(getNode(send));
@@ -255,6 +272,11 @@
     return constantValue;
   }
 
+  ConstantValue getConstantForType(ir.DartType irType) {
+    DartType type = getDartType(irType);
+    return _backend.constantSystem.createType(_compiler, type.asRaw());
+  }
+
   bool isIntercepted(ir.Node node) {
     Selector selector = getSelector(node);
     return _backend.isInterceptedSelector(selector);
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 3cf8a56..74831e1 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -686,11 +686,7 @@
           message: 'Missing element for identifier'));
       assert(invariant(
           node,
-          element.isVariable ||
-              element.isRegularParameter ||
-              element.isField ||
-              (element.isInitializingFormal &&
-                  compiler.options.enableInitializingFormalAccess),
+          element.isVariable || element.isParameter || element.isField,
           message: 'Unexpected context element ${element}'));
       return element.computeType(resolution);
     }
@@ -775,10 +771,7 @@
       return access;
     }
     if (receiverElement != null &&
-        (receiverElement.isVariable ||
-            receiverElement.isRegularParameter ||
-            (receiverElement.isInitializingFormal &&
-                compiler.options.enableInitializingFormalAccess))) {
+        (receiverElement.isVariable || receiverElement.isParameter)) {
       Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement];
       if (typePromotions != null) {
         while (!typePromotions.isEmpty) {
@@ -1095,10 +1088,7 @@
   }
 
   ElementAccess createPromotedAccess(Element element) {
-    if (element.isVariable ||
-        element.isRegularParameter ||
-        (element.isInitializingFormal &&
-            compiler.options.enableInitializingFormalAccess)) {
+    if (element.isVariable || element.isParameter) {
       TypePromotion typePromotion = getKnownTypePromotion(element);
       if (typePromotion != null) {
         return new PromotedAccess(element, typePromotion.type);
@@ -1215,11 +1205,7 @@
           }
         }
 
-        if (variable != null &&
-            (variable.isVariable ||
-                variable.isRegularParameter ||
-                (variable.isInitializingFormal &&
-                    compiler.options.enableInitializingFormalAccess))) {
+        if (variable != null && (variable.isVariable || variable.isParameter)) {
           DartType knownType = getKnownType(variable);
           if (!knownType.isDynamic) {
             DartType shownType = elements.getType(node.arguments.head);
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 19bd26e..07f759a 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -12,7 +12,7 @@
   js_runtime:
     path: ../../sdk/lib/_internal/js_runtime
   kernel:
-    path: ../../third_party/pkg/kernel
+    path: ../../pkg/kernel
   sdk_library_metadata:
     path: ../../sdk/lib/_internal/sdk_library_metadata
   dart2js_info: ^0.3.0
diff --git a/pkg/compiler/tool/perf.dart b/pkg/compiler/tool/perf.dart
index 348570d..7705061 100644
--- a/pkg/compiler/tool/perf.dart
+++ b/pkg/compiler/tool/perf.dart
@@ -18,7 +18,6 @@
 import 'package:compiler/src/diagnostics/messages.dart'
     show Message, MessageTemplate;
 import 'package:compiler/src/io/source_file.dart';
-import 'package:compiler/src/options.dart' show ParserOptions;
 import 'package:compiler/src/options.dart';
 import 'package:compiler/src/parser/element_listener.dart' show ScannerOptions;
 import 'package:compiler/src/parser/listener.dart';
@@ -182,7 +181,7 @@
 Set<String> parseDirectives(SourceFile source) {
   var tokens = tokenize(source);
   var listener = new DirectiveListener();
-  new PartialParser(listener, const _ParserOptions()).parseUnit(tokens);
+  new PartialParser(listener).parseUnit(tokens);
   return listener.targets;
 }
 
@@ -191,7 +190,7 @@
   var tokens = tokenize(source);
   NodeListener listener = new NodeListener(
       const ScannerOptions(canUseNative: true), new FakeReporter(), null);
-  Parser parser = new Parser(listener, const _ParserOptions());
+  Parser parser = new Parser(listener);
   parser.parseUnit(tokens);
   return listener.popNode();
 }
@@ -333,11 +332,6 @@
   }
 }
 
-class _ParserOptions implements ParserOptions {
-  const _ParserOptions();
-  bool get enableGenericMethodSyntax => true;
-}
-
 generateKernel(Uri entryUri) async {
   var timer = new Stopwatch()..start();
   var options = new CompilerOptions(
diff --git a/pkg/dev_compiler/CHANGELOG.md b/pkg/dev_compiler/CHANGELOG.md
index 9633a3d..e7da8f1 100644
--- a/pkg/dev_compiler/CHANGELOG.md
+++ b/pkg/dev_compiler/CHANGELOG.md
@@ -4,6 +4,7 @@
 - add support for AMD modules and make it the default.
 - precompile the SDK in AMD, CommonJS, and ES6 flavors.
 - legacy module format is deprecated.
+- remove --package-paths option
 
 ## 0.1.24
 - workaround breaking change on requestAnimationFrame
diff --git a/pkg/dev_compiler/lib/js/amd/dart_sdk.js b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
index 2b7e741..7252d35 100644
--- a/pkg/dev_compiler/lib/js/amd/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
@@ -1147,6 +1147,23 @@
     }
     return type[dart._typeObject] = new dart.WrappedType(type);
   };
+  dart.lazyJSType = function(getJSTypeCallback, name) {
+    let key = getJSTypeCallback.toString();
+    if (dart._lazyJSTypes.has(key)) {
+      return dart._lazyJSTypes.get(key);
+    }
+    let ret = new dart.LazyJSType(getJSTypeCallback, name);
+    dart._lazyJSTypes.set(key, ret);
+    return ret;
+  };
+  dart.lazyAnonymousJSType = function(name) {
+    if (dart._lazyJSTypes.has(name)) {
+      return dart._lazyJSTypes.get(name);
+    }
+    let ret = new dart.LazyJSType(null, name);
+    dart._lazyJSTypes.set(name, ret);
+    return ret;
+  };
   const _wrappedType = Symbol('_wrappedType');
   dart.unwrapType = function(obj) {
     return dart.dload(obj, _wrappedType);
@@ -1169,6 +1186,26 @@
   dart.tagLazy = function(value, compute) {
     dart.defineLazyProperty(value, dart._runtimeType, {get: compute});
   };
+  const _jsTypeCallback = Symbol('_jsTypeCallback');
+  const _rawJSType = Symbol('_rawJSType');
+  dart._isInstanceOfLazyJSType = function(o, t) {
+    if (t[_jsTypeCallback] != null) {
+      return dart.is(o, t[_rawJSType]);
+    }
+    if (o == null) return false;
+    return dart._isJSObject(o);
+  };
+  dart._asInstanceOfLazyJSType = function(o, t) {
+    if (t[_jsTypeCallback] != null) {
+      return dart.as(o, t[_rawJSType]);
+    }
+    if (o == null) return null;
+    if (!dart.test(dart._isJSObject(o))) dart._throwCastError(o, t, true);
+    return o;
+  };
+  dart._isJSObject = function(o) {
+    return !dart.getReifiedType(o)[dart._runtimeType];
+  };
   dart._initialize2 = function() {
     dart.TypeRep.prototype.is = function is_T(object) {
       return dart.is(object, this);
@@ -1188,6 +1225,12 @@
     dart.Dynamic.prototype._check = function check_Dynamic(object) {
       return object;
     };
+    dart.LazyJSType.prototype.is = function is_T(object) {
+      return dart._isInstanceOfLazyJSType(object, this);
+    };
+    dart.LazyJSType.prototype.as = function as_T(object) {
+      return dart._asInstanceOfLazyJSType(object, this);
+    };
   };
   dart._functionType = function(definite, returnType, args, extra) {
     if (args === void 0 && extra === void 0) {
@@ -1250,6 +1293,11 @@
   dart.isFunctionType = function(type) {
     return type instanceof dart.AbstractFunctionType || type === core.Function;
   };
+  dart.isLazyJSSubtype = function(t1, t2, covariant) {
+    if (dart.equals(t1, t2)) return true;
+    if (t1[_jsTypeCallback] == null || t2[_jsTypeCallback] == null) return true;
+    return dart.isClassSubType(t1[_rawJSType], t2[_rawJSType], covariant);
+  };
   dart.isFunctionSubtype = function(ft1, ft2, covariant) {
     if (ft2 === core.Function) {
       return true;
@@ -1345,6 +1393,9 @@
     if (dart.isFunctionType(t1) && dart.isFunctionType(t2)) {
       return dart.isFunctionSubtype(t1, t2, covariant);
     }
+    if (t1 instanceof dart.LazyJSType && t2 instanceof dart.LazyJSType) {
+      return dart.isLazyJSSubtype(t1, t2, covariant);
+    }
     return false;
   };
   dart.isClassSubType = function(t1, t2, covariant) {
@@ -2066,6 +2117,12 @@
   dart.dartx = dartx;
   dart._runtimeType = Symbol("_runtimeType");
   dart.isNamedConstructor = Symbol("isNamedConstructor");
+  dart.defineLazy(dart, {
+    get _lazyJSTypes() {
+      return new Map();
+    },
+    set _lazyJSTypes(_) {}
+  });
   dart.metadata = Symbol("metadata");
   dart._typeObject = Symbol("typeObject");
   core.Object = class Object {
@@ -2136,6 +2193,28 @@
       return 'dynamic';
     }
   };
+  const _dartName = Symbol('_dartName');
+  dart.LazyJSType = class LazyJSType extends core.Object {
+    new(jsTypeCallback, dartName) {
+      this[_jsTypeCallback] = jsTypeCallback;
+      this[_dartName] = dartName;
+    }
+    get [_rawJSType]() {
+      return this[_jsTypeCallback]();
+    }
+    toString() {
+      return core.String._check(this[_jsTypeCallback] != null ? dart.typeName(this[_rawJSType]) : this[_dartName]);
+    }
+  };
+  dart.LazyJSType[dart.implements] = () => [core.Type];
+  dart.setSignature(dart.LazyJSType, {
+    constructors: () => ({new: dart.definiteFunctionType(dart.LazyJSType, [dart.dynamic, dart.dynamic])}),
+    fields: () => ({
+      [_jsTypeCallback]: dart.dynamic,
+      [_dartName]: dart.dynamic
+    }),
+    getters: () => ({[_rawJSType]: dart.definiteFunctionType(dart.dynamic, [])})
+  });
   dart.dynamic = new dart.Dynamic();
   dart._initialize = dart._initialize2();
   dart.Void = class Void extends dart.TypeRep {
diff --git a/pkg/dev_compiler/lib/js/common/dart_sdk.js b/pkg/dev_compiler/lib/js/common/dart_sdk.js
index 274a113..2656bda 100644
--- a/pkg/dev_compiler/lib/js/common/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/common/dart_sdk.js
@@ -1147,6 +1147,23 @@
     }
     return type[dart._typeObject] = new dart.WrappedType(type);
   };
+  dart.lazyJSType = function(getJSTypeCallback, name) {
+    let key = getJSTypeCallback.toString();
+    if (dart._lazyJSTypes.has(key)) {
+      return dart._lazyJSTypes.get(key);
+    }
+    let ret = new dart.LazyJSType(getJSTypeCallback, name);
+    dart._lazyJSTypes.set(key, ret);
+    return ret;
+  };
+  dart.lazyAnonymousJSType = function(name) {
+    if (dart._lazyJSTypes.has(name)) {
+      return dart._lazyJSTypes.get(name);
+    }
+    let ret = new dart.LazyJSType(null, name);
+    dart._lazyJSTypes.set(name, ret);
+    return ret;
+  };
   const _wrappedType = Symbol('_wrappedType');
   dart.unwrapType = function(obj) {
     return dart.dload(obj, _wrappedType);
@@ -1169,6 +1186,26 @@
   dart.tagLazy = function(value, compute) {
     dart.defineLazyProperty(value, dart._runtimeType, {get: compute});
   };
+  const _jsTypeCallback = Symbol('_jsTypeCallback');
+  const _rawJSType = Symbol('_rawJSType');
+  dart._isInstanceOfLazyJSType = function(o, t) {
+    if (t[_jsTypeCallback] != null) {
+      return dart.is(o, t[_rawJSType]);
+    }
+    if (o == null) return false;
+    return dart._isJSObject(o);
+  };
+  dart._asInstanceOfLazyJSType = function(o, t) {
+    if (t[_jsTypeCallback] != null) {
+      return dart.as(o, t[_rawJSType]);
+    }
+    if (o == null) return null;
+    if (!dart.test(dart._isJSObject(o))) dart._throwCastError(o, t, true);
+    return o;
+  };
+  dart._isJSObject = function(o) {
+    return !dart.getReifiedType(o)[dart._runtimeType];
+  };
   dart._initialize2 = function() {
     dart.TypeRep.prototype.is = function is_T(object) {
       return dart.is(object, this);
@@ -1188,6 +1225,12 @@
     dart.Dynamic.prototype._check = function check_Dynamic(object) {
       return object;
     };
+    dart.LazyJSType.prototype.is = function is_T(object) {
+      return dart._isInstanceOfLazyJSType(object, this);
+    };
+    dart.LazyJSType.prototype.as = function as_T(object) {
+      return dart._asInstanceOfLazyJSType(object, this);
+    };
   };
   dart._functionType = function(definite, returnType, args, extra) {
     if (args === void 0 && extra === void 0) {
@@ -1250,6 +1293,11 @@
   dart.isFunctionType = function(type) {
     return type instanceof dart.AbstractFunctionType || type === core.Function;
   };
+  dart.isLazyJSSubtype = function(t1, t2, covariant) {
+    if (dart.equals(t1, t2)) return true;
+    if (t1[_jsTypeCallback] == null || t2[_jsTypeCallback] == null) return true;
+    return dart.isClassSubType(t1[_rawJSType], t2[_rawJSType], covariant);
+  };
   dart.isFunctionSubtype = function(ft1, ft2, covariant) {
     if (ft2 === core.Function) {
       return true;
@@ -1345,6 +1393,9 @@
     if (dart.isFunctionType(t1) && dart.isFunctionType(t2)) {
       return dart.isFunctionSubtype(t1, t2, covariant);
     }
+    if (t1 instanceof dart.LazyJSType && t2 instanceof dart.LazyJSType) {
+      return dart.isLazyJSSubtype(t1, t2, covariant);
+    }
     return false;
   };
   dart.isClassSubType = function(t1, t2, covariant) {
@@ -2066,6 +2117,12 @@
   dart.dartx = dartx;
   dart._runtimeType = Symbol("_runtimeType");
   dart.isNamedConstructor = Symbol("isNamedConstructor");
+  dart.defineLazy(dart, {
+    get _lazyJSTypes() {
+      return new Map();
+    },
+    set _lazyJSTypes(_) {}
+  });
   dart.metadata = Symbol("metadata");
   dart._typeObject = Symbol("typeObject");
   core.Object = class Object {
@@ -2136,6 +2193,28 @@
       return 'dynamic';
     }
   };
+  const _dartName = Symbol('_dartName');
+  dart.LazyJSType = class LazyJSType extends core.Object {
+    new(jsTypeCallback, dartName) {
+      this[_jsTypeCallback] = jsTypeCallback;
+      this[_dartName] = dartName;
+    }
+    get [_rawJSType]() {
+      return this[_jsTypeCallback]();
+    }
+    toString() {
+      return core.String._check(this[_jsTypeCallback] != null ? dart.typeName(this[_rawJSType]) : this[_dartName]);
+    }
+  };
+  dart.LazyJSType[dart.implements] = () => [core.Type];
+  dart.setSignature(dart.LazyJSType, {
+    constructors: () => ({new: dart.definiteFunctionType(dart.LazyJSType, [dart.dynamic, dart.dynamic])}),
+    fields: () => ({
+      [_jsTypeCallback]: dart.dynamic,
+      [_dartName]: dart.dynamic
+    }),
+    getters: () => ({[_rawJSType]: dart.definiteFunctionType(dart.dynamic, [])})
+  });
   dart.dynamic = new dart.Dynamic();
   dart._initialize = dart._initialize2();
   dart.Void = class Void extends dart.TypeRep {
diff --git a/pkg/dev_compiler/lib/js/es6/dart_sdk.js b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
index 17bea27..754189c 100644
--- a/pkg/dev_compiler/lib/js/es6/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
@@ -1145,6 +1145,23 @@
   }
   return type[dart._typeObject] = new dart.WrappedType(type);
 };
+dart.lazyJSType = function(getJSTypeCallback, name) {
+  let key = getJSTypeCallback.toString();
+  if (dart._lazyJSTypes.has(key)) {
+    return dart._lazyJSTypes.get(key);
+  }
+  let ret = new dart.LazyJSType(getJSTypeCallback, name);
+  dart._lazyJSTypes.set(key, ret);
+  return ret;
+};
+dart.lazyAnonymousJSType = function(name) {
+  if (dart._lazyJSTypes.has(name)) {
+    return dart._lazyJSTypes.get(name);
+  }
+  let ret = new dart.LazyJSType(null, name);
+  dart._lazyJSTypes.set(name, ret);
+  return ret;
+};
 const _wrappedType = Symbol('_wrappedType');
 dart.unwrapType = function(obj) {
   return dart.dload(obj, _wrappedType);
@@ -1167,6 +1184,26 @@
 dart.tagLazy = function(value, compute) {
   dart.defineLazyProperty(value, dart._runtimeType, {get: compute});
 };
+const _jsTypeCallback = Symbol('_jsTypeCallback');
+const _rawJSType = Symbol('_rawJSType');
+dart._isInstanceOfLazyJSType = function(o, t) {
+  if (t[_jsTypeCallback] != null) {
+    return dart.is(o, t[_rawJSType]);
+  }
+  if (o == null) return false;
+  return dart._isJSObject(o);
+};
+dart._asInstanceOfLazyJSType = function(o, t) {
+  if (t[_jsTypeCallback] != null) {
+    return dart.as(o, t[_rawJSType]);
+  }
+  if (o == null) return null;
+  if (!dart.test(dart._isJSObject(o))) dart._throwCastError(o, t, true);
+  return o;
+};
+dart._isJSObject = function(o) {
+  return !dart.getReifiedType(o)[dart._runtimeType];
+};
 dart._initialize2 = function() {
   dart.TypeRep.prototype.is = function is_T(object) {
     return dart.is(object, this);
@@ -1186,6 +1223,12 @@
   dart.Dynamic.prototype._check = function check_Dynamic(object) {
     return object;
   };
+  dart.LazyJSType.prototype.is = function is_T(object) {
+    return dart._isInstanceOfLazyJSType(object, this);
+  };
+  dart.LazyJSType.prototype.as = function as_T(object) {
+    return dart._asInstanceOfLazyJSType(object, this);
+  };
 };
 dart._functionType = function(definite, returnType, args, extra) {
   if (args === void 0 && extra === void 0) {
@@ -1248,6 +1291,11 @@
 dart.isFunctionType = function(type) {
   return type instanceof dart.AbstractFunctionType || type === core.Function;
 };
+dart.isLazyJSSubtype = function(t1, t2, covariant) {
+  if (dart.equals(t1, t2)) return true;
+  if (t1[_jsTypeCallback] == null || t2[_jsTypeCallback] == null) return true;
+  return dart.isClassSubType(t1[_rawJSType], t2[_rawJSType], covariant);
+};
 dart.isFunctionSubtype = function(ft1, ft2, covariant) {
   if (ft2 === core.Function) {
     return true;
@@ -1343,6 +1391,9 @@
   if (dart.isFunctionType(t1) && dart.isFunctionType(t2)) {
     return dart.isFunctionSubtype(t1, t2, covariant);
   }
+  if (t1 instanceof dart.LazyJSType && t2 instanceof dart.LazyJSType) {
+    return dart.isLazyJSSubtype(t1, t2, covariant);
+  }
   return false;
 };
 dart.isClassSubType = function(t1, t2, covariant) {
@@ -2064,6 +2115,12 @@
 dart.dartx = dartx;
 dart._runtimeType = Symbol("_runtimeType");
 dart.isNamedConstructor = Symbol("isNamedConstructor");
+dart.defineLazy(dart, {
+  get _lazyJSTypes() {
+    return new Map();
+  },
+  set _lazyJSTypes(_) {}
+});
 dart.metadata = Symbol("metadata");
 dart._typeObject = Symbol("typeObject");
 core.Object = class Object {
@@ -2134,6 +2191,28 @@
     return 'dynamic';
   }
 };
+const _dartName = Symbol('_dartName');
+dart.LazyJSType = class LazyJSType extends core.Object {
+  new(jsTypeCallback, dartName) {
+    this[_jsTypeCallback] = jsTypeCallback;
+    this[_dartName] = dartName;
+  }
+  get [_rawJSType]() {
+    return this[_jsTypeCallback]();
+  }
+  toString() {
+    return core.String._check(this[_jsTypeCallback] != null ? dart.typeName(this[_rawJSType]) : this[_dartName]);
+  }
+};
+dart.LazyJSType[dart.implements] = () => [core.Type];
+dart.setSignature(dart.LazyJSType, {
+  constructors: () => ({new: dart.definiteFunctionType(dart.LazyJSType, [dart.dynamic, dart.dynamic])}),
+  fields: () => ({
+    [_jsTypeCallback]: dart.dynamic,
+    [_dartName]: dart.dynamic
+  }),
+  getters: () => ({[_rawJSType]: dart.definiteFunctionType(dart.dynamic, [])})
+});
 dart.dynamic = new dart.Dynamic();
 dart._initialize = dart._initialize2();
 dart.Void = class Void extends dart.TypeRep {
diff --git a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
index 8a6f13e..c9d9c75 100644
--- a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
@@ -1148,6 +1148,23 @@
     }
     return type[dart._typeObject] = new dart.WrappedType(type);
   };
+  dart.lazyJSType = function(getJSTypeCallback, name) {
+    let key = getJSTypeCallback.toString();
+    if (dart._lazyJSTypes.has(key)) {
+      return dart._lazyJSTypes.get(key);
+    }
+    let ret = new dart.LazyJSType(getJSTypeCallback, name);
+    dart._lazyJSTypes.set(key, ret);
+    return ret;
+  };
+  dart.lazyAnonymousJSType = function(name) {
+    if (dart._lazyJSTypes.has(name)) {
+      return dart._lazyJSTypes.get(name);
+    }
+    let ret = new dart.LazyJSType(null, name);
+    dart._lazyJSTypes.set(name, ret);
+    return ret;
+  };
   const _wrappedType = Symbol('_wrappedType');
   dart.unwrapType = function(obj) {
     return dart.dload(obj, _wrappedType);
@@ -1170,6 +1187,26 @@
   dart.tagLazy = function(value, compute) {
     dart.defineLazyProperty(value, dart._runtimeType, {get: compute});
   };
+  const _jsTypeCallback = Symbol('_jsTypeCallback');
+  const _rawJSType = Symbol('_rawJSType');
+  dart._isInstanceOfLazyJSType = function(o, t) {
+    if (t[_jsTypeCallback] != null) {
+      return dart.is(o, t[_rawJSType]);
+    }
+    if (o == null) return false;
+    return dart._isJSObject(o);
+  };
+  dart._asInstanceOfLazyJSType = function(o, t) {
+    if (t[_jsTypeCallback] != null) {
+      return dart.as(o, t[_rawJSType]);
+    }
+    if (o == null) return null;
+    if (!dart.test(dart._isJSObject(o))) dart._throwCastError(o, t, true);
+    return o;
+  };
+  dart._isJSObject = function(o) {
+    return !dart.getReifiedType(o)[dart._runtimeType];
+  };
   dart._initialize2 = function() {
     dart.TypeRep.prototype.is = function is_T(object) {
       return dart.is(object, this);
@@ -1189,6 +1226,12 @@
     dart.Dynamic.prototype._check = function check_Dynamic(object) {
       return object;
     };
+    dart.LazyJSType.prototype.is = function is_T(object) {
+      return dart._isInstanceOfLazyJSType(object, this);
+    };
+    dart.LazyJSType.prototype.as = function as_T(object) {
+      return dart._asInstanceOfLazyJSType(object, this);
+    };
   };
   dart._functionType = function(definite, returnType, args, extra) {
     if (args === void 0 && extra === void 0) {
@@ -1251,6 +1294,11 @@
   dart.isFunctionType = function(type) {
     return type instanceof dart.AbstractFunctionType || type === core.Function;
   };
+  dart.isLazyJSSubtype = function(t1, t2, covariant) {
+    if (dart.equals(t1, t2)) return true;
+    if (t1[_jsTypeCallback] == null || t2[_jsTypeCallback] == null) return true;
+    return dart.isClassSubType(t1[_rawJSType], t2[_rawJSType], covariant);
+  };
   dart.isFunctionSubtype = function(ft1, ft2, covariant) {
     if (ft2 === core.Function) {
       return true;
@@ -1346,6 +1394,9 @@
     if (dart.isFunctionType(t1) && dart.isFunctionType(t2)) {
       return dart.isFunctionSubtype(t1, t2, covariant);
     }
+    if (t1 instanceof dart.LazyJSType && t2 instanceof dart.LazyJSType) {
+      return dart.isLazyJSSubtype(t1, t2, covariant);
+    }
     return false;
   };
   dart.isClassSubType = function(t1, t2, covariant) {
@@ -2067,6 +2118,12 @@
   dart.dartx = dartx;
   dart._runtimeType = Symbol("_runtimeType");
   dart.isNamedConstructor = Symbol("isNamedConstructor");
+  dart.defineLazy(dart, {
+    get _lazyJSTypes() {
+      return new Map();
+    },
+    set _lazyJSTypes(_) {}
+  });
   dart.metadata = Symbol("metadata");
   dart._typeObject = Symbol("typeObject");
   core.Object = class Object {
@@ -2137,6 +2194,28 @@
       return 'dynamic';
     }
   };
+  const _dartName = Symbol('_dartName');
+  dart.LazyJSType = class LazyJSType extends core.Object {
+    new(jsTypeCallback, dartName) {
+      this[_jsTypeCallback] = jsTypeCallback;
+      this[_dartName] = dartName;
+    }
+    get [_rawJSType]() {
+      return this[_jsTypeCallback]();
+    }
+    toString() {
+      return core.String._check(this[_jsTypeCallback] != null ? dart.typeName(this[_rawJSType]) : this[_dartName]);
+    }
+  };
+  dart.LazyJSType[dart.implements] = () => [core.Type];
+  dart.setSignature(dart.LazyJSType, {
+    constructors: () => ({new: dart.definiteFunctionType(dart.LazyJSType, [dart.dynamic, dart.dynamic])}),
+    fields: () => ({
+      [_jsTypeCallback]: dart.dynamic,
+      [_dartName]: dart.dynamic
+    }),
+    getters: () => ({[_rawJSType]: dart.definiteFunctionType(dart.dynamic, [])})
+  });
   dart.dynamic = new dart.Dynamic();
   dart._initialize = dart._initialize2();
   dart.Void = class Void extends dart.TypeRep {
diff --git a/pkg/dev_compiler/lib/sdk/ddc_sdk.sum b/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
index 04077ed..fda5a6d 100644
--- a/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
+++ b/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
Binary files differ
diff --git a/pkg/dev_compiler/lib/src/analyzer/context.dart b/pkg/dev_compiler/lib/src/analyzer/context.dart
index 5617f7f..d2bfe96 100644
--- a/pkg/dev_compiler/lib/src/analyzer/context.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/context.dart
@@ -22,8 +22,6 @@
 import 'package:cli_util/cli_util.dart' show getSdkDir;
 import 'package:path/path.dart' as path;
 
-import 'multi_package_resolver.dart' show MultiPackageResolver;
-
 /// Options used to set up Source URI resolution in the analysis context.
 class AnalyzerOptions {
   /// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart"
@@ -35,9 +33,6 @@
   /// List of summary file paths.
   final List<String> summaryPaths;
 
-  /// List of paths used for the multi-package resolver.
-  final List<String> packagePaths;
-
   /// Path to the dart-sdk. Null if `useMockSdk` is true or if the path couldn't
   /// be determined
   final String dartSdkPath;
@@ -55,7 +50,6 @@
       this.dartSdkSummaryPath,
       this.customUrlMappings: const {},
       this.packageRoot: null,
-      this.packagePaths: const [],
       this.declaredVariables: const {}})
       : dartSdkPath = dartSdkPath ?? getSdkDir().path;
 
@@ -77,13 +71,9 @@
         dartSdkSummaryPath: sdkSummaryPath,
         customUrlMappings: _parseUrlMappings(args['url-mapping']),
         packageRoot: args['package-root'],
-        packagePaths: (args['package-paths'] as String)?.split(',') ?? [],
         declaredVariables: declaredVariables);
   }
 
-  /// Whether to resolve 'package:' uris using the multi-package resolver.
-  bool get useMultiPackage => packagePaths.isNotEmpty;
-
   static void addArguments(ArgParser parser) {
     parser
       ..addOption('summary',
@@ -98,9 +88,7 @@
           help: '--url-mapping=libraryUri,/path/to/library.dart uses\n'
               'library.dart as the source for an import of of "libraryUri".',
           allowMultiple: true,
-          splitCommas: false)
-      ..addOption('package-paths',
-          help: 'use a list of directories to resolve "package:" imports');
+          splitCommas: false);
   }
 
   static Map<String, String> _parseUrlMappings(Iterable argument) {
@@ -168,12 +156,7 @@
         builder.convertPackagesToMap(builder.createPackageMap('')));
   }
 
-  return [
-    new ResourceUriResolver(resourceProvider),
-    options.useMultiPackage
-        ? new MultiPackageResolver(options.packagePaths)
-        : packageResolver()
-  ];
+  return [new ResourceUriResolver(resourceProvider), packageResolver()];
 }
 
 FolderBasedDartSdk _createFolderBasedDartSdk(String sdkPath) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/multi_package_resolver.dart b/pkg/dev_compiler/lib/src/analyzer/multi_package_resolver.dart
deleted file mode 100644
index 66905ec..0000000
--- a/pkg/dev_compiler/lib/src/analyzer/multi_package_resolver.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:path/path.dart' show join;
-
-/// A package resolver that supports a non-standard package layout, where
-/// packages with dotted names are expanded to a hierarchy of directories, and
-/// packages can be found on one or more locations.
-class MultiPackageResolver extends UriResolver {
-  final List<String> searchPaths;
-  MultiPackageResolver(this.searchPaths);
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    var candidates = _expandPath(uri);
-    if (candidates == null) return null;
-
-    for (var path in candidates) {
-      var resolvedPath = _resolve(path);
-      if (resolvedPath != null) {
-        return new FileBasedSource(
-            new JavaFile(resolvedPath), actualUri != null ? actualUri : uri);
-      }
-    }
-    return null;
-  }
-
-  /// Resolve [path] by looking at each prefix in [searchPaths] and returning
-  /// the first location where `prefix + path` exists.
-  String _resolve(String path) {
-    for (var prefix in searchPaths) {
-      var resolvedPath = join(prefix, path);
-      if (new File(resolvedPath).existsSync()) return resolvedPath;
-    }
-    return null;
-  }
-
-  /// Expand `uri.path`, replacing dots in the package name with slashes.
-  List<String> _expandPath(Uri uri) {
-    if (uri.scheme != 'package') return null;
-    var path = uri.path;
-    var slashPos = path.indexOf('/');
-    var packagePath = path.substring(0, slashPos).replaceAll(".", "/");
-    var filePath = path.substring(slashPos + 1);
-    return ['$packagePath/lib/$filePath', '$packagePath/$filePath'];
-  }
-}
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index b7f3d5a..361f5ec 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -308,7 +308,8 @@
   }
 
   List<String> _getJSName(Element e) {
-    if (findAnnotation(e.library, isPublicJSAnnotation) == null) {
+    if (e.library == null ||
+        findAnnotation(e.library, isPublicJSAnnotation) == null) {
       return null;
     }
 
@@ -322,6 +323,7 @@
     if (findAnnotation(e, isPublicJSAnnotation) != null) {
       elementJSName = getAnnotationName(e, isPublicJSAnnotation) ?? '';
     }
+
     if (e is TopLevelVariableElement &&
         e.getter != null &&
         (e.getter.isExternal ||
@@ -2705,11 +2707,8 @@
       var type = element.enclosingElement.type;
       var member = _emitMemberName(name, isStatic: isStatic, type: type);
 
-      // For static methods, we add the raw type name, without generics or
-      // library prefix. We don't need those because static calls can't use
-      // the generic type.
       if (isStatic) {
-        var dynType = _emitType(fillDynamicTypeArgs(type));
+        var dynType = _emitStaticAccess(type);
         return new JS.PropertyAccess(dynType, member);
       }
 
@@ -2908,6 +2907,40 @@
     return typeParts;
   }
 
+  /// Emits an expression that lets you access statics on a [type] from code.
+  ///
+  /// If [nameType] is true, then the type will be named.  In addition,
+  /// if [hoistType] is true, then the named type will be hoisted.
+  JS.Expression _emitConstructorAccess(DartType type,
+      {bool nameType: true, bool hoistType: true}) {
+    return _emitJSInterop(type.element) ??
+        _emitType(type, nameType: nameType, hoistType: hoistType);
+  }
+
+  /// Emits an expression that lets you access statics on a [type] from code.
+  JS.Expression _emitStaticAccess(DartType type) {
+    // Make sure we aren't attempting to emit a static access path to a type
+    // that does not have a valid static access path.
+    assert(!type.isVoid &&
+        !type.isDynamic &&
+        !type.isBottom &&
+        type is! TypeParameterType);
+
+    // For statics, we add the raw type name, without generics or
+    // library prefix. We don't need those because static calls can't use
+    // the generic type.
+    type = fillDynamicTypeArgs(type);
+    var element = type.element;
+    _declareBeforeUse(element);
+
+    var interop = _emitJSInterop(element);
+    if (interop != null) return interop;
+
+    assert(type.name != '' && type.name != null);
+
+    return _emitTopLevelNameNoInterop(element);
+  }
+
   /// Emits a Dart [type] into code.
   ///
   /// If [lowerTypedef] is set, a typedef will be expanded as if it were a
@@ -2937,13 +2970,37 @@
       return _callHelper('bottom');
     }
 
-    _declareBeforeUse(type.element);
+    var element = type.element;
+    _declareBeforeUse(element);
+
+    var interop = _emitJSInterop(element);
+    // Type parameters don't matter as JS interop types cannot be reified.
+    // We have to use lazy JS types because until we have proper module
+    // loading for JS libraries bundled with Dart libraries, we will sometimes
+    // need to load Dart libraries before the corresponding JS libraries are
+    // actually loaded.
+    // Given a JS type such as:
+    //     @JS('google.maps.Location')
+    //     class Location { ... }
+    // We can't emit a reference to MyType because the JS library that defines
+    // it may be loaded after our code. So for now, we use a special lazy type
+    // object to represent MyType.
+    // Anonymous JS types do not have a corresponding concrete JS type so we
+    // have to use a helper to define them.
+    if (interop != null) {
+      if (_isObjectLiteral(element)) {
+        return _callHelper(
+            'lazyAnonymousJSType(#)', js.string(element.displayName));
+      } else {
+        return _callHelper('lazyJSType(() => #, #)',
+            [interop, js.string(_getJSName(element).join('.'))]);
+      }
+    }
 
     // TODO(jmesserly): like constants, should we hoist function types out of
     // methods? Similar issue with generic types. For all of these, we may want
     // to canonicalize them too, at least when inside the same library.
     var name = type.name;
-    var element = type.element;
     if (name == '' || name == null || lowerTypedef) {
       // TODO(jmesserly): should we change how typedefs work? They currently
       // go through use similar logic as generic classes. This makes them
@@ -2957,9 +3014,7 @@
       return new JS.Identifier(name);
     }
 
-    if (type == subClass?.type) {
-      return className;
-    }
+    if (type == subClass?.type) return className;
 
     if (type is ParameterizedType) {
       var args = type.typeArguments;
@@ -2982,12 +3037,16 @@
       }
     }
 
-    return _emitTopLevelName(element);
+    return _emitTopLevelNameNoInterop(element);
   }
 
   JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) {
     var interop = _emitJSInterop(e);
     if (interop != null) return interop;
+    return _emitTopLevelNameNoInterop(e, suffix: suffix);
+  }
+
+  JS.PropertyAccess _emitTopLevelNameNoInterop(Element e, {String suffix: ''}) {
     String name = getJSExportName(e) + suffix;
     return new JS.PropertyAccess(
         emitLibraryName(e.library), _propertyName(name));
@@ -3211,7 +3270,7 @@
     // the generic type.
     ClassElement classElement = element.enclosingElement;
     var type = classElement.type;
-    var dynType = _emitType(fillDynamicTypeArgs(type));
+    var dynType = _emitStaticAccess(type);
     var member = _emitMemberName(element.name, isStatic: true, type: type);
     return _visit(rhs).toAssignExpression(
         annotate(new JS.PropertyAccess(dynType, member), lhs));
@@ -3362,6 +3421,19 @@
     return helperMethodName;
   }
 
+  JS.Expression _emitTarget(Expression target, Element element, bool isStatic) {
+    if (isStatic) {
+      if (element is ConstructorElement) {
+        return _emitConstructorAccess(element.enclosingElement.type);
+      }
+      if (element is ExecutableElement) {
+        return _emitStaticAccess(
+            (element.enclosingElement as ClassElement).type);
+      }
+    }
+    return _visit(target);
+  }
+
   /// Emits a (possibly generic) instance method call.
   JS.Expression _emitMethodCallInternal(
       Expression target,
@@ -3374,7 +3446,7 @@
     bool isStatic = element is ExecutableElement && element.isStatic;
     var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
 
-    JS.Expression jsTarget = _visit(target);
+    JS.Expression jsTarget = _emitTarget(target, element, isStatic);
     if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) {
       if (_inWhitelistCode(target)) {
         var vars = <JS.MetaLetVariable, JS.Expression>{};
@@ -3899,7 +3971,7 @@
     var classElem = element.enclosingElement;
     var interop = _emitJSInterop(classElem);
     if (interop != null) return interop;
-    var typeName = _emitType(type);
+    var typeName = _emitConstructorAccess(type);
     if (name != null || element.isFactory) {
       var namedCtor = _constructorName(element);
       return new JS.PropertyAccess(typeName, namedCtor);
@@ -3925,7 +3997,7 @@
       if (element == null) {
         // TODO(jmesserly): this only happens if we had a static error.
         // Should we generate a throw instead?
-        ctor = _emitType(type,
+        ctor = _emitConstructorAccess(type,
             nameType: options.hoistInstanceCreation,
             hoistType: options.hoistInstanceCreation);
         if (name != null) {
@@ -4749,7 +4821,7 @@
           [_emitDynamicOperationName('dload'), _visit(target), name]);
     }
 
-    var jsTarget = _visit(target);
+    var jsTarget = _emitTarget(target, member, isStatic);
     bool isSuper = jsTarget is JS.Super;
 
     if (isSuper && member is FieldElement && !member.isSynthetic) {
@@ -5123,7 +5195,8 @@
       // TODO(vsm): When we canonicalize, we need to treat private symbols
       // correctly.
       var name = js.string(node.components.join('.'), "'");
-      return js.call('#.new(#)', [_emitType(types.symbolType), name]);
+      return js
+          .call('#.new(#)', [_emitConstructorAccess(types.symbolType), name]);
     }
 
     return _emitConst(emitSymbol);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_lazy_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_lazy_test.dart
new file mode 100644
index 0000000..97af07f
--- /dev/null
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_lazy_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_lazy_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+import 'package:expect/minitest.dart';
+
+@JS('someProperty')
+external get foo;
+
+@JS('baz.bar')
+external get bar;
+
+@JS('baz.LazyClass')
+class LazyClass {
+  external factory LazyClass(a);
+  external get a;
+}
+
+@anonymous
+@JS('some.bogus.ignored.js.path')
+class AnonClass {
+  external factory AnonClass({a});
+  external get a;
+}
+
+@anonymous
+@JS()
+class AnonClass2 {
+  external factory AnonClass2({b});
+  external get b;
+}
+
+abstract class Foo<T> {
+  T get obj;
+}
+
+// This class would cause compile time issues if JS classes are not properly lazy.
+class FooImpl extends Foo<LazyClass> {
+  LazyClass get obj => new LazyClass(100);
+}
+
+main() {
+  group('lazy property', () {
+    test('simple', () {
+      expect(foo, isNull);
+      js_util.setProperty(window, 'someProperty', 42);
+      expect(foo, equals(42));
+    });
+
+    test('nested', () {
+      js_util.setProperty(window, 'baz', js_util.newObject());
+      expect(bar, isNull);
+      js_util.setProperty(window, 'baz', js_util.jsify({'bar': 100}));
+      expect(bar, equals(100));
+    });
+  });
+
+  group('lazy class', () {
+    test('type literal', () {
+      // Fine because we can determine the class literals are equal without
+      // having to determine what (non-existant) JS type they correspond to.
+      var x = LazyClass;
+      var y = LazyClass;
+      expect(x == y, isTrue);
+    });
+
+    test('reference in type parameter', () {
+      var o = new FooImpl();
+      expect(o is Foo<LazyClass>, isTrue);
+    });
+
+    test('create instance', () {
+      document.body.append(new ScriptElement()
+        ..type = 'text/javascript'
+        ..innerHtml = r"""
+window.baz = {};
+
+baz.LazyClass = function LazyClass(a) {
+  this.a = a;
+};
+""");
+      var l = new LazyClass(42);
+      expect(l.a, equals(42));
+      expect(l is LazyClass, isTrue);
+      expect(l is AnonClass, isTrue);
+      expect((l as AnonClass) == l, isTrue);
+      expect((l as AnonClass2) == l, isTrue);
+      var anon = new AnonClass(a: 42);
+      expect(anon is! LazyClass, isTrue);
+      expect(anon is AnonClass, isTrue);
+      expect(anon is AnonClass2, isTrue);
+
+      // Sanity check that is and as are not broken.
+      expect(new Object() is! LazyClass, isTrue);
+      expect(new Object() is! AnonClass, isTrue);
+      expect(new Object() is! AnonClass2, isTrue);
+
+      expect(<AnonClass>[] is List<AnonClass>, isTrue);
+      // TODO(jacobr): why doesn't this test pass?
+      // expect(<AnonClass>[] is List<AnonClass2>, isTrue);
+      expect(<int>[] is! List<AnonClass>, isTrue);
+      expect(<AnonClass>[] is! List<LazyClass>, isTrue);
+      expect(<int>[] is! List<LazyClass>, isTrue);
+      expect(<LazyClass>[] is List<LazyClass>, isTrue);
+    });
+  });
+}
diff --git a/pkg/dev_compiler/test/codegen_expected/sunflower/sunflower.js.map b/pkg/dev_compiler/test/codegen_expected/sunflower/sunflower.js.map
index 54b3f04..e102d33 100644
--- a/pkg/dev_compiler/test/codegen_expected/sunflower/sunflower.js.map
+++ b/pkg/dev_compiler/test/codegen_expected/sunflower/sunflower.js.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../../codegen/sunflower/sunflower.dart","../../codegen/sunflower/circle.dart","../../codegen/sunflower/painter.dart"],"names":["MAX_D","centerX","document","selector","querySelector","canvas","sqrt","slider","draw","seeds","int","context","i","TAU","PHI","SCALE_FACTOR","r","cos","theta","centerY","sin","x","y","SEED_RADIUS","notes","ORANGE","color","radius","PI"],"mappings":";;;;;;;;;;;;;AAYM,0BAAc,CAAC;AAAA,AACf,2BAAe,CAAC;AAAA,AAChB,oBAAQ,GAAG;AAAA,AACX,sBAAU,AAAAA,eAAK,GAAG,CAAC,AAAA;AAAA,AACnB,sBAAUC,iBAAO;AAAA,AAEvB,4BAAqB,SAAC,QAAe,EAAE;UAAG,AAAAC,cAAQ,sBAAeC,QAAQ,CAAC;GAAC,AAAA;AAAA;AACrE;IAAA;YAAS,uBAAA,AAAAC,uBAAa,CAAC,SAAS,CAAC,CAAiB;KAAA;;AAClD;IAAA;YAAU,kCAAA,AAAAC,gBAAM,mBAAY,IAAI,CAAC,CAA4B;KAAA;;AAC7D;IAAA;YAAS,sBAAA,AAAAD,uBAAa,CAAC,SAAS,CAAC,CAAgB;KAAA;;AACjD;IAAA;YAAQ,AAAAA,wBAAa,CAAC,QAAQ,CAAC;KAAA;;AAE/B;IAAA;YAAM,EAAA,aAAC,AAAAE,SAAI,CAAC,CAAC,CAAC,IAAG,CAAC,AAAC,IAAG,CAAC,AAAA;KAAA;;AACzB,oBAAQ,CAAC;AAAA,AAEb,mBAAS,WAAG;AACV,IAAA,AAAAC,gBAAM,yBAAkB,QAAQ,EAAE,QAAA,AAAC,CAAC,IAAK,AAAAC,cAAI,EAAE,AAAA,gBAAA,CAAC;AAAC,AACjD,IAAA,AAAAA,cAAI,EAAE;AAAC,GACR,AAAA;AAAA;AAED,mBACS,WAAG;AACV,IAAA,AAAAC,eAAK,GAAG,AAAAC,QAAG,OAAO,AAAAH,gBAAM,aAAM,CAAC,AAAA;AAAC,AAChC,IAAA,AAAAI,iBAAO,kBAAW,CAAC,EAAE,CAAC,EAAEX,eAAK,EAAEA,eAAK,CAAC;AAAC,AACtC,SAAK,IAAI,IAAI,CAAC,AAAA,AAAA,EAAE,AAAAY,CAAC,gBAAGH,eAAK,CAAA,EAAE,AAAAG,CAAC,EAAE,EAAE;AAC9B,kBAAc,AAAA,AAAAA,CAAC,GAAGC,WAAG,AAAA,gBAAGC,aAAG,CAAA;AAAC,AAC5B,cAAU,aAAA,AAAAR,SAAI,CAACM,CAAC,CAAC,IAAGG,sBAAY,AAAA;AAAC,AACjC,cAAU,AAAAd,iBAAO,GAAG,AAAAe,CAAC,gBAAGC,AAAA,QAAG,CAACC,KAAK,CAAC,CAAA,AAAA;AAAC,AACnC,cAAU,AAAAC,iBAAO,GAAG,AAAAH,CAAC,gBAAG,AAAAI,QAAG,CAACF,KAAK,CAAC,CAAA,AAAA;AAAC,AACnC,MAAA,AAAA,4BAAkBG,CAAC,EAAEC,CAAC,EAAEC,qBAAW,CAAC,MAAMZ,iBAAO,CAAC;AAAC,KACpD;AAAA,AACD,IAAA,AAAA,AAAAa,eAAK,YAAK,GAAG,WAAC,eAAM,QAAO,AAAA;AAAC,GAC7B,AAAA;AAAA;;ICnCC,IAAO,CAAM,EAAE,CAAM,EAAE,MAAW,EAAlC;;;;AAAmC,AAAC,KAAA;;;;;;;;;;;ICYtC;mBAEiBC,cAAM;KAevB;IAbE,KACU,OAAgC,EAAE;AAC1C,MAAAd,AACE,OADK,mBACQ;MADfA,AAEE,AAAA,OAFK,iBAEM,GAAG,CAAC,AAAA;MAFjBA,AAGE,AAAA,OAHK,iBAGM,GAAGe,UAAK,AAAA;MAHrBf,AAIE,AAAA,OAJK,mBAIQ,GAAGe,UAAK,AAAA;MAJvBf,AAKE,OALK,YAKCU,MAAC,EAAEC,MAAC,EAAEK,WAAM,EAAE,CAAC,EAAEd,WAAG,EAAE,KAAK,CAAC;MALpCF,AAME,OANK,cAMG;MANVA,AAOE,OAPK,mBAOQ;MAPfA,AAQE,OARK,gBAQK;AAAC,KACd,AAAA;;;;;;;;IFYD,IAAc,CAAK,EAAE,CAAK,EAAE,MAAU,EAAG,KAAY,EAArD;;AACE,gBAAMU,CAAC,EAAEC,CAAC,EAAEK,MAAM;AAAC,AAAC,AACpB,UAAI,AAAAD,KAAK,IAAI,IAAI,AAAA,EAAE,AAAA,AAAA,AAAA,IAAI,MAAM,GAAGA,KAAK,AAAA;AAAC,AAAA,AACvC,KAAA;;;;;AExCG,mBAAS,QAAQ;AAAA,AACjB,gBAAM,KAAK;AAAA,AACX,iBAAO,MAAM;AAAA,AACb,gBAAM,AAAAE,OAAE,GAAG,CAAC,AAAA;AAAA,AAElB,0BAAqB,SAAC,QAAe,EAAE;UAAG,AAAA1B,cAAQ,sBAAeC,QAAQ,CAAC;GAAC,AAAA;AAAA;AAErE;IAAA;YAAS,uBAAA,AAAAC,qBAAa,CAAC,SAAS,CAAC,CAAiB;KAAA;;AAClD;IAAA;YAAU,kCAAA,AAAAC,cAAM,mBAAY,IAAI,CAAC,CAA4B;KAAA","file":"sunflower.js"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../../codegen/sunflower/sunflower.dart","../../codegen/sunflower/circle.dart","../../codegen/sunflower/painter.dart"],"names":["MAX_D","centerX","document","selector","querySelector","canvas","sqrt","slider","draw","seeds","context","i","TAU","PHI","SCALE_FACTOR","r","cos","theta","centerY","sin","x","y","SEED_RADIUS","notes","ORANGE","color","radius","PI"],"mappings":";;;;;;;;;;;;;AAYM,0BAAc,CAAC;AAAA,AACf,2BAAe,CAAC;AAAA,AAChB,oBAAQ,GAAG;AAAA,AACX,sBAAU,AAAAA,eAAK,GAAG,CAAC,AAAA;AAAA,AACnB,sBAAUC,iBAAO;AAAA,AAEvB,4BAAqB,SAAC,QAAe,EAAE;UAAG,AAAAC,cAAQ,sBAAeC,QAAQ,CAAC;GAAC,AAAA;AAAA;AACrE;IAAA;YAAS,uBAAA,AAAAC,uBAAa,CAAC,SAAS,CAAC,CAAiB;KAAA;;AAClD;IAAA;YAAU,kCAAA,AAAAC,gBAAM,mBAAY,IAAI,CAAC,CAA4B;KAAA;;AAC7D;IAAA;YAAS,sBAAA,AAAAD,uBAAa,CAAC,SAAS,CAAC,CAAgB;KAAA;;AACjD;IAAA;YAAQ,AAAAA,wBAAa,CAAC,QAAQ,CAAC;KAAA;;AAE/B;IAAA;YAAM,EAAA,aAAC,AAAAE,SAAI,CAAC,CAAC,CAAC,IAAG,CAAC,AAAC,IAAG,CAAC,AAAA;KAAA;;AACzB,oBAAQ,CAAC;AAAA,AAEb,mBAAS,WAAG;AACV,IAAA,AAAAC,gBAAM,yBAAkB,QAAQ,EAAE,QAAA,AAAC,CAAC,IAAK,AAAAC,cAAI,EAAE,AAAA,gBAAA,CAAC;AAAC,AACjD,IAAA,AAAAA,cAAI,EAAE;AAAC,GACR,AAAA;AAAA;AAED,mBACS,WAAG;AACV,IAAA,AAAAC,eAAK,GAAG,eAAU,AAAAF,gBAAM,aAAM,CAAC,AAAA;AAAC,AAChC,IAAA,AAAAG,iBAAO,kBAAW,CAAC,EAAE,CAAC,EAAEV,eAAK,EAAEA,eAAK,CAAC;AAAC,AACtC,SAAK,IAAI,IAAI,CAAC,AAAA,AAAA,EAAE,AAAAW,CAAC,gBAAGF,eAAK,CAAA,EAAE,AAAAE,CAAC,EAAE,EAAE;AAC9B,kBAAc,AAAA,AAAAA,CAAC,GAAGC,WAAG,AAAA,gBAAGC,aAAG,CAAA;AAAC,AAC5B,cAAU,aAAA,AAAAP,SAAI,CAACK,CAAC,CAAC,IAAGG,sBAAY,AAAA;AAAC,AACjC,cAAU,AAAAb,iBAAO,GAAG,AAAAc,CAAC,gBAAG,AAAAC,QAAG,CAACC,KAAK,CAAC,CAAA,AAAA;AAAC,AACnC,cAAU,AAAAC,iBAAO,GAAG,AAAAH,CAAC,gBAAG,AAAAI,QAAG,CAACF,KAAK,CAAC,CAAA,AAAA;AAAC,AACnC,MAAA,AAAA,4BAAkBG,CAAC,EAAEC,CAAC,EAAEC,qBAAW,CAAC,MAAMZ,iBAAO,CAAC;AAAC,KACpD;AAAA,AACD,IAAA,AAAA,AAAAa,eAAK,YAAK,GAAG,WAAC,eAAM,QAAO,AAAA;AAAC,GAC7B,AAAA;AAAA;;ICnCC,IAAO,CAAM,EAAE,CAAM,EAAE,MAAW,EAAlC;;;;AAAmC,AAAC,KAAA;;;;;;;;;;;ICYtC;mBAEiBC,cAAM;KAevB;IAbE,KACU,OAAgC,EAAE;AAC1C,MAAAd,AACE,OADK,mBACQ;MADfA,AAEE,AAAA,OAFK,iBAEM,GAAG,CAAC,AAAA;MAFjBA,AAGE,AAAA,OAHK,iBAGM,GAAGe,UAAK,AAAA;MAHrBf,AAIE,AAAA,OAJK,mBAIQ,GAAGe,UAAK,AAAA;MAJvBf,AAKE,OALK,YAKCU,MAAC,EAAEC,MAAC,EAAEK,WAAM,EAAE,CAAC,EAAEd,WAAG,EAAE,KAAK,CAAC;MALpCF,AAME,OANK,cAMG;MANVA,AAOE,OAPK,mBAOQ;MAPfA,AAQE,OARK,gBAQK;AAAC,KACd,AAAA;;;;;;;;IFYD,IAAc,CAAK,EAAE,CAAK,EAAE,MAAU,EAAG,KAAY,EAArD;;AACE,gBAAMU,CAAC,EAAEC,CAAC,EAAEK,MAAM;AAAC,AAAC,AACpB,UAAI,AAAAD,KAAK,IAAI,IAAI,AAAA,EAAE,AAAA,AAAA,AAAA,IAAI,MAAM,GAAGA,KAAK,AAAA;AAAC,AAAA,AACvC,KAAA;;;;;AExCG,mBAAS,QAAQ;AAAA,AACjB,gBAAM,KAAK;AAAA,AACX,iBAAO,MAAM;AAAA,AACb,gBAAM,AAAAE,OAAE,GAAG,CAAC,AAAA;AAAA,AAElB,0BAAqB,SAAC,QAAe,EAAE;UAAG,AAAAzB,cAAQ,sBAAeC,QAAQ,CAAC;GAAC,AAAA;AAAA;AAErE;IAAA;YAAS,uBAAA,AAAAC,qBAAa,CAAC,SAAS,CAAC,CAAiB;KAAA;;AAClD;IAAA;YAAU,kCAAA,AAAAC,cAAM,mBAAY,IAAI,CAAC,CAA4B;KAAA","file":"sunflower.js"}
\ No newline at end of file
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
index c6419a0..d97b6bd 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
@@ -58,10 +58,8 @@
 fn(closure, t) {
   if (t == null) {
     // No type arguments, it's all dynamic
-    t = definiteFunctionType(
-        JS('', '#', dynamic),
-        JS('', 'Array(#.length).fill(#)', closure, dynamic),
-        JS('', 'void 0'));
+    t = definiteFunctionType(JS('', '#', dynamic),
+        JS('', 'Array(#.length).fill(#)', closure, dynamic), JS('', 'void 0'));
   }
   tag(closure, t);
   return closure;
@@ -161,6 +159,29 @@
   return JS('', '#[#] = new #(#)', type, _typeObject, WrappedType, type);
 }
 
+var _lazyJSTypes = JS('', 'new Map()');
+
+lazyJSType(getJSTypeCallback, name) {
+  var key = JS('String', '#.toString()', getJSTypeCallback);
+  if (JS('bool', '#.has(#)', _lazyJSTypes, key)) {
+    return JS('', '#.get(#)', _lazyJSTypes, key);
+  }
+  var ret = JS('', 'new #(#, #)', LazyJSType, getJSTypeCallback, name);
+  JS('', '#.set(#, #)', _lazyJSTypes, key, ret);
+  return ret;
+}
+
+// TODO(jacobr): do not use the same LazyJSType object for anonymous JS types
+// from different libraries.
+lazyAnonymousJSType(name) {
+  if (JS('bool', '#.has(#)', _lazyJSTypes, name)) {
+    return JS('', '#.get(#)', _lazyJSTypes, name);
+  }
+  var ret = JS('', 'new #(null, #)', LazyJSType, name);
+  JS('', '#.set(#, #)', _lazyJSTypes, name, ret);
+  return ret;
+}
+
 /// Given a WrappedType, return the internal runtime type object.
 unwrapType(obj) => obj._wrappedType;
 
@@ -180,6 +201,6 @@
 }
 
 void tagLazy(value, compute) {
-  JS('', '#(#, #, { get: # })',
-      defineLazyProperty, value, _runtimeType, compute);
+  JS('', '#(#, #, { get: # })', defineLazyProperty, value, _runtimeType,
+      compute);
 }
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index 1c1acb2..91a4ea8 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -56,7 +56,9 @@
 // TODO(jmesserly): we shouldn't implement Type here. It should be moved down
 // to AbstractFunctionType.
 class TypeRep implements Type {
-  TypeRep() { _initialize; }
+  TypeRep() {
+    _initialize;
+  }
   String get name => this.toString();
 }
 
@@ -64,12 +66,46 @@
   toString() => 'dynamic';
 }
 
+class LazyJSType implements Type {
+  final _jsTypeCallback;
+  final _dartName;
+
+  LazyJSType(this._jsTypeCallback, this._dartName);
+
+  get _rawJSType => JS('', '#()', _jsTypeCallback);
+
+  toString() => _jsTypeCallback != null ? typeName(_rawJSType) : _dartName;
+}
+
+_isInstanceOfLazyJSType(o, LazyJSType t) {
+  if (t._jsTypeCallback != null) {
+    return JS('bool', 'dart.is(#, #)', o, t._rawJSType);
+  }
+  if (o == null) return false;
+  // Anonymous case: match any JS type.
+  return _isJSObject(o);
+}
+
+_asInstanceOfLazyJSType(o, LazyJSType t) {
+  if (t._jsTypeCallback != null) {
+    return JS('bool', 'dart.as(#, #)', o, t._rawJSType);
+  }
+  // Anonymous case: allow any JS type.
+  if (o == null) return null;
+  if (!_isJSObject(o)) _throwCastError(o, t, true);
+  return o;
+}
+
+bool _isJSObject(o) => JS('bool', '!dart.getReifiedType(o)[dart._runtimeType]');
+
 @JSExportName('dynamic')
 final _dynamic = new Dynamic();
 
 final _initialize = _initialize2();
 
-_initialize2() => JS('', '''(() => {
+_initialize2() => JS(
+    '',
+    '''(() => {
   // JavaScript API forwards to runtime library.
   $TypeRep.prototype.is = function is_T(object) {
     return dart.is(object, this);
@@ -91,6 +127,13 @@
   $Dynamic.prototype._check = function check_Dynamic(object) {
     return object;
   };
+
+  $LazyJSType.prototype.is = function is_T(object) {
+    return $_isInstanceOfLazyJSType(object, this);
+  };
+  $LazyJSType.prototype.as = function as_T(object) {
+    return $_asInstanceOfLazyJSType(object, this);
+  };
 })()''');
 
 class Void extends TypeRep {
@@ -103,6 +146,7 @@
 class Bottom extends TypeRep {
   toString() => 'bottom';
 }
+
 final bottom = new Bottom();
 
 class JSObject extends TypeRep {
@@ -117,7 +161,9 @@
   toString() => typeName(_wrappedType);
 }
 
-final AbstractFunctionType = JS('', '''
+final AbstractFunctionType = JS(
+    '',
+    '''
   class AbstractFunctionType extends $TypeRep {
     constructor() {
       super();
@@ -172,6 +218,7 @@
 /// reached via this path (if any) is the canonical representative
 /// for this packet.
 final _fnTypeNamedArgMap = JS('', 'new Map()');
+
 /// Memo table for positional argument groups. A positional argument
 /// packet [type1, ..., typen] (required or optional) corresponds to
 /// the path n, type1, ...., typen.  The element reached via
@@ -179,11 +226,13 @@
 /// packet. Note that required and optional parameters packages
 /// may have the same canonical representation.
 final _fnTypeArrayArgMap = JS('', 'new Map()');
+
 /// Memo table for function types. The index path consists of the
 /// path length - 1, the returnType, the canonical positional argument
 /// packet, and if present, the canonical optional or named argument
 /// packet.  A level of indirection could be avoided here if desired.
 final _fnTypeTypeMap = JS('', 'new Map()');
+
 /// Memo table for small function types with no optional or named
 /// arguments and less than a fixed n (currently 3) number of
 /// required arguments.  Indexing into this table by the number
@@ -192,7 +241,9 @@
 /// index path (if present) is the canonical function type.
 final _fnTypeSmallMap = JS('', '[new Map(), new Map(), new Map()]');
 
-final FunctionType = JS('', '''
+final FunctionType = JS(
+    '',
+    '''
   class FunctionType extends $AbstractFunctionType {
     static _memoizeArray(map, arr, create) {
       let len = arr.length;
@@ -346,8 +397,9 @@
   }
 ''');
 
-
-final Typedef = JS('', '''
+final Typedef = JS(
+    '',
+    '''
   class Typedef extends $AbstractFunctionType {
     constructor(name, closure) {
       super();
@@ -391,7 +443,9 @@
 
 final _typeFormalCount = JS('', 'Symbol("_typeFormalCount")');
 
-_functionType(definite, returnType, args, extra) => JS('', '''(() => {
+_functionType(definite, returnType, args, extra) => JS(
+    '',
+    '''(() => {
   // TODO(jmesserly): this is a bit of a retrofit, to easily fit
   // generic functions into all of the existing ways we generate function
   // signatures. Given `(T) => [T, [T]]` we'll return a function that does
@@ -427,7 +481,9 @@
 
 typedef(name, closure) => JS('', 'new #(#, #)', Typedef, name, closure);
 
-typeName(type) => JS('', '''(() => {
+typeName(type) => JS(
+    '',
+    '''(() => {
   if ($type === void 0) return "undefined type";
   if ($type === null) return "null type";
   // Non-instance types
@@ -480,9 +536,16 @@
   return getMethodTypeFromType(type, 'call');
 }
 
-bool isFunctionType(type) =>
-    JS('bool', '# instanceof # || # === #',
-        type, AbstractFunctionType, type, Function);
+bool isFunctionType(type) => JS('bool', '# instanceof # || # === #', type,
+    AbstractFunctionType, type, Function);
+
+isLazyJSSubtype(LazyJSType t1, LazyJSType t2, covariant) {
+  if (t1 == t2) return true;
+
+  // All anonymous JS types are subtypes of each other.
+  if (t1._jsTypeCallback == null || t2._jsTypeCallback == null) return true;
+  return isClassSubType(t1._rawJSType, t2._rawJSType, covariant);
+}
 
 /// Returns true if [ft1] <: [ft2].
 /// Returns false if [ft1] </: [ft2] in both spec and strong mode
@@ -491,7 +554,9 @@
 /// If [covariant] is true, then we are checking subtyping in a covariant
 /// position, and hence the direction of the check for function types
 /// corresponds to the direction of the check according to the Dart spec.
-isFunctionSubtype(ft1, ft2, covariant) => JS('', '''(() => {
+isFunctionSubtype(ft1, ft2, covariant) => JS(
+    '',
+    '''(() => {
   if ($ft2 === $Function) {
     return true;
   }
@@ -571,7 +636,9 @@
 /// TODO(leafp): This duplicates code in operations.dart.
 /// I haven't found a way to factor it out that makes the
 /// code generator happy though.
-_subtypeMemo(f) => JS('', '''(() => {
+_subtypeMemo(f) => JS(
+    '',
+    '''(() => {
   let memo = new Map();
   return (t1, t2) => {
     let map = memo.get(t1);
@@ -592,14 +659,16 @@
 /// Returns false if [t1] </: [t2] in both spec and strong mode
 /// Returns undefined if [t1] </: [t2] in strong mode, but spec
 ///  mode may differ
-final isSubtype =
-    JS('', '$_subtypeMemo((t1, t2) => (t1 === t2) || $_isSubtype(t1, t2, true))');
+final isSubtype = JS(
+    '', '$_subtypeMemo((t1, t2) => (t1 === t2) || $_isSubtype(t1, t2, true))');
 
 _isBottom(type) => JS('bool', '# == #', type, bottom);
 
 _isTop(type) => JS('bool', '# == # || # == #', type, Object, type, dynamic);
 
-_isSubtype(t1, t2, covariant) => JS('', '''(() => {
+_isSubtype(t1, t2, covariant) => JS(
+    '',
+    '''(() => {
   if ($t1 === $t2) return true;
 
   // Trivially true.
@@ -633,10 +702,17 @@
   if ($isFunctionType($t1) && $isFunctionType($t2)) {
     return $isFunctionSubtype($t1, $t2, $covariant);
   }
+  
+  if ($t1 instanceof $LazyJSType && $t2 instanceof $LazyJSType) {
+    return $isLazyJSSubtype($t1, $t2, $covariant);
+  }
+  
   return false;
 })()''');
 
-isClassSubType(t1, t2, covariant) => JS('', '''(() => {
+isClassSubType(t1, t2, covariant) => JS(
+    '',
+    '''(() => {
   // We support Dart's covariant generics with the caveat that we do not
   // substitute bottom for dynamic in subtyping rules.
   // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
@@ -717,7 +793,9 @@
 // TODO(jmesserly): this isn't currently used, but it could be if we want
 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile
 // time.
-isGroundType(type) => JS('', '''(() => {
+isGroundType(type) => JS(
+    '',
+    '''(() => {
   // TODO(vsm): Cache this if we start using it at runtime.
 
   if ($type instanceof $AbstractFunctionType) {
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 8b75e23..5436751 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -12,7 +12,7 @@
 dev_dependencies:
   # TODO(sigmund): update to a version constraint once we roll the latest kernel
   # to the repo.
-  kernel: {path: ../../third_party/pkg/kernel}
+  kernel: {path: ../../pkg/kernel}
   package_config: '^1.0.0'
   test: ^0.12.0
   test_reflective_loader: ^0.1.0
diff --git a/pkg/js/README.md b/pkg/js/README.md
index 393a489..e95e03e 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -90,6 +90,8 @@
 }
 ```
 
+NB: This _anonymous_ class must have an unnamed _factory constructor_.
+
 #### Passing functions to JavaScript.
 
 If you are passing a Dart function to a JavaScript API, you must wrap it using
diff --git a/pkg/kernel/.analysis_options b/pkg/kernel/.analysis_options
new file mode 100644
index 0000000..e96ec6a
--- /dev/null
+++ b/pkg/kernel/.analysis_options
@@ -0,0 +1,6 @@
+analyzer:
+  strong-mode: true
+  language:
+    enableSuperMixins: true
+  exclude:
+    - testcases/**
diff --git a/pkg/kernel/.gitignore b/pkg/kernel/.gitignore
new file mode 100644
index 0000000..a151f3d
--- /dev/null
+++ b/pkg/kernel/.gitignore
@@ -0,0 +1,5 @@
+.packages
+.pub
+packages
+pubspec.lock
+bin/dartk.snapshot
diff --git a/pkg/kernel/AUTHORS b/pkg/kernel/AUTHORS
new file mode 100644
index 0000000..5aff99a
--- /dev/null
+++ b/pkg/kernel/AUTHORS
@@ -0,0 +1,10 @@
+# Below is a list of people and organizations that have contributed
+# to the project. Names should be added to the list like so:
+#
+#   Name/Organization <email address>
+
+Google Inc.
+
+Asger Feldthaus <asgerf@google.com>
+Martin Kustermann <kustermann@google.com>
+Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/kernel/LICENSE b/pkg/kernel/LICENSE
new file mode 100644
index 0000000..1883d24
--- /dev/null
+++ b/pkg/kernel/LICENSE
@@ -0,0 +1,24 @@
+Copyright 2016, 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/kernel/README.md b/pkg/kernel/README.md
new file mode 100644
index 0000000..8239a3d
--- /dev/null
+++ b/pkg/kernel/README.md
@@ -0,0 +1,67 @@
+Dart Kernel
+===========
+**Dart Kernel** is a small high-level language derived from Dart.
+It is designed for use as an intermediate format for whole-program analysis
+and transformations, and as a frontend for codegen and execution backends.
+
+The kernel language has in-memory representations in Dart and C++, and
+can be serialized as binary or text.
+
+Both the kernel language and its implementations are unstable and are under development.
+
+This package contains the Dart part of the implementation and contains:
+- A transformable IR for the kernel language
+- A frontend based on the analyzer
+- Serialization of kernel code
+
+Getting Kernel
+------------
+
+Checkout the repository and run pub get:
+```bash
+git clone https://github.com/dart-lang/kernel
+cd kernel
+pub get
+```
+
+Command-Line Tool
+-----------------
+
+Run `bin/dartk.dart` from the command-line to convert between .dart files
+and the serialized binary and textual formats.
+
+`dartk` expects the `.dill` extension for files in the binary format.
+The textual format has no preferred extension right now.
+
+Example commands:
+```bash
+dartk foo.dart            # print text IR for foo.dart
+dartk foo.dart -ofoo.dill # write binary IR for foo.dart to foo.dill
+dartk foo.dill            # print text IR for binary file foo.dill
+```
+
+Pass the `--link` or `-l` flag to link all transitive dependencies into one file:
+```bash
+dartk myapp.dart -ppackages -l -omyapp.dill # Bundle everything.
+dartk myapp.dill # Print it back out in a (very, very long) textual format.
+```
+
+See [ast.dart](lib/ast.dart) for the in-memory IR, or [binary.md](binary.md) for
+a description of the binary format.  For now, the textual format is very ad-hoc
+and cannot be parsed back in.
+
+
+Testing
+-------
+
+If you plan to make changes to kernel, get a checkout of the Dartk SDK and run:
+```bash
+tool/regenerate_dill_files.dart --sdk <path to SDK checkout>
+pub run test
+```
+
+
+Linking
+-------------------------
+Linking from binary files is not yet implemented.  In order to compile a whole
+program, currently everything must be compiled from source at once.
diff --git a/pkg/kernel/bin/batch_util.dart b/pkg/kernel/bin/batch_util.dart
new file mode 100644
index 0000000..0070aa0
--- /dev/null
+++ b/pkg/kernel/bin/batch_util.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.batch_util;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+enum CompilerOutcome { Ok, Fail, }
+
+typedef Future<CompilerOutcome> BatchCallback(List<String> arguments);
+
+/// Runs the given [callback] in the batch mode for use by the test framework in
+/// `dart-lang/sdk`.
+///
+/// The [callback] should behave as a main method, except it should return a
+/// [CompilerOutcome] for reporting its outcome to the testing framework.
+Future runBatch(BatchCallback callback) async {
+  int totalTests = 0;
+  int testsFailed = 0;
+  var watch = new Stopwatch()..start();
+  print('>>> BATCH START');
+  Stream input = stdin.transform(UTF8.decoder).transform(new LineSplitter());
+  await for (String line in input) {
+    if (line.isEmpty) {
+      int time = watch.elapsedMilliseconds;
+      print('>>> BATCH END '
+          '(${totalTests - testsFailed})/$totalTests ${time}ms');
+      break;
+    }
+    ++totalTests;
+    var arguments = line.split(new RegExp(r'\s+'));
+    try {
+      var outcome = await callback(arguments);
+      stderr.writeln('>>> EOF STDERR');
+      if (outcome == CompilerOutcome.Ok) {
+        print('>>> TEST PASS ${watch.elapsedMilliseconds}ms');
+      } else {
+        print('>>> TEST FAIL ${watch.elapsedMilliseconds}ms');
+      }
+    } catch (e, stackTrace) {
+      stderr.writeln(e);
+      stderr.writeln(stackTrace);
+      stderr.writeln('>>> EOF STDERR');
+      print('>>> TEST CRASH');
+    }
+  }
+}
diff --git a/pkg/kernel/bin/dartk.dart b/pkg/kernel/bin/dartk.dart
new file mode 100755
index 0000000..e735f97
--- /dev/null
+++ b/pkg/kernel/bin/dartk.dart
@@ -0,0 +1,384 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'batch_util.dart';
+
+import 'package:args/args.dart';
+import 'package:kernel/analyzer/loader.dart';
+import 'package:kernel/verifier.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/log.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:path/path.dart' as path;
+
+// Returns the path to the current sdk based on `Platform.resolvedExecutable`.
+String currentSdk() {
+  // The dart executable should be inside dart-sdk/bin/dart.
+  return path.dirname(path.dirname(path.absolute(Platform.resolvedExecutable)));
+}
+
+ArgParser parser = new ArgParser(allowTrailingOptions: true)
+  ..addOption('format',
+      abbr: 'f',
+      allowed: ['text', 'bin'],
+      help: 'Output format.\n'
+          '(defaults to "text" unless output file ends with ".dill")')
+  ..addOption('out',
+      abbr: 'o',
+      help: 'Output file.\n'
+          '(defaults to "out.dill" if format is "bin", otherwise stdout)')
+  ..addOption('sdk', defaultsTo: currentSdk(), help: 'Path to the Dart SDK.')
+  ..addOption('packages',
+      abbr: 'p', help: 'Path to the .packages file or packages folder.')
+  ..addOption('package-root', help: 'Deprecated alias for --packages')
+  ..addOption('target',
+      abbr: 't',
+      help: 'Tailor the IR to the given target.',
+      allowed: targetNames,
+      defaultsTo: 'vm')
+  ..addFlag('strong',
+      help: 'Load .dart files in strong mode.\n'
+          'Does not affect loading of binary files. Strong mode support is very\n'
+          'unstable and not well integrated yet.')
+  ..addFlag('link', abbr: 'l', help: 'Link the whole program into one file.')
+  ..addFlag('no-output', negatable: false, help: 'Do not output any files.')
+  ..addOption('url-mapping',
+      allowMultiple: true,
+      help: 'A custom url mapping of the form `<scheme>:<name>::<uri>`.')
+  ..addFlag('verbose',
+      abbr: 'v',
+      negatable: false,
+      help: 'Print internal warnings and diagnostics to stderr.')
+  ..addFlag('print-metrics',
+      negatable: false, help: 'Print performance metrics.')
+  ..addOption('write-dependencies',
+      help: 'Write all the .dart that were loaded to the given file.')
+  ..addFlag('verify-ir', help: 'Perform slow internal correctness checks.')
+  ..addFlag('tolerant',
+      help: 'Generate kernel even if there are compile-time errors.',
+      defaultsTo: false)
+  ..addOption('D',
+      abbr: 'D',
+      allowMultiple: true,
+      help: 'Define an environment variable.',
+      hide: true)
+  ..addFlag('show-external',
+      help: 'When printing a library as text, also print its dependencies\n'
+          'on external libraries.');
+
+String getUsage() => """
+Usage: dartk [options] FILE
+
+Convert .dart or .dill files to kernel's IR and print out its textual
+or binary form.
+
+Examples:
+    dartk foo.dart            # print text IR for foo.dart
+    dartk foo.dart -ofoo.dill # write binary IR for foo.dart to foo.dill
+    dartk foo.dill            # print text IR for binary file foo.dill
+
+Options:
+${parser.usage}
+
+    -D<name>=<value>        Define an environment variable.
+""";
+
+dynamic fail(String message) {
+  stderr.writeln(message);
+  exit(1);
+  return null;
+}
+
+ArgResults options;
+
+String defaultFormat() {
+  if (options['out'] != null && options['out'].endsWith('.dill')) {
+    return 'bin';
+  }
+  return 'text';
+}
+
+String defaultOutput() {
+  if (options['format'] == 'bin') {
+    return 'out.dill';
+  }
+  return null;
+}
+
+void checkIsDirectoryOrNull(String path, String option) {
+  if (path == null) return;
+  var stat = new File(path).statSync();
+  switch (stat.type) {
+    case FileSystemEntityType.DIRECTORY:
+    case FileSystemEntityType.LINK:
+      return;
+    case FileSystemEntityType.NOT_FOUND:
+      throw fail('$option not found: $path');
+    default:
+      fail('$option is not a directory: $path');
+  }
+}
+
+void checkIsFile(String path, {String option}) {
+  var stat = new File(path).statSync();
+  switch (stat.type) {
+    case FileSystemEntityType.DIRECTORY:
+      throw fail('$option is a directory: $path');
+
+    case FileSystemEntityType.NOT_FOUND:
+      throw fail('$option not found: $path');
+  }
+}
+
+void checkIsFileOrDirectoryOrNull(String path, String option) {
+  if (path == null) return;
+  var stat = new File(path).statSync();
+  if (stat.type == FileSystemEntityType.NOT_FOUND) {
+    fail('$option not found: $path');
+  }
+}
+
+int getTotalSourceSize(List<String> files) {
+  int size = 0;
+  for (var filename in files) {
+    size += new File(filename).statSync().size;
+  }
+  return size;
+}
+
+bool get shouldReportMetrics => options['print-metrics'];
+
+void dumpString(String value, [String filename]) {
+  if (filename == null) {
+    print(value);
+  } else {
+    new File(filename).writeAsStringSync(value);
+  }
+}
+
+Map<Uri, Uri> parseCustomUriMappings(List<String> mappings) {
+  Map<Uri, Uri> customUriMappings = <Uri, Uri>{};
+
+  fatal(String mapping) {
+    fail('Invalid uri mapping "$mapping". Each mapping should have the '
+        'form "<scheme>:<name>::<uri>".');
+  }
+
+  // Each mapping has the form <uri>::<uri>.
+  for (var mapping in mappings) {
+    List<String> parts = mapping.split('::');
+    if (parts.length != 2) {
+      fatal(mapping);
+    }
+    Uri fromUri = Uri.parse(parts[0]);
+    if (fromUri.scheme == '' || fromUri.path.contains('/')) {
+      fatal(mapping);
+    }
+    Uri toUri = Uri.parse(parts[1]);
+    if (toUri.scheme == '') {
+      toUri = new Uri.file(path.absolute(parts[1]));
+    }
+    customUriMappings[fromUri] = toUri;
+  }
+
+  return customUriMappings;
+}
+
+/// Maintains state that should be shared between batched executions when
+/// running in batch mode (for testing purposes).
+///
+/// This reuses the analyzer's in-memory copy of the Dart SDK between runs.
+class BatchModeState {
+  bool isBatchMode = false;
+  DartLoaderBatch batch = new DartLoaderBatch();
+}
+
+main(List<String> args) async {
+  if (args.isNotEmpty && args[0] == '--batch') {
+    if (args.length != 1) {
+      return fail('--batch cannot be used with other arguments');
+    }
+    var batchModeState = new BatchModeState()..isBatchMode = true;
+    await runBatch((args) => batchMain(args, batchModeState));
+  } else {
+    CompilerOutcome outcome = await batchMain(args, new BatchModeState());
+    exit(outcome == CompilerOutcome.Ok ? 0 : 1);
+  }
+}
+
+bool isSupportedArgument(String arg) {
+  if (arg.startsWith('--')) {
+    int equals = arg.indexOf('=');
+    var name = equals != -1 ? arg.substring(2, equals) : arg.substring(2);
+    return parser.options.containsKey(name);
+  }
+  if (arg.startsWith('-')) {
+    return parser.findByAbbreviation(arg.substring(1)) != null;
+  }
+  return true;
+}
+
+Future<CompilerOutcome> batchMain(
+    List<String> args, BatchModeState batchModeState) async {
+  if (args.contains('--ignore-unrecognized-flags')) {
+    args = args.where(isSupportedArgument).toList();
+  }
+
+  if (args.isEmpty) {
+    return fail(getUsage());
+  }
+
+  try {
+    options = parser.parse(args);
+  } on FormatException catch (e) {
+    return fail(e.message); // Don't puke stack traces.
+  }
+
+  checkIsDirectoryOrNull(options['sdk'], 'Dart SDK');
+
+  String packagePath = options['packages'] ?? options['package-root'];
+  checkIsFileOrDirectoryOrNull(packagePath, 'Package root or .packages');
+
+  // Set up logging.
+  if (options['verbose']) {
+    log.onRecord.listen((LogRecord rec) {
+      stderr.writeln(rec.message);
+    });
+  }
+
+  if (options.rest.length != 1) {
+    return fail('Exactly one FILE should be given.');
+  }
+
+  var file = options.rest.single;
+
+  checkIsFile(file, option: 'Input file');
+
+  String format = options['format'] ?? defaultFormat();
+  String outputFile = options['out'] ?? defaultOutput();
+
+  List<String> urlMapping = options['url-mapping'] as List<String>;
+  var customUriMappings = parseCustomUriMappings(urlMapping);
+  var repository = new Repository();
+
+  Program program;
+
+  var watch = new Stopwatch()..start();
+  List<String> loadedFiles;
+  Function getLoadedFiles;
+  List errors = const [];
+  TargetFlags targetFlags = new TargetFlags(strongMode: options['strong']);
+  Target target = getTarget(options['target'], targetFlags);
+
+  var declaredVariables = <String, String>{};
+  declaredVariables.addAll(target.extraDeclaredVariables);
+  for (String define in options['D']) {
+    int separator = define.indexOf('=');
+    if (separator == -1) {
+      fail('Invalid define: -D$define. Format is -D<name>=<value>');
+    }
+    String name = define.substring(0, separator);
+    String value = define.substring(separator + 1);
+    declaredVariables[name] = value;
+  }
+
+  if (file.endsWith('.dill')) {
+    program = loadProgramFromBinary(file, repository);
+    getLoadedFiles = () => [file];
+  } else {
+    DartOptions dartOptions = new DartOptions(
+        strongMode: target.strongMode,
+        strongModeSdk: target.strongModeSdk,
+        sdk: options['sdk'],
+        packagePath: packagePath,
+        customUriMappings: customUriMappings,
+        declaredVariables: declaredVariables);
+    String packageDiscoveryPath = batchModeState.isBatchMode ? null : file;
+    DartLoader loader = await batchModeState.batch.getLoader(
+        repository, dartOptions,
+        packageDiscoveryPath: packageDiscoveryPath);
+    if (options['link']) {
+      program = loader.loadProgram(file, target: target);
+    } else {
+      var library = loader.loadLibrary(file);
+      assert(library == repository.getLibrary(file));
+      program = new Program(repository.libraries);
+    }
+    errors = loader.errors;
+    if (errors.isNotEmpty) {
+      const int errorLimit = 100;
+      stderr.writeln(errors.take(errorLimit).join('\n'));
+      if (errors.length > errorLimit) {
+        stderr
+            .writeln('[error] ${errors.length - errorLimit} errors not shown');
+      }
+    }
+    getLoadedFiles = () => loadedFiles ??= loader.getLoadedFileNames();
+  }
+
+  bool canContinueCompilation = errors.isEmpty || options['tolerant'];
+
+  int loadTime = watch.elapsedMilliseconds;
+  if (shouldReportMetrics) {
+    print('loader.time = $loadTime ms');
+  }
+
+  void runVerifier() {
+    if (options['verify-ir']) {
+      verifyProgram(program);
+    }
+  }
+
+  if (canContinueCompilation) {
+    runVerifier();
+  }
+
+  String outputDependencies = options['write-dependencies'];
+  if (outputDependencies != null) {
+    new File(outputDependencies).writeAsStringSync(getLoadedFiles().join('\n'));
+  }
+
+  // Apply target-specific transformations.
+  if (target != null && options['link'] && canContinueCompilation) {
+    target.transformProgram(program);
+    runVerifier();
+  }
+
+  if (options['no-output']) {
+    return CompilerOutcome.Ok;
+  }
+
+  watch.reset();
+
+  Future ioFuture;
+  if (canContinueCompilation) {
+    switch (format) {
+      case 'text':
+        writeProgramToText(program,
+            path: outputFile, showExternal: options['show-external']);
+        break;
+      case 'bin':
+        ioFuture = writeProgramToBinary(program, outputFile);
+        break;
+    }
+  }
+
+  int time = watch.elapsedMilliseconds;
+  if (shouldReportMetrics) {
+    print('writer.time = $time ms');
+  }
+
+  await ioFuture;
+
+  if (shouldReportMetrics) {
+    int flushTime = watch.elapsedMilliseconds - time;
+    print('writer.flush_time = $flushTime ms');
+  }
+
+  return errors.length > 0 ? CompilerOutcome.Fail : CompilerOutcome.Ok;
+}
diff --git a/pkg/kernel/bin/dump.dart b/pkg/kernel/bin/dump.dart
new file mode 100755
index 0000000..540142a
--- /dev/null
+++ b/pkg/kernel/bin/dump.dart
@@ -0,0 +1,11 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+
+main(args) {
+  var binary = loadProgramFromBinary(args[0]);
+  writeProgramToText(binary, path: args[1]);
+}
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
new file mode 100755
index 0000000..680a760
--- /dev/null
+++ b/pkg/kernel/bin/transform.dart
@@ -0,0 +1,96 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:kernel/verifier.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/continuation.dart' as cont;
+import 'package:kernel/transformations/infer_values.dart' as infer_values;
+import 'package:kernel/transformations/mixin_full_resolution.dart' as mix;
+import 'package:kernel/transformations/treeshaker.dart' as treeshaker;
+
+import 'batch_util.dart';
+
+ArgParser parser = new ArgParser()
+  ..addOption('format',
+      abbr: 'f',
+      allowed: ['text', 'bin'],
+      defaultsTo: 'bin',
+      help: 'Output format.')
+  ..addOption('out', abbr: 'o', help: 'Output file.', defaultsTo: null)
+  ..addFlag('verbose',
+      abbr: 'v',
+      negatable: false,
+      help: 'Be verbose (e.g. prints transformed main library).',
+      defaultsTo: false)
+  ..addOption('transformation',
+      abbr: 't',
+      help: 'The transformation to apply.',
+      defaultsTo: 'continuation');
+
+main(List<String> arguments) async {
+  if (arguments.isNotEmpty && arguments[0] == '--batch') {
+    if (arguments.length != 1) {
+      throw '--batch cannot be used with other arguments';
+    }
+    await runBatch((arguments) => runTransformation(arguments));
+  } else {
+    CompilerOutcome outcome = await runTransformation(arguments);
+    exit(outcome == CompilerOutcome.Ok ? 0 : 1);
+  }
+}
+
+Future<CompilerOutcome> runTransformation(List<String> arguments) async {
+  ArgResults options = parser.parse(arguments);
+
+  if (options.rest.length != 1) {
+    throw 'Usage:\n${parser.usage}';
+  }
+
+  var input = options.rest.first;
+  var output = options['out'];
+  var format = options['format'];
+  var verbose = options['verbose'];
+
+  if (output == null) {
+    output = '${input.substring(0, input.lastIndexOf('.'))}.transformed.dill';
+  }
+
+  var program = loadProgramFromBinary(input);
+  switch (options['transformation']) {
+    case 'continuation':
+      program = cont.transformProgram(program);
+      break;
+    case 'infervalues':
+      program = infer_values.transformProgram(program);
+      break;
+    case 'resolve-mixins':
+      program = mix.transformProgram(program);
+      break;
+    case 'treeshake':
+      program = treeshaker.transformProgram(program);
+      break;
+    default:
+      throw 'Unknown transformation';
+  }
+
+  verifyProgram(program);
+
+  if (format == 'text') {
+    writeProgramToText(program, path: output);
+  } else {
+    assert(format == 'bin');
+    await writeProgramToBinary(program, output);
+  }
+
+  if (verbose) {
+    writeLibraryToText(program.mainMethod.parent as Library);
+  }
+
+  return CompilerOutcome.Ok;
+}
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
new file mode 100644
index 0000000..6f8a03a
--- /dev/null
+++ b/pkg/kernel/binary.md
@@ -0,0 +1,904 @@
+This file describes the binary format of Dart Kernel.
+
+Notation
+--------
+Bitmasks are described with the syntax:
+```scala
+    Byte flags (flag1, flag2, ..., flagN)
+```
+where 'flag<N>' is the N-th least significant bit,
+(so flag1 is the least significant bit).
+
+Bytes with tagging bits are described with the syntax:
+```scala
+    Byte byte (10xxxxxx)
+```
+where the x'es represent the bit positions to be extracted from the
+byte and the 0'es and 1'es the bits used for tagging.  The leftmost bit
+is the most significant.
+
+Binary format
+-------------
+```scala
+type Byte = a byte
+
+abstract type UInt {}
+
+type UInt7 extends UInt {
+  Byte byte1(0xxxxxxx);
+}
+
+type UInt14 extends UInt {
+  Byte byte1(10xxxxxx); // most significant byte, discard the high bit
+  Byte byte2(xxxxxxxx); // least signficant byte
+}
+
+type UInt30 extends UInt {
+  Byte byte1(11xxxxxx); // most significant byte, discard the two high bits.
+  Byte byte2(xxxxxxxx);
+  Byte byte3(xxxxxxxx);
+  Byte byte4(xxxxxxxx); // least significant byte
+}
+
+type MagicWord = big endian 32-bit unsigned integer
+
+type String {
+  UInt num_bytes;
+  Byte[num_bytes] utf8_bytes;
+}
+
+type StringTable {
+  UInt num_strings;
+  String[num_strings] strings;
+}
+
+type StringReference {
+  UInt index; // Index into the StringTable.
+}
+
+type LineStarts {
+  UInt lineCount;
+  // Delta encoded, e.g. 0, 10, 15, 7, 10 means 0, 10, 25, 32, 42.
+  UInt[lineCount] lineStarts;
+}
+
+type UriLineStarts {
+  StringTable uris;
+  LineStarts[uris.num_strings] lineStarts;
+}
+
+type UriReference {
+  UInt index; // Index into the URIs StringTable.
+}
+
+type FileOffset {
+  // Saved as number+1 to accommodate literal "-1".
+  UInt fileOffset;
+}
+
+type List<T> {
+  UInt length;
+  T[length] items;
+}
+
+type Option<T> {
+  Byte tag;
+}
+type Nothing extends Option<T> {
+  Byte tag = 0;
+}
+type Something<T> extends Option<T> {
+  Byte tag = 1;
+  T value;
+}
+
+type ProgramFile {
+  MagicWord magic = 0x90ABCDEF;
+  StringTable strings;
+  UriLineStarts lineStartsMap;
+  List<Library> library;
+  LibraryProcedureReference mainMethod;
+}
+
+type LibraryReference {
+  // For library files, this is an index into the import table.
+  // For program files, this is an index into the list of libaries.
+  UInt index;
+}
+
+abstract type ClassReference {}
+
+type NormalClassReference extends ClassReference {
+  Byte tag = 100;
+  LibraryReference library;
+  UInt classIndex;
+}
+
+type MixinClassReference extends ClassReference {
+  Byte tag = 101;
+  LibraryReference library;
+  UInt classIndex;
+}
+
+abstract type MemberReference {
+}
+
+type LibraryFieldReference extends MemberReference {
+  Byte tag = 102;
+  LibraryReference library;
+  UInt fieldIndex; // Index in list of fields.
+}
+
+type ClassFieldReference extends MemberReference {
+  Byte tag = 103;
+  ClassReference class;
+  UInt fieldIndex;
+}
+
+type ClassConstructorReference extends MemberReference {
+  Byte tag = 104;
+  ClassReference class;
+  UInt constructorIndex; // Index in list of constructors.
+}
+
+type LibraryProcedureReference extends MemberReference {
+  Byte tag = 105;
+  LibraryReference library;
+  UInt procedureIndex; // Index in list of procedures.
+}
+
+type ClassProcedureReference extends MemberReference {
+  Byte tag = 106;
+  ClassReference class;
+  UInt procedureIndex;
+}
+
+// Can be used as MemberReference or ClassReference *only* if indicated that
+// the given reference may be a NullReference.
+type NullReference extends MemberReference, ClassReference {
+  Byte tag = 99;
+}
+
+type Name {
+  StringReference name;
+  if name begins with '_' {
+    LibraryReference library;
+  }
+}
+
+type Library {
+  Byte flags (isExternal);
+  StringReference name;
+  // A URI with the dart, package, or file scheme.  For file URIs, the path
+  // is an absolute path to the .dart file from which the library was created.
+  StringReference importUri;
+  // An absolute path URI to the .dart file from which the library was created.
+  UriReference fileUri;
+  List<Class> classes;
+  List<Field> fields;
+  List<Procedure> procedures;
+}
+
+abstract type Node {
+  Byte tag;
+}
+
+// A class can be represented at one of three levels: type, hierarchy, or body.
+//
+// If the enclosing library is external, a class is either at type or
+// hierarchy level, depending on its isTypeLevel flag.
+// If the enclosing library is not external, a class is always at body level.
+//
+// See ClassLevel in ast.dart for the details of each loading level.
+
+abstract type Class extends Node {}
+
+type NormalClass extends Class {
+  Byte tag = 2;
+  Byte flags (isAbstract, isTypeLevel);
+  StringReference name;
+  // An absolute path URI to the .dart file from which the class was created.
+  UriReference fileUri;
+  List<Expression> annotations;
+  List<TypeParameter> typeParameters;
+  Option<InterfaceType> superClass;
+  List<InterfaceType> implementedClasses;
+  List<Field> fields;
+  List<Constructor> constructors;
+  List<Procedure> procedures;
+}
+
+type MixinClass extends Class {
+  Byte tag = 3;
+  Byte flags (isAbstract, isTypeLevel);
+  StringReference name;
+  // An absolute path URI to the .dart file from which the class was created.
+  UriReference fileUri;
+  List<Expression> annotations;
+  List<TypeParameter> typeParameters;
+  InterfaceType firstSuperClass;
+  InterfaceType secondSuperClass;
+  List<InterfaceType> implementedClasses;
+  List<Constructor> constructors;
+}
+
+abstract type Member extends Node {}
+
+type Field extends Member {
+  Byte tag = 4;
+  FileOffset fileOffset;
+  Byte flags (isFinal, isConst, isStatic);
+  Name name;
+  // An absolute path URI to the .dart file from which the field was created.
+  UriReference fileUri;
+  List<Expression> annotations;
+  DartType type;
+  Option<InferredValue> inferredValue;
+  Option<Expression> initializer;
+}
+
+type Constructor extends Member {
+  Byte tag = 5;
+  Byte flags (isConst, isExternal);
+  Name name;
+  List<Expression> annotations;
+  FunctionNode function;
+  List<Initializer> initializers;
+}
+
+/*
+enum ProcedureKind {
+  Method,
+  Getter,
+  Setter,
+  Operator,
+  Factory,
+}
+*/
+
+type Procedure extends Member {
+  Byte tag = 6;
+  Byte kind; // Index into the ProcedureKind enum above.
+  Byte flags (isStatic, isAbstract, isExternal, isConst);
+  Name name;
+  // An absolute path URI to the .dart file from which the class was created.
+  UriReference fileUri;
+  List<Expression> annotations;
+  // Can only be absent if abstract, but tag is there anyway.
+  Option<FunctionNode> function;
+}
+
+abstract type Initializer extends Node {}
+
+type InvalidInitializer extends Initializer {
+  Byte tag = 7;
+}
+
+type FieldInitializer extends Initializer {
+  Byte tag = 8;
+  FieldReference field;
+  Expression value;
+}
+
+type SuperInitializer extends Initializer {
+  Byte tag = 9;
+  ConstructorReference target;
+  Arguments arguments;
+}
+
+type RedirectingInitializer extends Initializer {
+  Byte tag = 10;
+  ConstructorReference target;
+  Arguments arguments;
+}
+
+type LocalInitializer extends Initializer {
+  Byte tag = 11;
+  VariableDeclaration variable;
+}
+
+/*
+enum AsyncMarker {
+  Sync,
+  SyncStar,
+  Async,
+  AsyncStar
+}
+*/
+
+type FunctionNode {
+  // Note: there is no tag on FunctionNode.
+  Byte asyncMarker; // Index into AsyncMarker above.
+  List<TypeParameter> typeParameters;
+  UInt requiredParameterCount;
+  List<VariableDeclaration> positionalParameters;
+  List<VariableDeclaration> namedParameters;
+  DartType returnType;
+  Option<InferredValue> inferredReturnValue;
+  Option<Statement> body;
+}
+
+type VariableReference {
+  // Reference to the Nth variable in scope, with 0 being the
+  // first variable declared in the outermost scope, and larger
+  // numbers being the variables declared later in a given scope,
+  // or in a more deeply nested scope.
+  //
+  // Function parameters are indexed from left to right and make
+  // up the outermost scope (enclosing the function body).
+  // Variables ARE NOT in scope inside their own initializer.
+  // Variables ARE NOT in scope before their declaration, in contrast
+  // to how the Dart Specification defines scoping.
+  // Variables ARE in scope across function boundaries.
+  //
+  // When declared, a variable remains in scope until the end of the
+  // immediately enclosing Block, Let, FunctionNode, ForStatement,
+  // ForInStatement, or Catch.
+  //
+  // A special exception is made for constructor parameters, which are
+  // also in scope in the initializer list, even though the tree nesting
+  // is inconsistent with the scoping.
+  UInt stackIndex;
+}
+
+abstract type Expression extends Node {}
+
+type InvalidExpression extends Expression {
+  Byte tag = 19;
+}
+
+type VariableGet extends Expression {
+  Byte tag = 20;
+  VariableReference variable;
+}
+
+type SpecializedVariableGet extends Expression {
+  Byte tag = 128 + N; // Where 0 <= N < 8.
+  // Equivalent to a VariableGet with index N.
+}
+
+type VariableSet extends Expression {
+  Byte tag = 21;
+  VariableReference variable;
+  Expression value;
+}
+
+type SpecializedVariableSet extends Expression {
+  Byte tag = 136 + N; // Where 0 <= N < 8.
+  Expression value;
+  // Equivalent to VariableSet with index N.
+}
+
+type PropertyGet extends Expression {
+  Byte tag = 22;
+  FileOffset fileOffset;
+  Expression receiver;
+  Name name;
+  MemberReference interfaceTarget; // May be NullReference.
+}
+
+type PropertySet extends Expression {
+  Byte tag = 23;
+  FileOffset fileOffset;
+  Expression receiver;
+  Name name;
+  Expression value;
+  MemberReference interfaceTarget; // May be NullReference.
+}
+
+type SuperPropertyGet extends Expression {
+  Byte tag = 24;
+  Name name;
+  MemberReference interfaceTarget; // May be NullReference.
+}
+
+type SuperPropertySet extends Expression {
+  Byte tag = 25;
+  Name name;
+  Expression value;
+  MemberReference interfaceTarget; // May be NullReference.
+}
+
+type DirectPropertyGet extends Expression {
+  Byte tag = 15; // Note: tag is out of order
+  Expression receiver;
+  MemberReference target;
+}
+
+type DirectPropertySet extends Expression {
+  Byte tag = 16; // Note: tag is out of order
+  Expression receiver;
+  MemberReference target;
+  Expression value;
+}
+
+type StaticGet extends Expression {
+  Byte tag = 26;
+  FileOffset fileOffset;
+  MemberReference target;
+}
+
+type StaticSet extends Expression {
+  Byte tag = 27;
+  MemberReference target;
+  Expression value;
+}
+
+type Arguments {
+  // Note: there is no tag on Arguments.
+  List<DartType> types;
+  List<Expression> positional;
+  List<NamedExpression> named;
+}
+
+type NamedExpression {
+  // Note: there is no tag on NamedExpression.
+  StringReference name;
+  Expression value;
+}
+
+type MethodInvocation extends Expression {
+  Byte tag = 28;
+  FileOffset fileOffset;
+  Expression receiver;
+  Name name;
+  Arguments arguments;
+  MemberReference interfaceTarget; // May be NullReference.
+}
+
+type SuperMethodInvocation extends Expression {
+  Byte tag = 29;
+  FileOffset fileOffset;
+  Name name;
+  Arguments arguments;
+  MemberReference interfaceTarget; // May be NullReference.
+}
+
+type DirectMethodInvocation extends Expression {
+  Byte tag = 17; // Note: tag is out of order
+  Expression receiver;
+  MemberReference target;
+  Arguments arguments;
+}
+
+type StaticInvocation extends Expression {
+  Byte tag = 30;
+  FileOffset fileOffset;
+  MemberReference target;
+  Arguments arguments;
+}
+
+// Constant call to an external constant factory.
+type ConstStaticInvocation extends Expression {
+  Byte tag = 18; // Note: tag is out of order.
+  FileOffset fileOffset;
+  MemberReference target;
+  Arguments arguments;
+}
+
+type ConstructorInvocation extends Expression {
+  Byte tag = 31;
+  FileOffset fileOffset;
+  ConstructorReference target;
+  Arguments arguments;
+}
+
+type ConstConstructorInvocation extends Expression {
+  Byte tag = 32;
+  FileOffset fileOffset;
+  ConstructorReference target;
+  Arguments arguments;
+}
+
+type Not extends Expression {
+  Byte tag = 33;
+  Expression operand;
+}
+
+/*
+ enum LogicalOperator { &&, || }
+*/
+
+type LogicalExpression extends Expression {
+  Byte tag = 34;
+  Expression left;
+  Byte operator; // Index into LogicalOperator enum above
+  Expression right;
+  Option<DartType> staticType;
+}
+
+type ConditionalExpression extends Expression {
+  Byte tag = 35;
+  Expression condition;
+  Expression then;
+  Expression otherwise;
+  Option<DartType> staticType;
+}
+
+type StringConcatenation extends Expression {
+  Byte tag = 36;
+  List<Expression> expressions;
+}
+
+type IsExpression extends Expression {
+  Byte tag = 37;
+  Expression operand;
+  DartType type;
+}
+
+type AsExpression extends Expression {
+  Byte tag = 38;
+  Expression operand;
+  DartType type;
+}
+
+type StringLiteral extends Expression {
+  Byte tag = 39;
+  StringReference value;
+}
+
+type SpecializedIntLiteral extends Expression {
+  Byte tag = 144 + N; // Where 0 <= N < 8.
+  // Integer literal with value (N - 3), that is, an integer in range -3..4.
+}
+
+type PositiveIntLiteral extends Expression {
+  Byte tag = 55;
+  UInt value;
+}
+
+type NegativeIntLiteral extends Expression {
+  Byte tag = 56;
+  UInt absoluteValue;
+}
+
+type BigIntLiteral extends Expression {
+  Byte tag = 57;
+  StringReference valueString;
+}
+
+type DoubleLiteral extends Expression {
+  Byte tag = 40;
+  StringReference valueString;
+}
+
+type TrueLiteral extends Expression {
+  Byte tag = 41;
+}
+
+type FalseLiteral extends Expression {
+  Byte tag = 42;
+}
+
+type NullLiteral extends Expression {
+  Byte tag = 43;
+}
+
+type SymbolLiteral extends Expression {
+  Byte tag = 44;
+  StringReference value; // Everything strictly after the '#'.
+}
+
+type TypeLiteral extends Expression {
+  Byte tag = 45;
+  DartType type;
+}
+
+type ThisExpression extends Expression {
+  Byte tag = 46;
+}
+
+type Rethrow extends Expression {
+  Byte tag = 47;
+}
+
+type Throw extends Expression {
+  Byte tag = 48;
+  FileOffset fileOffset;
+  Expression value;
+}
+
+type ListLiteral extends Expression {
+  Byte tag = 49;
+  DartType typeArgument;
+  List<Expression> values;
+}
+
+type ConstListLiteral extends Expression {
+  Byte tag = 58; // Note: tag is out of order.
+  DartType typeArgument;
+  List<Expression> values;
+}
+
+type MapLiteral extends Expression {
+  Byte tag = 50;
+  DartType keyType;
+  DartType valueType;
+  List<MapEntry> entries;
+}
+
+type ConstMapLiteral extends Expression {
+  Byte tag = 59; // Note: tag is out of order.
+  DartType keyType;
+  DartType valueType;
+  List<MapEntry> entries;
+}
+
+type MapEntry {
+  // Note: there is no tag on MapEntry
+  Expression key;
+  Expression value;
+}
+
+type AwaitExpression extends Expression {
+  Byte tag = 51;
+  Expression operand;
+}
+
+type FunctionExpression extends Expression {
+  Byte tag = 52;
+  FunctionNode function;
+}
+
+type Let extends Expression {
+  Byte tag = 53;
+  VariableDeclaration variable;
+  Expression body;
+}
+
+abstract type Statement extends Node {}
+
+type InvalidStatement extends Statement {
+  Byte tag = 60;
+}
+
+type ExpressionStatement extends Statement {
+  Byte tag = 61;
+  Expression expression;
+}
+
+type Block extends Statement {
+  Byte tag = 62;
+  List<Expression> expressions;
+}
+
+type EmptyStatement extends Statement {
+  Byte tag = 63;
+}
+
+type AssertStatement extends Statement {
+  Byte tag = 64;
+  Expression condition;
+  Option<Expression> message;
+}
+
+type LabeledStatement extends Statement {
+  Byte tag = 65;
+  Statement body;
+}
+
+type BreakStatement extends Statement {
+  Byte tag = 66;
+
+  // Reference to the Nth LabeledStatement in scope, with 0 being the
+  // outermost enclosing labeled statement within the same FunctionNode.
+  //
+  // Labels are not in scope across function boundaries.
+  UInt labelIndex;
+}
+
+type WhileStatement extends Statement {
+  Byte tag = 67;
+  Expression condition;
+  Statement body;
+}
+
+type DoStatement extends Statement {
+  Byte tag = 68;
+  Statement body;
+  Expression condition;
+}
+
+type ForStatement extends Statement {
+  Byte tag = 69;
+  List<VariableDeclaration> variables;
+  Option<Expression> condition;
+  List<Expression> updates;
+  Statement body;
+}
+
+type ForInStatement extends Statement {
+  Byte tag = 70;
+  VariableDeclaration variable;
+  Expression iterable;
+  Statement body;
+}
+
+type AsyncForInStatement extends Statement {
+  Byte tag = 80; // Note: tag is out of order.
+  VariableDeclaration variable;
+  Expression iterable;
+  Statement body;
+}
+
+type SwitchStatement extends Statement {
+  Byte tag = 71;
+  Expression expression;
+  List<SwitchCase> cases;
+}
+
+type SwitchCase {
+  // Note: there is no tag on SwitchCase
+  List<Expression> expressions;
+  Byte isDefault; // 1 if default, 0 is not default.
+  Statement body;
+}
+
+type ContinueSwitchStatement extends Statement {
+  Byte tag = 72;
+
+  // Reference to the Nth SwitchCase in scope.
+  //
+  // A SwitchCase is in scope everywhere within its enclosing switch,
+  // except the scope is delimited by FunctionNodes.
+  //
+  // Switches are ordered from outermost to innermost, and the SwitchCases
+  // within a switch are consecutively indexed from first to last, so index
+  // 0 is the first SwitchCase of the outermost enclosing switch in the
+  // same FunctionNode.
+  UInt caseIndex;
+}
+
+type IfStatement extends Statement {
+  Byte tag = 73;
+  Expression condition;
+  Statement then;
+  Statement otherwise; // Empty statement if there was no else part.
+}
+
+type ReturnStatement extends Statement {
+  Byte tag = 74;
+  Option<Expression> expression;
+}
+
+type TryCatch extends Statement {
+  Byte tag = 75;
+  Statement body;
+  List<Catch> catches;
+}
+
+type Catch {
+  DartType guard;
+  Option<VariableDeclaration> exception;
+  Option<VariableDeclaration> stackTrace;
+  Statement body;
+}
+
+type TryFinally extends Statement {
+  Byte tag = 76;
+  Statement body;
+  Statement finalizer;
+}
+
+type YieldStatement extends Statement {
+  Byte tag = 77;
+  Byte flags (isYieldStar);
+  Expression expression;
+}
+
+type VariableDeclarationStatement extends Statement {
+  Byte tag = 78;
+  VariableDeclaration variable;
+}
+
+type VariableDeclaration {
+  Byte flags (isFinal, isConst);
+  // For named parameters, this is the parameter name.
+  // For other variables, the name is cosmetic, may be empty,
+  // and is not necessarily unique.
+  StringReference name;
+  DartType type;
+  Option<InferredValue> inferredValue;
+
+  // For statements and for-loops, this is the initial value.
+  // For optional parameters, this is the default value (if given).
+  // In all other contexts, it must be Nothing.
+  Option<Expression> initializer;
+}
+
+type FunctionDeclaration extends Statement {
+  Byte tag = 79;
+  // The variable binding the function.  The variable is in scope
+  // within the function for use as a self-reference.
+  // Some of the fields in the variable are redundant, but its presence here
+  // simplifies the rule for variable indexing.
+  VariableDeclaration variable;
+  FunctionNode function;
+}
+
+abstract type DartType extends Node {}
+
+type InvalidType extends DartType {
+  Byte tag = 90;
+}
+
+type DynamicType extends DartType {
+  Byte tag = 91;
+}
+
+type VoidType extends DartType {
+  Byte tag = 92;
+}
+
+type InterfaceType extends DartType {
+  Byte tag = 93;
+  ClassReference class;
+  List<DartType> typeArguments;
+}
+
+type SimpleInterfaceType extends DartType {
+  Byte tag = 96; // Note: tag is out of order.
+  ClassReference class;
+  // Equivalent to InterfaceType with empty list of type arguments.
+}
+
+type FunctionType extends DartType {
+  Byte tag = 94;
+  List<TypeParameter> typeParameters;
+  UInt requiredParameterCount;
+  List<DartType> positionalParameters;
+  List<NamedDartType> namedParameters;
+  DartType returnType;
+}
+
+type SimpleFunctionType extends DartType {
+  Byte tag = 97; // Note: tag is out of order.
+  List<DartType> positionalParameters;
+  DartType returnType;
+  // Equivalent to a FunctionType with no type parameters or named parameters,
+  // and where all positional parameters are required.
+}
+
+type NamedDartType {
+  StringReference name;
+  DartType type;
+}
+
+type TypeParameterType extends DartType {
+  Byte tag = 95;
+
+  // Reference to the Nth type parameter in scope (with some caveats about
+  // type parameter bounds).
+  //
+  // As with the other indexing schemes, outermost nodes have lower
+  // indices, and a type parameter list is consecutively indexed from
+  // left to right.
+  //
+  // In the case of type parameter bounds, this indexing diverges slightly
+  // from the definition of scoping, since type parameter N+1 is not "in scope"
+  // in the bound of type parameter N, but it takes up an index as if it was in
+  // scope there.
+  //
+  // The type parameter can be bound by a Class, FunctionNode, or FunctionType.
+  //
+  // Note that constructors currently do not declare type parameters.  Uses of
+  // the class type parameters in a constructor refer to those declared on the
+  // class.
+  UInt index;
+}
+
+type TypeParameter {
+  // Note: there is no tag on TypeParameter
+  StringReference name; // Cosmetic, may be empty, not unique.
+  DartType bound; // 'dynamic' if no explicit bound was given.
+}
+
+/* enum BaseClassKind { None, Exact, Subclass, Subtype, } */
+
+type InferredValue {
+  ClassReference baseClass; // May be NullReference if kind = None.
+  Byte kind; // Index into BaseClassKind.
+  Byte valueBits; // See lib/type_propagation/type_propagation.dart
+}
+
+```
diff --git a/pkg/kernel/codereview.settings b/pkg/kernel/codereview.settings
new file mode 100644
index 0000000..d777626
--- /dev/null
+++ b/pkg/kernel/codereview.settings
@@ -0,0 +1,7 @@
+# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+CODE_REVIEW_SERVER: http://codereview.chromium.org
+VIEW_VC: https://github.com/dart-lang/kernel/commit/
+PROJECT: Dart Kernel
+CC_LIST: dart-kernel+reviews@google.com
diff --git a/pkg/kernel/lib/analyzer/analyzer.dart b/pkg/kernel/lib/analyzer/analyzer.dart
new file mode 100644
index 0000000..4ae4a67
--- /dev/null
+++ b/pkg/kernel/lib/analyzer/analyzer.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 library that re-exports the analyzer's program representation parts.
+library kernel.analyzer.frontend;
+
+export 'package:analyzer/dart/ast/visitor.dart';
+export 'package:analyzer/dart/ast/ast.dart';
+export 'package:analyzer/dart/element/element.dart';
+export 'package:analyzer/dart/element/type.dart';
+export 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
+export 'package:analyzer/src/dart/element/member.dart' show Member;
+export 'package:analyzer/dart/ast/token.dart' show Token;
diff --git a/pkg/kernel/lib/analyzer/ast_from_analyzer.dart b/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
new file mode 100644
index 0000000..9847b59
--- /dev/null
+++ b/pkg/kernel/lib/analyzer/ast_from_analyzer.dart
@@ -0,0 +1,2806 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.analyzer.ast_from_analyzer;
+
+import '../ast.dart' as ast;
+import '../frontend/accessors.dart';
+import '../frontend/super_initializers.dart';
+import '../log.dart';
+import '../type_algebra.dart';
+import '../transformations/flags.dart';
+import 'analyzer.dart';
+import 'loader.dart';
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+/// Provides reference-level access to libraries, classes, and members.
+///
+/// "Reference level" objects are incomplete nodes that have no children but
+/// can be used for linking until the loader promotes the node to a higher
+/// loading level.
+///
+/// The [ReferenceScope] is the most restrictive scope in a hierarchy of scopes
+/// that provide increasing amounts of contextual information.  [TypeScope] is
+/// used when type parameters might be in scope, and [MemberScope] is used when
+/// building the body of a [ast.Member].
+class ReferenceScope {
+  final ReferenceLevelLoader loader;
+
+  ReferenceScope(this.loader);
+
+  bool get strongMode => loader.strongMode;
+
+  ast.Library getLibraryReference(LibraryElement element) {
+    if (element == null) return null;
+    return loader.getLibraryReference(getBaseElement(element));
+  }
+
+  ast.Class getRootClassReference() {
+    return loader.getRootClassReference();
+  }
+
+  ast.Class getClassReference(ClassElement element) {
+    return loader.getClassReference(getBaseElement(element));
+  }
+
+  ast.Member getMemberReference(Element element) {
+    return loader.getMemberReference(getBaseElement(element));
+  }
+
+  static Element getBaseElement(Element element) {
+    while (element is Member) {
+      element = (element as Member).baseElement;
+    }
+    return element;
+  }
+
+  static bool supportsConcreteGet(Element element) {
+    return (element is PropertyAccessorElement &&
+            element.isGetter &&
+            !element.isAbstract) ||
+        element is FieldElement ||
+        element is TopLevelVariableElement ||
+        element is MethodElement && !element.isAbstract ||
+        isTopLevelFunction(element);
+  }
+
+  static bool supportsInterfaceGet(Element element) {
+    return (element is PropertyAccessorElement && element.isGetter) ||
+        element is FieldElement ||
+        element is MethodElement;
+  }
+
+  static bool supportsConcreteSet(Element element) {
+    return (element is PropertyAccessorElement &&
+            element.isSetter &&
+            !element.isAbstract) ||
+        element is FieldElement && !element.isFinal && !element.isConst ||
+        element is TopLevelVariableElement &&
+            !element.isFinal &&
+            !element.isConst;
+  }
+
+  static bool supportsInterfaceSet(Element element) {
+    return (element is PropertyAccessorElement && element.isSetter) ||
+        element is FieldElement && !element.isFinal && !element.isConst;
+  }
+
+  static bool supportsConcreteIndexGet(Element element) {
+    return element is MethodElement &&
+        element.name == '[]' &&
+        !element.isAbstract;
+  }
+
+  static bool supportsInterfaceIndexGet(Element element) {
+    return element is MethodElement && element.name == '[]';
+  }
+
+  static bool supportsConcreteIndexSet(Element element) {
+    return element is MethodElement &&
+        element.name == '[]=' &&
+        !element.isAbstract;
+  }
+
+  static bool supportsInterfaceIndexSet(Element element) {
+    return element is MethodElement && element.name == '[]=';
+  }
+
+  static bool supportsConcreteMethodCall(Element element) {
+    // Note that local functions are not valid targets for method calls because
+    // they are not "methods" or even "procedures" in our AST.
+    return element is MethodElement && !element.isAbstract ||
+        isTopLevelFunction(element) ||
+        element is ConstructorElement && element.isFactory;
+  }
+
+  static bool supportsInterfaceMethodCall(Element element) {
+    return element is MethodElement;
+  }
+
+  static bool supportsConstructorCall(Element element) {
+    return element is ConstructorElement && !element.isFactory;
+  }
+
+  ast.Member _resolveGet(
+      Element element, Element auxiliary, bool predicate(Element element)) {
+    element = desynthesizeGetter(element);
+    if (predicate(element)) return getMemberReference(element);
+    if (element is PropertyAccessorElement && element.isSetter) {
+      // The getter is sometimes stored as the 'corresponding getter' instead
+      // of the 'auxiliary' element.
+      auxiliary ??= element.correspondingGetter;
+    }
+    auxiliary = desynthesizeGetter(auxiliary);
+    if (predicate(auxiliary)) return getMemberReference(auxiliary);
+    return null;
+  }
+
+  ast.Member resolveConcreteGet(Element element, Element auxiliary) {
+    return _resolveGet(element, auxiliary, supportsConcreteGet);
+  }
+
+  ast.Member resolveInterfaceGet(Element element, Element auxiliary) {
+    if (!strongMode) return null;
+    return _resolveGet(element, auxiliary, supportsInterfaceGet);
+  }
+
+  DartType getterTypeOfElement(Element element) {
+    if (element is VariableElement) {
+      return element.type;
+    } else if (element is PropertyAccessorElement && element.isGetter) {
+      return element.returnType;
+    } else {
+      return null;
+    }
+  }
+
+  /// Returns the interface target of a `call` dispatch to the given member.
+  ///
+  /// For example, if the member is a field of type C, the target will be the
+  /// `call` method of class C, if it has such a method.
+  ///
+  /// If the class C has a getter or field named `call`, this method returns
+  /// `null` - the static type system does support typed calls with indirection.
+  ast.Member resolveInterfaceFunctionCall(Element element) {
+    if (!strongMode || element == null) return null;
+    return resolveInterfaceFunctionCallOnType(getterTypeOfElement(element));
+  }
+
+  /// Returns the `call` method of [callee], if it has one, otherwise `null`.
+  ast.Member resolveInterfaceFunctionCallOnType(DartType callee) {
+    return callee is InterfaceType
+        ? resolveInterfaceMethod(callee.getMethod('call'))
+        : null;
+  }
+
+  ast.Member _resolveSet(
+      Element element, Element auxiliary, bool predicate(Element element)) {
+    element = desynthesizeSetter(element);
+    if (predicate(element)) {
+      return getMemberReference(element);
+    }
+    if (element is PropertyAccessorElement && element.isSetter) {
+      // The setter is sometimes stored as the 'corresponding setter' instead
+      // of the 'auxiliary' element.
+      auxiliary ??= element.correspondingGetter;
+    }
+    auxiliary = desynthesizeSetter(auxiliary);
+    if (predicate(auxiliary)) {
+      return getMemberReference(auxiliary);
+    }
+    return null;
+  }
+
+  ast.Member resolveConcreteSet(Element element, Element auxiliary) {
+    return _resolveSet(element, auxiliary, supportsConcreteSet);
+  }
+
+  ast.Member resolveInterfaceSet(Element element, Element auxiliary) {
+    if (!strongMode) return null;
+    return _resolveSet(element, auxiliary, supportsInterfaceSet);
+  }
+
+  ast.Member resolveConcreteIndexGet(Element element, Element auxiliary) {
+    if (supportsConcreteIndexGet(element)) {
+      return getMemberReference(element);
+    }
+    if (supportsConcreteIndexGet(auxiliary)) {
+      return getMemberReference(auxiliary);
+    }
+    return null;
+  }
+
+  ast.Member resolveInterfaceIndexGet(Element element, Element auxiliary) {
+    if (!strongMode) return null;
+    if (supportsInterfaceIndexGet(element)) {
+      return getMemberReference(element);
+    }
+    if (supportsInterfaceIndexGet(auxiliary)) {
+      return getMemberReference(auxiliary);
+    }
+    return null;
+  }
+
+  ast.Member resolveConcreteIndexSet(Element element, Element auxiliary) {
+    if (supportsConcreteIndexSet(element)) {
+      return getMemberReference(element);
+    }
+    if (supportsConcreteIndexSet(auxiliary)) {
+      return getMemberReference(auxiliary);
+    }
+    return null;
+  }
+
+  ast.Member resolveInterfaceIndexSet(Element element, Element auxiliary) {
+    if (!strongMode) return null;
+    if (supportsInterfaceIndexSet(element)) {
+      return getMemberReference(element);
+    }
+    if (supportsInterfaceIndexSet(auxiliary)) {
+      return getMemberReference(auxiliary);
+    }
+    return null;
+  }
+
+  ast.Member resolveConcreteMethod(Element element) {
+    if (supportsConcreteMethodCall(element)) {
+      return getMemberReference(element);
+    }
+    return null;
+  }
+
+  ast.Member resolveInterfaceMethod(Element element) {
+    if (!strongMode) return null;
+    if (supportsInterfaceMethodCall(element)) {
+      return getMemberReference(element);
+    }
+    return null;
+  }
+
+  ast.Constructor resolveConstructor(Element element) {
+    if (supportsConstructorCall(element)) {
+      return getMemberReference(element);
+    }
+    return null;
+  }
+
+  ast.Field resolveField(Element element) {
+    if (element is FieldElement && !element.isSynthetic) {
+      return getMemberReference(element);
+    }
+    return null;
+  }
+
+  /// A static accessor that generates a 'throw NoSuchMethodError' when a
+  /// read or write access could not be resolved.
+  Accessor staticAccess(String name, Element element, [Element auxiliary]) {
+    return new _StaticAccessor(
+        this,
+        name,
+        resolveConcreteGet(element, auxiliary),
+        resolveConcreteSet(element, auxiliary));
+  }
+
+  /// An accessor that generates a 'throw NoSuchMethodError' on both read
+  /// and write access.
+  Accessor unresolvedAccess(String name) {
+    return new _StaticAccessor(this, name, null, null);
+  }
+}
+
+class TypeScope extends ReferenceScope {
+  final Map<TypeParameterElement, ast.TypeParameter> localTypeParameters =
+      <TypeParameterElement, ast.TypeParameter>{};
+
+  TypeScope(ReferenceLevelLoader loader) : super(loader);
+
+  String get location => '?';
+
+  bool get allowClassTypeParameters => false;
+
+  ast.DartType get defaultTypeParameterBound => getRootClassReference().rawType;
+
+  ast.TypeParameter getTypeParameterReference(TypeParameterElement element) {
+    return localTypeParameters[element] ??
+        loader.tryGetClassTypeParameter(element) ??
+        (localTypeParameters[element] = new ast.TypeParameter(element.name));
+  }
+
+  ast.TypeParameter makeTypeParameter(TypeParameterElement element,
+      {ast.DartType bound}) {
+    var typeParameter = getTypeParameterReference(element);
+    assert(bound != null);
+    typeParameter.bound = bound;
+    return typeParameter;
+  }
+
+  ast.DartType buildType(DartType type) {
+    return new TypeAnnotationBuilder(this).buildFromDartType(type);
+  }
+
+  ast.Supertype buildSupertype(DartType type) {
+    if (type is InterfaceType) {
+      var classElement = type.element;
+      if (classElement == null) return getRootClassReference().asRawSupertype;
+      var classNode = getClassReference(classElement);
+      if (classNode.typeParameters.isEmpty ||
+          classNode.typeParameters.length != type.typeArguments.length) {
+        return classNode.asRawSupertype;
+      } else {
+        return new ast.Supertype(classNode,
+            type.typeArguments.map(buildType).toList(growable: false));
+      }
+    }
+    return getRootClassReference().asRawSupertype;
+  }
+
+  ast.DartType buildTypeAnnotation(AstNode node) {
+    return new TypeAnnotationBuilder(this).build(node);
+  }
+
+  ast.DartType buildOptionalTypeAnnotation(AstNode node) {
+    return node == null ? null : new TypeAnnotationBuilder(this).build(node);
+  }
+
+  ast.DartType getInferredType(Expression node) {
+    if (!strongMode) return const ast.DynamicType();
+    // TODO: Is this official way to get the strong-mode inferred type?
+    return buildType(node.staticType);
+  }
+
+  ast.DartType getInferredTypeArgument(Expression node, int index) {
+    var type = getInferredType(node);
+    return type is ast.InterfaceType && index < type.typeArguments.length
+        ? type.typeArguments[index]
+        : const ast.DynamicType();
+  }
+
+  ast.DartType getInferredReturnType(Expression node) {
+    var type = getInferredType(node);
+    return type is ast.FunctionType ? type.returnType : const ast.DynamicType();
+  }
+
+  List<ast.DartType> getInferredInvocationTypeArguments(
+      InvocationExpression node) {
+    if (!strongMode) return <ast.DartType>[];
+    ast.DartType inferredFunctionType = buildType(node.staticInvokeType);
+    ast.DartType genericFunctionType = buildType(node.function.staticType);
+    if (genericFunctionType is ast.FunctionType) {
+      if (genericFunctionType.typeParameters.isEmpty) return <ast.DartType>[];
+      // Attempt to unify the two types to obtain a substitution of the type
+      // variables.  If successful, use the substituted types in the order
+      // they occur in the type parameter list.
+      var substitution = unifyTypes(genericFunctionType.withoutTypeParameters,
+          inferredFunctionType, genericFunctionType.typeParameters.toSet());
+      if (substitution != null) {
+        return genericFunctionType.typeParameters
+            .map((p) => substitution[p] ?? const ast.DynamicType())
+            .toList();
+      }
+      return new List<ast.DartType>.filled(
+          genericFunctionType.typeParameters.length, const ast.DynamicType());
+    } else {
+      return <ast.DartType>[];
+    }
+  }
+
+  List<ast.DartType> buildOptionalTypeArgumentList(TypeArgumentList node) {
+    if (node == null) return null;
+    return new TypeAnnotationBuilder(this).buildList(node.arguments);
+  }
+
+  List<ast.DartType> buildTypeArgumentList(TypeArgumentList node) {
+    return new TypeAnnotationBuilder(this).buildList(node.arguments);
+  }
+
+  List<ast.TypeParameter> buildOptionalTypeParameterList(
+      TypeParameterList node) {
+    if (node == null) return <ast.TypeParameter>[];
+    return node.typeParameters.map(buildTypeParameter).toList();
+  }
+
+  ast.TypeParameter buildTypeParameter(TypeParameter node) {
+    return makeTypeParameter(node.element,
+        bound: buildOptionalTypeAnnotation(node.bound) ??
+            defaultTypeParameterBound);
+  }
+
+  ConstructorElement findDefaultConstructor(ClassElement class_) {
+    for (var constructor in class_.constructors) {
+      // Note: isDefaultConstructor checks if the constructor is suitable for
+      // being invoked without arguments.  It does not imply that it is
+      // synthetic.
+      if (constructor.isDefaultConstructor && !constructor.isFactory) {
+        return constructor;
+      }
+    }
+    return null;
+  }
+
+  ast.FunctionNode buildFunctionInterface(FunctionTypedElement element) {
+    var positional = <ast.VariableDeclaration>[];
+    var named = <ast.VariableDeclaration>[];
+    int requiredParameterCount = 0;
+    // Initialize type parameters in two passes: put them into scope,
+    // and compute the bounds afterwards while they are all in scope.
+    var typeParameters = <ast.TypeParameter>[];
+    for (var parameter in element.typeParameters) {
+      var parameterNode = new ast.TypeParameter(parameter.name);
+      typeParameters.add(parameterNode);
+      localTypeParameters[parameter] = parameterNode;
+    }
+    for (int i = 0; i < typeParameters.length; ++i) {
+      var parameter = element.typeParameters[i];
+      var parameterNode = typeParameters[i];
+      parameterNode.bound = parameter.bound == null
+          ? defaultTypeParameterBound
+          : buildType(parameter.bound);
+    }
+    for (var parameter in element.parameters) {
+      var parameterNode = new ast.VariableDeclaration(parameter.name,
+          type: buildType(parameter.type));
+      switch (parameter.parameterKind) {
+        case ParameterKind.REQUIRED:
+          positional.add(parameterNode);
+          ++requiredParameterCount;
+          break;
+
+        case ParameterKind.POSITIONAL:
+          positional.add(parameterNode);
+          break;
+
+        case ParameterKind.NAMED:
+          named.add(parameterNode);
+          break;
+      }
+    }
+    var returnType = element is ConstructorElement
+        ? const ast.VoidType()
+        : buildType(element.returnType);
+    return new ast.FunctionNode(null,
+        typeParameters: typeParameters,
+        positionalParameters: positional,
+        namedParameters: named,
+        requiredParameterCount: requiredParameterCount,
+        returnType: returnType);
+  }
+}
+
+class ExpressionScope extends TypeScope {
+  ast.Library currentLibrary;
+  final Map<LocalElement, ast.VariableDeclaration> localVariables =
+      <LocalElement, ast.VariableDeclaration>{};
+
+  ExpressionBuilder _expressionBuilder;
+  StatementBuilder _statementBuilder;
+
+  ExpressionScope(ReferenceLevelLoader loader, this.currentLibrary)
+      : super(loader) {
+    assert(currentLibrary != null);
+    _expressionBuilder = new ExpressionBuilder(this);
+    _statementBuilder = new StatementBuilder(this);
+  }
+
+  bool get allowThis => false; // Overridden by MemberScope.
+
+  ast.Name buildName(SimpleIdentifier node) {
+    return new ast.Name(node.name, currentLibrary);
+  }
+
+  ast.Statement buildStatement(Statement node) {
+    return _statementBuilder.build(node);
+  }
+
+  ast.Statement buildOptionalFunctionBody(FunctionBody body) {
+    if (body == null ||
+        body is EmptyFunctionBody ||
+        body is NativeFunctionBody) {
+      return null;
+    }
+    return buildMandatoryFunctionBody(body);
+  }
+
+  ast.Statement buildMandatoryFunctionBody(FunctionBody body) {
+    try {
+      if (body is BlockFunctionBody) {
+        return buildStatement(body.block);
+      } else if (body is ExpressionFunctionBody) {
+        if (bodyHasVoidReturn(body)) {
+          return new ast.ExpressionStatement(buildExpression(body.expression));
+        } else {
+          return new ast.ReturnStatement(buildExpression(body.expression));
+        }
+      } else {
+        return internalError('Missing function body');
+      }
+    } on _CompilationError catch (e) {
+      return new ast.ExpressionStatement(buildThrowCompileTimeError(e.message));
+    }
+  }
+
+  ast.AsyncMarker getAsyncMarker({bool isAsync: false, bool isStar: false}) {
+    return ast.AsyncMarker.values[(isAsync ? 2 : 0) + (isStar ? 1 : 0)];
+  }
+
+  ast.FunctionNode buildFunctionNode(
+      FormalParameterList formalParameters, FunctionBody body,
+      {TypeName returnType,
+      List<ast.TypeParameter> typeParameters,
+      ast.DartType inferredReturnType}) {
+    // TODO(asgerf): This will in many cases rebuild the interface built by
+    //   TypeScope.buildFunctionInterface.
+    var positional = <ast.VariableDeclaration>[];
+    var named = <ast.VariableDeclaration>[];
+    int requiredParameterCount = 0;
+    var formals = formalParameters?.parameters ?? const <FormalParameter>[];
+    for (var parameter in formals) {
+      var declaration = makeVariableDeclaration(parameter.element,
+          initializer: parameter is DefaultFormalParameter
+              ? buildOptionalTopLevelExpression(parameter.defaultValue)
+              : null,
+          type: buildType(parameter.element.type));
+      switch (parameter.kind) {
+        case ParameterKind.REQUIRED:
+          positional.add(declaration);
+          ++requiredParameterCount;
+          declaration.initializer = null;
+          break;
+
+        case ParameterKind.POSITIONAL:
+          positional.add(declaration);
+          break;
+
+        case ParameterKind.NAMED:
+          named.add(declaration);
+          break;
+      }
+    }
+    return new ast.FunctionNode(buildOptionalFunctionBody(body),
+        typeParameters: typeParameters,
+        positionalParameters: positional,
+        namedParameters: named,
+        requiredParameterCount: requiredParameterCount,
+        returnType: buildOptionalTypeAnnotation(returnType) ??
+            inferredReturnType ??
+            const ast.DynamicType(),
+        asyncMarker: getAsyncMarker(
+            isAsync: body.isAsynchronous, isStar: body.isGenerator));
+  }
+
+  ast.Expression buildOptionalTopLevelExpression(Expression node) {
+    return node == null ? null : buildTopLevelExpression(node);
+  }
+
+  ast.Expression buildTopLevelExpression(Expression node) {
+    try {
+      return _expressionBuilder.build(node);
+    } on _CompilationError catch (e) {
+      return buildThrowCompileTimeError(e.message);
+    }
+  }
+
+  ast.Expression buildExpression(Expression node) {
+    return _expressionBuilder.build(node);
+  }
+
+  ast.Expression buildOptionalExpression(Expression node) {
+    return node == null ? null : _expressionBuilder.build(node);
+  }
+
+  Accessor buildLeftHandValue(Expression node) {
+    return _expressionBuilder.buildLeftHandValue(node);
+  }
+
+  ast.Expression buildStringLiteral(Expression node) {
+    List<ast.Expression> parts = <ast.Expression>[];
+    new StringLiteralPartBuilder(this, parts).build(node);
+    return parts.length == 1 && parts[0] is ast.StringLiteral
+        ? parts[0]
+        : new ast.StringConcatenation(parts);
+  }
+
+  ast.Expression buildThis() {
+    return allowThis
+        ? new ast.ThisExpression()
+        : emitCompileTimeError(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS);
+  }
+
+  ast.Initializer buildInitializer(ConstructorInitializer node) {
+    try {
+      return new InitializerBuilder(this).build(node);
+    } on _CompilationError catch (_) {
+      return new ast.InvalidInitializer();
+    }
+  }
+
+  bool isFinal(Element element) {
+    return element is VariableElement && element.isFinal ||
+        element is FunctionElement;
+  }
+
+  bool isConst(Element element) {
+    return element is VariableElement && element.isConst;
+  }
+
+  ast.VariableDeclaration getVariableReference(LocalElement element) {
+    return localVariables.putIfAbsent(element, () {
+      return new ast.VariableDeclaration(element.name,
+          isFinal: isFinal(element), isConst: isConst(element));
+    });
+  }
+
+  ast.DartType getInferredVariableType(Element element) {
+    if (!strongMode) return const ast.DynamicType();
+    if (element is FunctionTypedElement) {
+      return buildType(element.type);
+    } else if (element is VariableElement) {
+      return buildType(element.type);
+    } else {
+      log.severe('Unexpected variable element: $element');
+      return const ast.DynamicType();
+    }
+  }
+
+  ast.VariableDeclaration makeVariableDeclaration(LocalElement element,
+      {ast.DartType type, ast.Expression initializer}) {
+    var declaration = getVariableReference(element);
+    declaration.type = type ?? getInferredVariableType(element);
+    if (initializer != null) {
+      declaration.initializer = initializer..parent = declaration;
+    }
+    return declaration;
+  }
+
+  /// Returns true if [arguments] can be accepted by [target]
+  /// (not taking type checks into account).
+  bool areArgumentsCompatible(
+      FunctionTypedElement target, ast.Arguments arguments) {
+    var positionals = arguments.positional;
+    var parameters = target.parameters;
+    const required = ParameterKind.REQUIRED; // For avoiding long lines.
+    const named = ParameterKind.NAMED;
+    // If the first unprovided parameter is required, there are too few
+    // positional arguments.
+    if (positionals.length < parameters.length &&
+        parameters[positionals.length].parameterKind == required) {
+      return false;
+    }
+    // If there are more positional arguments than parameters, or if the last
+    // positional argument corresponds to a named parameter, there are too many
+    // positional arguments.
+    if (positionals.length > parameters.length) return false;
+    if (positionals.isNotEmpty &&
+        parameters[positionals.length - 1].parameterKind == named) {
+      return false; // Too many positional arguments.
+    }
+    if (arguments.named.isEmpty) return true;
+    int firstNamedParameter = positionals.length;
+    while (firstNamedParameter < parameters.length &&
+        parameters[firstNamedParameter].parameterKind != ParameterKind.NAMED) {
+      ++firstNamedParameter;
+    }
+    namedLoop:
+    for (int i = 0; i < arguments.named.length; ++i) {
+      String name = arguments.named[i].name;
+      for (int j = firstNamedParameter; j < parameters.length; ++j) {
+        if (parameters[j].parameterKind == ParameterKind.NAMED &&
+            parameters[j].name == name) {
+          continue namedLoop;
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+
+  /// Throws a NoSuchMethodError corresponding to a call to [memberName] on
+  /// [receiver] with the given [arguments].
+  ///
+  /// If provided, [candiateTarget] provides the expected arity and argument
+  /// names for the best candidate target.
+  ast.Expression buildThrowNoSuchMethodError(
+      ast.Expression receiver, String memberName, ast.Arguments arguments,
+      {Element candidateTarget}) {
+    // TODO(asgerf): When we have better integration with patch files, use
+    //   the internal constructor that provides a more detailed error message.
+    ast.Expression candidateArgumentNames;
+    if (candidateTarget is FunctionTypedElement) {
+      candidateArgumentNames = new ast.ListLiteral(candidateTarget.parameters
+          .map((p) => new ast.StringLiteral(p.name))
+          .toList());
+    } else {
+      candidateArgumentNames = new ast.NullLiteral();
+    }
+    return new ast.Throw(new ast.ConstructorInvocation(
+        loader.getCoreClassConstructorReference('NoSuchMethodError'),
+        new ast.Arguments(<ast.Expression>[
+          receiver,
+          new ast.SymbolLiteral(memberName),
+          new ast.ListLiteral(arguments.positional),
+          new ast.MapLiteral(arguments.named.map((arg) {
+            return new ast.MapEntry(new ast.SymbolLiteral(arg.name), arg.value);
+          }).toList()),
+          candidateArgumentNames
+        ])));
+  }
+
+  ast.Expression buildThrowCompileTimeError(String message) {
+    // The spec does not mandate a specific behavior in face of a compile-time
+    // error.  We just throw a string.  The VM throws an uncatchable exception
+    // for this case.
+    // TOOD(asgerf): Should we add uncatchable exceptions to kernel?
+    return new ast.Throw(new ast.StringLiteral(message));
+  }
+
+  static final RegExp _errorMessagePattern = new RegExp(r'\{(\d+)\}');
+
+  /// Throws an exception that will be caught at the function level, to replace
+  /// the entire function with a throw.
+  emitCompileTimeError(ErrorCode error, [List arguments]) {
+    String message = error.message;
+    if (arguments != null) {
+      message = message.replaceAllMapped(_errorMessagePattern, (m) {
+        String numberString = m.group(1);
+        int index = int.parse(numberString);
+        return arguments[index];
+      });
+    }
+    throw new _CompilationError(message);
+  }
+
+  ast.Expression buildThrowAbstractClassInstantiationError(String name) {
+    return new ast.Throw(new ast.ConstructorInvocation(
+        loader.getCoreClassConstructorReference(
+            'AbstractClassInstantiationError'),
+        new ast.Arguments(<ast.Expression>[new ast.StringLiteral(name)])));
+  }
+
+  ast.Expression buildThrowFallThroughError() {
+    return new ast.Throw(new ast.ConstructorInvocation(
+        loader.getCoreClassConstructorReference('FallThroughError'),
+        new ast.Arguments.empty()));
+  }
+
+  emitInvalidConstant([ErrorCode error]) {
+    error ??= CompileTimeErrorCode.INVALID_CONSTANT;
+    return emitCompileTimeError(error);
+  }
+
+  internalError(String message) {
+    throw 'Internal error when compiling $location: $message';
+  }
+
+  unsupportedFeature(String feature) {
+    throw new _CompilationError('$feature is not supported');
+  }
+
+  ast.Expression buildAnnotation(Annotation annotation) {
+    Element element = annotation.element;
+    if (annotation.arguments == null) {
+      var target = resolveConcreteGet(element, null);
+      return target == null
+          ? new ast.InvalidExpression()
+          : new ast.StaticGet(target);
+    } else if (element is ConstructorElement && element.isConst) {
+      var target = resolveConstructor(element);
+      return target == null
+          ? new ast.InvalidExpression()
+          : new ast.ConstructorInvocation(
+              target, _expressionBuilder.buildArguments(annotation.arguments),
+              isConst: true);
+    } else {
+      return new ast.InvalidExpression();
+    }
+  }
+
+  void addTransformerFlag(int flags) {
+    // Overridden by MemberScope.
+  }
+
+  /// True if the body of the given method must return nothing.
+  bool hasVoidReturn(ExecutableElement element) {
+    return (strongMode && element.returnType.isVoid) ||
+        (element is PropertyAccessorElement && element.isSetter) ||
+        element.name == '[]=';
+  }
+
+  bool bodyHasVoidReturn(FunctionBody body) {
+    AstNode parent = body.parent;
+    return parent is MethodDeclaration && hasVoidReturn(parent.element) ||
+        parent is FunctionDeclaration && hasVoidReturn(parent.element);
+  }
+}
+
+/// A scope in which class type parameters are in scope, while not in scope
+/// of a specific member.
+class ClassScope extends ExpressionScope {
+  @override
+  bool get allowClassTypeParameters => true;
+
+  ClassScope(ReferenceLevelLoader loader, ast.Library library)
+      : super(loader, library);
+}
+
+/// Translates expressions, statements, and other constructs into [ast] nodes.
+///
+/// Naming convention:
+/// - `buildX` may not be given null as argument (it may crash the compiler).
+/// - `buildOptionalX` returns null or an empty list if given null
+/// - `buildMandatoryX` returns an invalid node if given null.
+class MemberScope extends ExpressionScope {
+  /// A reference to the member currently being upgraded to body level.
+  final ast.Member currentMember;
+
+  MemberScope(ReferenceLevelLoader loader, ast.Member currentMember)
+      : currentMember = currentMember,
+        super(loader, currentMember.enclosingLibrary) {
+    assert(currentMember != null);
+  }
+
+  ast.Class get currentClass => currentMember.enclosingClass;
+
+  bool get allowThis => _memberHasThis(currentMember);
+
+  @override
+  bool get allowClassTypeParameters {
+    return currentMember.isInstanceMember || currentMember is ast.Constructor;
+  }
+
+  /// Returns a string for debugging use, indicating the location of the member
+  /// being built.
+  String get location {
+    var library = currentMember.enclosingLibrary?.importUri ?? '<No Library>';
+    var className = currentMember.enclosingClass == null
+        ? null
+        : (currentMember.enclosingClass?.name ?? '<Anonymous Class>');
+    var member =
+        currentMember.name?.name ?? '<Anonymous ${currentMember.runtimeType}>';
+    return [library, className, member].join('::');
+  }
+
+  bool _memberHasThis(ast.Member member) {
+    return member is ast.Procedure && !member.isStatic ||
+        member is ast.Constructor;
+  }
+
+  void addTransformerFlag(int flags) {
+    currentMember.transformerFlags |= flags;
+  }
+}
+
+class LabelStack {
+  final List<String> labels; // Contains null for unlabeled targets.
+  final LabelStack next;
+  final List<ast.Statement> jumps = <ast.Statement>[];
+  bool isSwitchTarget = false;
+
+  LabelStack(String label, this.next) : labels = <String>[label];
+  LabelStack.unlabeled(this.next) : labels = <String>[null];
+  LabelStack.switchCase(String label, this.next)
+      : isSwitchTarget = true,
+        labels = <String>[label];
+  LabelStack.many(this.labels, this.next);
+}
+
+class StatementBuilder extends GeneralizingAstVisitor<ast.Statement> {
+  final ExpressionScope scope;
+  final LabelStack breakStack, continueStack;
+
+  StatementBuilder(this.scope, [this.breakStack, this.continueStack]);
+
+  ast.Statement build(Statement node) {
+    return node.accept(this);
+  }
+
+  ast.Statement buildOptional(Statement node) {
+    return node?.accept(this);
+  }
+
+  ast.Statement buildInScope(
+      Statement node, LabelStack breakNode, LabelStack continueNode) {
+    return new StatementBuilder(scope, breakNode, continueNode).build(node);
+  }
+
+  void buildBlockMember(Statement node, List<ast.Statement> output) {
+    if (node is LabeledStatement &&
+        node.statement is VariableDeclarationStatement) {
+      // If a variable is labeled, its scope is part of the enclosing block.
+      LabeledStatement labeled = node;
+      node = labeled.statement;
+    }
+    if (node is VariableDeclarationStatement) {
+      VariableDeclarationList list = node.variables;
+      ast.DartType type = scope.buildOptionalTypeAnnotation(list.type);
+      for (VariableDeclaration decl in list.variables) {
+        LocalElement local = decl.element as dynamic; // Cross cast.
+        output.add(scope.makeVariableDeclaration(local,
+            type: type,
+            initializer: scope.buildOptionalExpression(decl.initializer)));
+      }
+    } else {
+      output.add(build(node));
+    }
+  }
+
+  ast.Statement makeBreakTarget(ast.Statement node, LabelStack stackNode) {
+    if (stackNode.jumps.isEmpty) return node;
+    var labeled = new ast.LabeledStatement(node);
+    for (var jump in stackNode.jumps) {
+      (jump as ast.BreakStatement).target = labeled;
+    }
+    return labeled;
+  }
+
+  LabelStack findLabelTarget(String label, LabelStack stack) {
+    while (stack != null) {
+      if (stack.labels.contains(label)) return stack;
+      stack = stack.next;
+    }
+    return null;
+  }
+
+  ast.Statement visitAssertStatement(AssertStatement node) {
+    return new ast.AssertStatement(scope.buildExpression(node.condition),
+        scope.buildOptionalExpression(node.message));
+  }
+
+  ast.Statement visitBlock(Block node) {
+    List<ast.Statement> statements = <ast.Statement>[];
+    for (Statement statement in node.statements) {
+      buildBlockMember(statement, statements);
+    }
+    return new ast.Block(statements);
+  }
+
+  ast.Statement visitBreakStatement(BreakStatement node) {
+    var stackNode = findLabelTarget(node.label?.name, breakStack);
+    if (stackNode == null) {
+      return node.label == null
+          ? scope.emitCompileTimeError(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP)
+          : scope.emitCompileTimeError(
+              CompileTimeErrorCode.LABEL_UNDEFINED, [node.label.name]);
+    }
+    var result = new ast.BreakStatement(null);
+    stackNode.jumps.add(result);
+    return result;
+  }
+
+  ast.Statement visitContinueStatement(ContinueStatement node) {
+    var stackNode = findLabelTarget(node.label?.name, continueStack);
+    if (stackNode == null) {
+      return node.label == null
+          ? scope.emitCompileTimeError(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP)
+          : scope.emitCompileTimeError(
+              CompileTimeErrorCode.LABEL_UNDEFINED, [node.label.name]);
+    }
+    var result = stackNode.isSwitchTarget
+        ? new ast.ContinueSwitchStatement(null)
+        : new ast.BreakStatement(null);
+    stackNode.jumps.add(result);
+    return result;
+  }
+
+  void addLoopLabels(Statement loop, LabelStack continueNode) {
+    AstNode parent = loop.parent;
+    if (parent is LabeledStatement) {
+      for (var label in parent.labels) {
+        continueNode.labels.add(label.label.name);
+      }
+    }
+  }
+
+  ast.Statement visitDoStatement(DoStatement node) {
+    LabelStack breakNode = new LabelStack.unlabeled(breakStack);
+    LabelStack continueNode = new LabelStack.unlabeled(continueStack);
+    addLoopLabels(node, continueNode);
+    var body = buildInScope(node.body, breakNode, continueNode);
+    var loop = new ast.DoStatement(makeBreakTarget(body, continueNode),
+        scope.buildExpression(node.condition));
+    return makeBreakTarget(loop, breakNode);
+  }
+
+  ast.Statement visitWhileStatement(WhileStatement node) {
+    LabelStack breakNode = new LabelStack.unlabeled(breakStack);
+    LabelStack continueNode = new LabelStack.unlabeled(continueStack);
+    addLoopLabels(node, continueNode);
+    var body = buildInScope(node.body, breakNode, continueNode);
+    var loop = new ast.WhileStatement(scope.buildExpression(node.condition),
+        makeBreakTarget(body, continueNode));
+    return makeBreakTarget(loop, breakNode);
+  }
+
+  ast.Statement visitEmptyStatement(EmptyStatement node) {
+    return new ast.EmptyStatement();
+  }
+
+  ast.Statement visitExpressionStatement(ExpressionStatement node) {
+    return new ast.ExpressionStatement(scope.buildExpression(node.expression));
+  }
+
+  static String _getLabelName(Label label) {
+    return label.label.name;
+  }
+
+  ast.Statement visitLabeledStatement(LabeledStatement node) {
+    // Only set up breaks here.  Loops handle labeling on their own.
+    var breakNode = new LabelStack.many(
+        node.labels.map(_getLabelName).toList(), breakStack);
+    var body = buildInScope(node.statement, breakNode, continueStack);
+    return makeBreakTarget(body, breakNode);
+  }
+
+  static bool isBreakingExpression(ast.Expression node) {
+    return node is ast.Throw || node is ast.Rethrow;
+  }
+
+  static bool isBreakingStatement(ast.Statement node) {
+    return node is ast.BreakStatement ||
+        node is ast.ContinueSwitchStatement ||
+        node is ast.ReturnStatement ||
+        node is ast.ExpressionStatement &&
+            isBreakingExpression(node.expression);
+  }
+
+  ast.Statement visitSwitchStatement(SwitchStatement node) {
+    // Group all cases into case blocks.  Use parallel lists to collect the
+    // intermediate terms until we are ready to create the AST nodes.
+    LabelStack breakNode = new LabelStack.unlabeled(breakStack);
+    LabelStack continueNode = continueStack;
+    var cases = <ast.SwitchCase>[];
+    var bodies = <List<Statement>>[];
+    var labelToNode = <String, ast.SwitchCase>{};
+    ast.SwitchCase currentCase = null;
+    for (var member in node.members) {
+      if (currentCase != null && currentCase.isDefault) {
+        var error = member is SwitchCase
+            ? ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE
+            : ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES;
+        return scope.emitCompileTimeError(error);
+      }
+      if (currentCase == null) {
+        currentCase = new ast.SwitchCase(<ast.Expression>[], null);
+        cases.add(currentCase);
+      }
+      if (member is SwitchCase) {
+        var expression = scope.buildExpression(member.expression);
+        currentCase.expressions.add(expression..parent = currentCase);
+      } else {
+        currentCase.isDefault = true;
+      }
+      for (Label label in member.labels) {
+        continueNode =
+            new LabelStack.switchCase(label.label.name, continueNode);
+        labelToNode[label.label.name] = currentCase;
+      }
+      if (member.statements?.isNotEmpty ?? false) {
+        bodies.add(member.statements);
+        currentCase = null;
+      }
+    }
+    if (currentCase != null) {
+      // Close off a trailing block.
+      bodies.add(const <Statement>[]);
+      currentCase = null;
+    }
+    // Now that the label environment is set up, build the bodies.
+    var innerBuilder = new StatementBuilder(scope, breakNode, continueNode);
+    for (int i = 0; i < cases.length; ++i) {
+      var blockNodes = <ast.Statement>[];
+      for (var statement in bodies[i]) {
+        innerBuilder.buildBlockMember(statement, blockNodes);
+      }
+      if (blockNodes.isEmpty || !isBreakingStatement(blockNodes.last)) {
+        if (i < cases.length - 1) {
+          blockNodes.add(
+              new ast.ExpressionStatement(scope.buildThrowFallThroughError()));
+        } else {
+          var jump = new ast.BreakStatement(null);
+          blockNodes.add(jump);
+          breakNode.jumps.add(jump);
+        }
+      }
+      cases[i].body = new ast.Block(blockNodes)..parent = cases[i];
+    }
+    // Unwind the stack of case labels and bind their jumps to the case target.
+    while (continueNode != continueStack) {
+      for (var jump in continueNode.jumps) {
+        (jump as ast.ContinueSwitchStatement).target =
+            labelToNode[continueNode.labels.first];
+      }
+      continueNode = continueNode.next;
+    }
+    var expression = scope.buildExpression(node.expression);
+    var result = new ast.SwitchStatement(expression, cases);
+    return makeBreakTarget(result, breakNode);
+  }
+
+  ast.Statement visitForStatement(ForStatement node) {
+    List<ast.VariableDeclaration> variables = <ast.VariableDeclaration>[];
+    ast.Expression initialExpression;
+    if (node.variables != null) {
+      VariableDeclarationList list = node.variables;
+      var type = scope.buildOptionalTypeAnnotation(list.type);
+      for (var variable in list.variables) {
+        LocalElement local = variable.element as dynamic; // Cross cast.
+        variables.add(scope.makeVariableDeclaration(local,
+            initializer: scope.buildOptionalExpression(variable.initializer),
+            type: type));
+      }
+    } else if (node.initialization != null) {
+      initialExpression = scope.buildExpression(node.initialization);
+    }
+    var breakNode = new LabelStack.unlabeled(breakStack);
+    var continueNode = new LabelStack.unlabeled(continueStack);
+    addLoopLabels(node, continueNode);
+    var body = buildInScope(node.body, breakNode, continueNode);
+    var loop = new ast.ForStatement(
+        variables,
+        scope.buildOptionalExpression(node.condition),
+        node.updaters.map(scope.buildExpression).toList(),
+        makeBreakTarget(body, continueNode));
+    loop = makeBreakTarget(loop, breakNode);
+    if (initialExpression != null) {
+      return new ast.Block(<ast.Statement>[
+        new ast.ExpressionStatement(initialExpression),
+        loop
+      ]);
+    }
+    return loop;
+  }
+
+  ast.Statement visitForEachStatement(ForEachStatement node) {
+    ast.VariableDeclaration variable;
+    Accessor leftHand;
+    if (node.loopVariable != null) {
+      DeclaredIdentifier loopVariable = node.loopVariable;
+      variable = scope.makeVariableDeclaration(loopVariable.element,
+          type: scope.buildOptionalTypeAnnotation(loopVariable.type));
+    } else if (node.identifier != null) {
+      leftHand = scope.buildLeftHandValue(node.identifier);
+      // TODO: In strong mode, set variable type based on iterable type.
+      variable = new ast.VariableDeclaration(null, isFinal: true);
+    }
+    var breakNode = new LabelStack.unlabeled(breakStack);
+    var continueNode = new LabelStack.unlabeled(continueStack);
+    addLoopLabels(node, continueNode);
+    var body = buildInScope(node.body, breakNode, continueNode);
+    if (leftHand != null) {
+      // Desugar
+      //
+      //     for (x in e) BODY
+      //
+      // to
+      //
+      //     for (var tmp in e) {
+      //       x = tmp;
+      //       BODY
+      //     }
+      body = new ast.Block(<ast.Statement>[
+        new ast.ExpressionStatement(leftHand
+            .buildAssignment(new ast.VariableGet(variable), voidContext: true)),
+        body
+      ]);
+    }
+    var loop = new ast.ForInStatement(
+        variable,
+        scope.buildExpression(node.iterable),
+        makeBreakTarget(body, continueNode),
+        isAsync: node.awaitKeyword != null);
+    return makeBreakTarget(loop, breakNode);
+  }
+
+  ast.Statement visitIfStatement(IfStatement node) {
+    return new ast.IfStatement(scope.buildExpression(node.condition),
+        build(node.thenStatement), buildOptional(node.elseStatement));
+  }
+
+  ast.Statement visitReturnStatement(ReturnStatement node) {
+    return new ast.ReturnStatement(
+        scope.buildOptionalExpression(node.expression));
+  }
+
+  ast.Catch buildCatchClause(CatchClause node) {
+    var exceptionVariable = node.exceptionParameter == null
+        ? null
+        : scope.makeVariableDeclaration(node.exceptionParameter.staticElement);
+    var stackTraceVariable = node.stackTraceParameter == null
+        ? null
+        : scope.makeVariableDeclaration(node.stackTraceParameter.staticElement);
+    return new ast.Catch(exceptionVariable, build(node.body),
+        stackTrace: stackTraceVariable,
+        guard: scope.buildOptionalTypeAnnotation(node.exceptionType) ??
+            const ast.DynamicType());
+  }
+
+  ast.Statement visitTryStatement(TryStatement node) {
+    ast.Statement statement = build(node.body);
+    if (node.catchClauses.isNotEmpty) {
+      statement = new ast.TryCatch(
+          statement, node.catchClauses.map(buildCatchClause).toList());
+    }
+    if (node.finallyBlock != null) {
+      statement = new ast.TryFinally(statement, build(node.finallyBlock));
+    }
+    return statement;
+  }
+
+  ast.Statement visitVariableDeclarationStatement(
+      VariableDeclarationStatement node) {
+    // This is only reached when a variable is declared in non-block level,
+    // because visitBlock intercepts visits to its children.
+    // An example where we hit this case is:
+    //
+    //   if (foo) var x = 5, y = x + 1;
+    //
+    // We wrap these in a block:
+    //
+    //   if (foo) {
+    //     var x = 5;
+    //     var y = x + 1;
+    //   }
+    //
+    // Note that the use of a block here is required by the kernel language,
+    // even if there is only one variable declaration.
+    List<ast.Statement> statements = <ast.Statement>[];
+    buildBlockMember(node, statements);
+    return new ast.Block(statements);
+  }
+
+  ast.Statement visitYieldStatement(YieldStatement node) {
+    return new ast.YieldStatement(scope.buildExpression(node.expression),
+        isYieldStar: node.star != null);
+  }
+
+  ast.Statement visitFunctionDeclarationStatement(
+      FunctionDeclarationStatement node) {
+    var declaration = node.functionDeclaration;
+    var expression = declaration.functionExpression;
+    LocalElement element = declaration.element as dynamic; // Cross cast.
+    // TODO: Set a function type on the variable.
+    return new ast.FunctionDeclaration(
+        scope.makeVariableDeclaration(element),
+        scope.buildFunctionNode(expression.parameters, expression.body,
+            typeParameters:
+                scope.buildOptionalTypeParameterList(expression.typeParameters),
+            returnType: declaration.returnType));
+  }
+
+  @override
+  visitStatement(Statement node) {
+    return scope.internalError('Unhandled statement ${node.runtimeType}');
+  }
+}
+
+class ExpressionBuilder
+    extends GeneralizingAstVisitor /* <ast.Expression | Accessor> */ {
+  final ExpressionScope scope;
+  final ast.VariableDeclaration cascadeReceiver;
+  ExpressionBuilder(this.scope, [this.cascadeReceiver]);
+
+  ast.Expression build(Expression node) {
+    var result = node.accept(this);
+    if (result is Accessor) {
+      result = result.buildSimpleRead();
+    }
+    return result..fileOffset = _getOffset(node);
+  }
+
+  int _getOffset(AstNode node) {
+    if (node is MethodInvocation) {
+      return node.methodName.offset;
+    } else if (node is InstanceCreationExpression) {
+      return node.constructorName.offset;
+    } else if (node is BinaryExpression) {
+      return node.operator.offset;
+    } else if (node is PrefixedIdentifier) {
+      return node.identifier.offset;
+    } else if (node is AssignmentExpression) {
+      return _getOffset(node.leftHandSide);
+    }
+    return node.offset;
+  }
+
+  Accessor buildLeftHandValue(Expression node) {
+    var result = node.accept(this);
+    if (result is Accessor) {
+      return result;
+    } else {
+      return new ReadOnlyAccessor(result);
+    }
+  }
+
+  ast.Expression visitAsExpression(AsExpression node) {
+    return new ast.AsExpression(
+        build(node.expression), scope.buildTypeAnnotation(node.type));
+  }
+
+  ast.Expression visitAssignmentExpression(AssignmentExpression node) {
+    bool voidContext = isInVoidContext(node);
+    String operator = node.operator.value();
+    var leftHand = buildLeftHandValue(node.leftHandSide);
+    var rightHand = build(node.rightHandSide);
+    if (operator == '=') {
+      return leftHand.buildAssignment(rightHand, voidContext: voidContext);
+    } else if (operator == '??=') {
+      return leftHand.buildNullAwareAssignment(
+          rightHand, scope.buildType(node.staticType),
+          voidContext: voidContext);
+    } else {
+      // Cut off the trailing '='.
+      var name = new ast.Name(operator.substring(0, operator.length - 1));
+      return leftHand.buildCompoundAssignment(name, rightHand,
+          voidContext: voidContext,
+          interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
+    }
+  }
+
+  ast.Expression visitAwaitExpression(AwaitExpression node) {
+    return new ast.AwaitExpression(build(node.expression));
+  }
+
+  ast.Arguments buildSingleArgument(Expression node) {
+    return new ast.Arguments(<ast.Expression>[build(node)]);
+  }
+
+  ast.Expression visitBinaryExpression(BinaryExpression node) {
+    String operator = node.operator.value();
+    if (operator == '&&' || operator == '||') {
+      return new ast.LogicalExpression(
+          build(node.leftOperand), operator, build(node.rightOperand));
+    }
+    if (operator == '??') {
+      ast.Expression leftOperand = build(node.leftOperand);
+      if (leftOperand is ast.VariableGet) {
+        return new ast.ConditionalExpression(
+            buildIsNull(leftOperand),
+            build(node.rightOperand),
+            new ast.VariableGet(leftOperand.variable),
+            scope.getInferredType(node));
+      } else {
+        var variable = new ast.VariableDeclaration.forValue(leftOperand);
+        return new ast.Let(
+            variable,
+            new ast.ConditionalExpression(
+                buildIsNull(new ast.VariableGet(variable)),
+                build(node.rightOperand),
+                new ast.VariableGet(variable),
+                scope.getInferredType(node)));
+      }
+    }
+    bool isNegated = false;
+    if (operator == '!=') {
+      isNegated = true;
+      operator = '==';
+    }
+    ast.Expression expression;
+    if (node.leftOperand is SuperExpression) {
+      scope.addTransformerFlag(TransformerFlag.superCalls);
+      expression = new ast.SuperMethodInvocation(
+          new ast.Name(operator),
+          buildSingleArgument(node.rightOperand),
+          scope.resolveConcreteMethod(node.staticElement));
+    } else {
+      expression = new ast.MethodInvocation(
+          build(node.leftOperand),
+          new ast.Name(operator),
+          buildSingleArgument(node.rightOperand),
+          scope.resolveInterfaceMethod(node.staticElement));
+    }
+    return isNegated ? new ast.Not(expression) : expression;
+  }
+
+  ast.Expression visitBooleanLiteral(BooleanLiteral node) {
+    return new ast.BoolLiteral(node.value);
+  }
+
+  ast.Expression visitDoubleLiteral(DoubleLiteral node) {
+    return new ast.DoubleLiteral(node.value);
+  }
+
+  ast.Expression visitIntegerLiteral(IntegerLiteral node) {
+    return new ast.IntLiteral(node.value);
+  }
+
+  ast.Expression visitNullLiteral(NullLiteral node) {
+    return new ast.NullLiteral();
+  }
+
+  ast.Expression visitSimpleStringLiteral(SimpleStringLiteral node) {
+    return new ast.StringLiteral(node.value);
+  }
+
+  ast.Expression visitStringLiteral(StringLiteral node) {
+    return scope.buildStringLiteral(node);
+  }
+
+  static Object _getTokenValue(Token token) {
+    return token.value();
+  }
+
+  ast.Expression visitSymbolLiteral(SymbolLiteral node) {
+    String value = node.components.map(_getTokenValue).join('.');
+    return new ast.SymbolLiteral(value);
+  }
+
+  ast.Expression visitCascadeExpression(CascadeExpression node) {
+    var receiver = build(node.target);
+    // If receiver is a variable it would be tempting to reuse it, but it
+    // might be reassigned in one of the cascade sections.
+    var receiverVariable = new ast.VariableDeclaration.forValue(receiver,
+        type: scope.getInferredType(node.target));
+    var inner = new ExpressionBuilder(scope, receiverVariable);
+    ast.Expression result = new ast.VariableGet(receiverVariable);
+    for (var section in node.cascadeSections.reversed) {
+      var dummy = new ast.VariableDeclaration.forValue(inner.build(section));
+      result = new ast.Let(dummy, result);
+    }
+    return new ast.Let(receiverVariable, result);
+  }
+
+  ast.Expression makeCascadeReceiver() {
+    assert(cascadeReceiver != null);
+    return new ast.VariableGet(cascadeReceiver);
+  }
+
+  ast.Expression visitConditionalExpression(ConditionalExpression node) {
+    return new ast.ConditionalExpression(
+        build(node.condition),
+        build(node.thenExpression),
+        build(node.elseExpression),
+        scope.getInferredType(node));
+  }
+
+  ast.Expression visitFunctionExpression(FunctionExpression node) {
+    return new ast.FunctionExpression(scope.buildFunctionNode(
+        node.parameters, node.body,
+        typeParameters:
+            scope.buildOptionalTypeParameterList(node.typeParameters),
+        inferredReturnType: scope.getInferredReturnType(node)));
+  }
+
+  ast.Arguments buildArguments(ArgumentList valueArguments,
+      {TypeArgumentList explicitTypeArguments,
+      List<ast.DartType> inferTypeArguments()}) {
+    var positional = <ast.Expression>[];
+    var named = <ast.NamedExpression>[];
+    for (var argument in valueArguments.arguments) {
+      if (argument is NamedExpression) {
+        named.add(new ast.NamedExpression(
+            argument.name.label.name, build(argument.expression)));
+      } else if (named.isNotEmpty) {
+        return scope.emitCompileTimeError(
+            ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT);
+      } else {
+        positional.add(build(argument));
+      }
+    }
+    List<ast.DartType> typeArguments;
+    if (explicitTypeArguments != null) {
+      typeArguments = scope.buildTypeArgumentList(explicitTypeArguments);
+    } else if (inferTypeArguments != null) {
+      typeArguments = inferTypeArguments();
+    }
+    return new ast.Arguments(positional, named: named, types: typeArguments);
+  }
+
+  ast.Arguments buildArgumentsForInvocation(InvocationExpression node) {
+    return buildArguments(node.argumentList,
+        explicitTypeArguments: node.typeArguments,
+        inferTypeArguments: () =>
+            scope.getInferredInvocationTypeArguments(node));
+  }
+
+  static final ast.Name callName = new ast.Name('call');
+
+  ast.Expression visitFunctionExpressionInvocation(
+      FunctionExpressionInvocation node) {
+    return new ast.MethodInvocation(
+        build(node.function),
+        callName,
+        buildArgumentsForInvocation(node),
+        scope.resolveInterfaceFunctionCallOnType(node.function.staticType));
+  }
+
+  visitPrefixedIdentifier(PrefixedIdentifier node) {
+    switch (ElementKind.of(node.prefix.staticElement)) {
+      case ElementKind.CLASS:
+      case ElementKind.LIBRARY:
+      case ElementKind.PREFIX:
+      case ElementKind.IMPORT:
+        if (node.identifier.staticElement != null) {
+          // Should be resolved to a static access.
+          // Do not invoke 'build', because the identifier should be seen as a
+          // left-hand value or an expression depending on the context.
+          return visitSimpleIdentifier(node.identifier);
+        }
+        // Unresolved access on a class or library.
+        return scope.unresolvedAccess(node.identifier.name);
+
+      case ElementKind.DYNAMIC:
+      case ElementKind.FUNCTION_TYPE_ALIAS:
+      case ElementKind.TYPE_PARAMETER:
+      // TODO: Check with the spec to see exactly when a type literal can be
+      // used in a property access without surrounding parentheses.
+      // For now, just fall through to the property access case.
+
+      case ElementKind.FIELD:
+      case ElementKind.TOP_LEVEL_VARIABLE:
+      case ElementKind.FUNCTION:
+      case ElementKind.METHOD:
+      case ElementKind.GETTER:
+      case ElementKind.SETTER:
+      case ElementKind.LOCAL_VARIABLE:
+      case ElementKind.PARAMETER:
+      case ElementKind.ERROR:
+        Element element = node.identifier.staticElement;
+        Element auxiliary = node.identifier.auxiliaryElements?.staticElement;
+        return PropertyAccessor.make(
+            build(node.prefix),
+            scope.buildName(node.identifier),
+            scope.resolveInterfaceGet(element, auxiliary),
+            scope.resolveInterfaceSet(element, auxiliary));
+
+      case ElementKind.UNIVERSE:
+      case ElementKind.NAME:
+      case ElementKind.CONSTRUCTOR:
+      case ElementKind.EXPORT:
+      case ElementKind.LABEL:
+      default:
+        return scope.internalError(
+            'Unexpected element kind: ${node.prefix.staticElement}');
+    }
+  }
+
+  bool isStatic(Element element) {
+    if (element is ClassMemberElement) {
+      return element.isStatic || element.enclosingElement == null;
+    }
+    if (element is PropertyAccessorElement) {
+      return element.isStatic || element.enclosingElement == null;
+    }
+    if (element is FunctionElement) {
+      return element.isStatic;
+    }
+    return false;
+  }
+
+  visitSimpleIdentifier(SimpleIdentifier node) {
+    Element element = node.staticElement;
+    switch (ElementKind.of(element)) {
+      case ElementKind.CLASS:
+      case ElementKind.DYNAMIC:
+      case ElementKind.FUNCTION_TYPE_ALIAS:
+      case ElementKind.TYPE_PARAMETER:
+        return new ast.TypeLiteral(scope.buildTypeAnnotation(node));
+
+      case ElementKind.ERROR: // This covers the case where nothing was found.
+        if (!scope.allowThis) {
+          return scope.unresolvedAccess(node.name);
+        }
+        return PropertyAccessor.make(
+            scope.buildThis(), scope.buildName(node), null, null);
+
+      case ElementKind.FIELD:
+      case ElementKind.TOP_LEVEL_VARIABLE:
+      case ElementKind.GETTER:
+      case ElementKind.SETTER:
+      case ElementKind.METHOD:
+        Element auxiliary = node.auxiliaryElements?.staticElement;
+        if (isStatic(element)) {
+          return scope.staticAccess(node.name, element, auxiliary);
+        }
+        if (!scope.allowThis) {
+          return scope.unresolvedAccess(node.name);
+        }
+        return PropertyAccessor.make(
+            scope.buildThis(),
+            scope.buildName(node),
+            scope.resolveInterfaceGet(element, auxiliary),
+            scope.resolveInterfaceSet(element, auxiliary));
+
+      case ElementKind.FUNCTION:
+        FunctionElement function = element;
+        if (isTopLevelFunction(function)) {
+          return scope.staticAccess(node.name, function);
+        }
+        return new VariableAccessor(scope.getVariableReference(function));
+
+      case ElementKind.LOCAL_VARIABLE:
+      case ElementKind.PARAMETER:
+        VariableElement variable = element;
+        var type = identical(node.staticType, variable.type)
+            ? null
+            : scope.buildType(node.staticType);
+        return new VariableAccessor(scope.getVariableReference(element), type);
+
+      case ElementKind.IMPORT:
+      case ElementKind.LIBRARY:
+      case ElementKind.PREFIX:
+        return scope.emitCompileTimeError(
+            CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+            [node.name]);
+
+      case ElementKind.COMPILATION_UNIT:
+      case ElementKind.CONSTRUCTOR:
+      case ElementKind.EXPORT:
+      case ElementKind.LABEL:
+      case ElementKind.UNIVERSE:
+      case ElementKind.NAME:
+      default:
+        return scope.internalError('Unexpected element kind: $element');
+    }
+  }
+
+  visitIndexExpression(IndexExpression node) {
+    Element element = node.staticElement;
+    Element auxiliary = node.auxiliaryElements?.staticElement;
+    if (node.isCascaded) {
+      return IndexAccessor.make(
+          makeCascadeReceiver(),
+          build(node.index),
+          scope.resolveInterfaceIndexGet(element, auxiliary),
+          scope.resolveInterfaceIndexSet(element, auxiliary));
+    } else if (node.target is SuperExpression) {
+      scope.addTransformerFlag(TransformerFlag.superCalls);
+      return new SuperIndexAccessor(
+          build(node.index),
+          scope.resolveConcreteIndexGet(element, auxiliary),
+          scope.resolveConcreteIndexSet(element, auxiliary));
+    } else {
+      return IndexAccessor.make(
+          build(node.target),
+          build(node.index),
+          scope.resolveInterfaceIndexGet(element, auxiliary),
+          scope.resolveInterfaceIndexSet(element, auxiliary));
+    }
+  }
+
+  /// Follows any number of redirecting factories, returning the effective
+  /// target or `null` if a cycle is found.
+  ///
+  /// The returned element is a [Member] if the type arguments to the effective
+  /// target are different from the original arguments.
+  ConstructorElement getEffectiveFactoryTarget(ConstructorElement element) {
+    ConstructorElement anchor = null;
+    int n = 1;
+    while (element.isFactory && element.redirectedConstructor != null) {
+      element = element.redirectedConstructor;
+      var base = ReferenceScope.getBaseElement(element);
+      if (base == anchor) return null; // Cyclic redirection.
+      if (n & ++n == 0) {
+        anchor = base;
+      }
+    }
+    return element;
+  }
+
+  ast.Expression visitInstanceCreationExpression(
+      InstanceCreationExpression node) {
+    ConstructorElement element = node.staticElement;
+    ClassElement classElement = element?.enclosingElement;
+    List<ast.DartType> inferTypeArguments() {
+      var inferredType = scope.getInferredType(node);
+      if (inferredType is ast.InterfaceType) {
+        return inferredType.typeArguments.toList();
+      }
+      int numberOfTypeArguments =
+          classElement == null ? 0 : classElement.typeParameters.length;
+      return new List<ast.DartType>.filled(
+          numberOfTypeArguments, const ast.DynamicType(),
+          growable: true);
+    }
+
+    var arguments = buildArguments(node.argumentList,
+        explicitTypeArguments: node.constructorName.type.typeArguments,
+        inferTypeArguments: inferTypeArguments);
+    ast.Expression noSuchMethodError() {
+      return node.isConst
+          ? scope.emitInvalidConstant()
+          : scope.buildThrowNoSuchMethodError(
+              new ast.NullLiteral(), '${node.constructorName}', arguments,
+              candidateTarget: element);
+    }
+
+    if (element == null) {
+      return noSuchMethodError();
+    }
+    assert(classElement != null);
+    var redirect = getEffectiveFactoryTarget(element);
+    if (redirect == null) {
+      return scope.buildThrowCompileTimeError(
+          CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT.message);
+    }
+    if (redirect != element) {
+      ast.InterfaceType returnType = scope.buildType(redirect.returnType);
+      arguments.types
+        ..clear()
+        ..addAll(returnType.typeArguments);
+      element = redirect;
+      classElement = element.enclosingElement;
+    }
+    element = ReferenceScope.getBaseElement(element);
+    if (node.isConst && !element.isConst) {
+      return scope
+          .emitInvalidConstant(CompileTimeErrorCode.CONST_WITH_NON_CONST);
+    }
+    if (classElement.isEnum) {
+      return scope.emitCompileTimeError(CompileTimeErrorCode.INSTANTIATE_ENUM);
+    }
+    if (element.isFactory) {
+      ast.Member target = scope.resolveConcreteMethod(element);
+      if (target is ast.Procedure &&
+          scope.areArgumentsCompatible(element, arguments)) {
+        return new ast.StaticInvocation(target, arguments,
+            isConst: node.isConst);
+      } else {
+        return noSuchMethodError();
+      }
+    }
+    if (classElement.isAbstract) {
+      return node.isConst
+          ? scope.emitInvalidConstant()
+          : scope.buildThrowAbstractClassInstantiationError(classElement.name);
+    }
+    ast.Constructor constructor = scope.resolveConstructor(element);
+    if (constructor != null &&
+        scope.areArgumentsCompatible(element, arguments)) {
+      return new ast.ConstructorInvocation(constructor, arguments,
+          isConst: node.isConst);
+    } else {
+      return noSuchMethodError();
+    }
+  }
+
+  ast.Expression visitIsExpression(IsExpression node) {
+    if (node.notOperator != null) {
+      return new ast.Not(new ast.IsExpression(
+          build(node.expression), scope.buildTypeAnnotation(node.type)));
+    } else {
+      return new ast.IsExpression(
+          build(node.expression), scope.buildTypeAnnotation(node.type));
+    }
+  }
+
+  /// Emit a method invocation, either as a direct call `o.f(x)` or decomposed
+  /// into a getter and function invocation `o.f.call(x)`.
+  ast.Expression buildDecomposableMethodInvocation(ast.Expression receiver,
+      ast.Name name, ast.Arguments arguments, Element targetElement) {
+    // Try to emit a typed call to an interface method.
+    ast.Procedure targetMethod = scope.resolveInterfaceMethod(targetElement);
+    if (targetMethod != null) {
+      return new ast.MethodInvocation(receiver, name, arguments, targetMethod);
+    }
+    // Try to emit a typed call to getter or field and call the returned
+    // function.
+    ast.Member targetGetter = scope.resolveInterfaceGet(targetElement, null);
+    if (targetGetter != null) {
+      return new ast.MethodInvocation(
+          new ast.PropertyGet(receiver, name, targetGetter),
+          callName,
+          arguments,
+          scope.resolveInterfaceFunctionCall(targetElement));
+    }
+    // Emit a dynamic call.
+    return new ast.MethodInvocation(receiver, name, arguments);
+  }
+
+  ast.Expression visitMethodInvocation(MethodInvocation node) {
+    Element element = node.methodName.staticElement;
+    if (element != null && element == element.library?.loadLibraryFunction) {
+      return scope.unsupportedFeature('Deferred loading');
+    }
+    var target = node.target;
+    if (node.isCascaded) {
+      return buildDecomposableMethodInvocation(
+          makeCascadeReceiver(),
+          scope.buildName(node.methodName),
+          buildArgumentsForInvocation(node),
+          element);
+    } else if (target is SuperExpression) {
+      scope.addTransformerFlag(TransformerFlag.superCalls);
+      return new ast.SuperMethodInvocation(
+          scope.buildName(node.methodName),
+          buildArgumentsForInvocation(node),
+          scope.resolveConcreteMethod(element));
+    } else if (isLocal(element)) {
+      return new ast.MethodInvocation(
+          new ast.VariableGet(scope.getVariableReference(element)),
+          callName,
+          buildArgumentsForInvocation(node),
+          scope.resolveInterfaceFunctionCall(element));
+    } else if (isStaticMethod(element)) {
+      var method = scope.resolveConcreteMethod(element);
+      var arguments = buildArgumentsForInvocation(node);
+      if (method == null || !scope.areArgumentsCompatible(element, arguments)) {
+        return scope.buildThrowNoSuchMethodError(
+            new ast.NullLiteral(), node.methodName.name, arguments,
+            candidateTarget: element);
+      }
+      return new ast.StaticInvocation(method, arguments);
+    } else if (isStaticVariableOrGetter(element)) {
+      var method = scope.resolveConcreteGet(element, null);
+      if (method == null) {
+        return scope.buildThrowNoSuchMethodError(
+            new ast.NullLiteral(), node.methodName.name, new ast.Arguments([]),
+            candidateTarget: element);
+      }
+      return new ast.MethodInvocation(
+          new ast.StaticGet(method),
+          callName,
+          buildArgumentsForInvocation(node),
+          scope.resolveInterfaceFunctionCall(element));
+    } else if (target == null && !scope.allowThis ||
+        target is Identifier && target.staticElement is ClassElement ||
+        target is Identifier && target.staticElement is PrefixElement) {
+      return scope.buildThrowNoSuchMethodError(new ast.NullLiteral(),
+          node.methodName.name, buildArgumentsForInvocation(node),
+          candidateTarget: element);
+    } else if (target == null) {
+      return buildDecomposableMethodInvocation(
+          scope.buildThis(),
+          scope.buildName(node.methodName),
+          buildArgumentsForInvocation(node),
+          element);
+    } else if (node.operator.value() == '?.') {
+      var receiver = makeOrReuseVariable(build(target));
+      return makeLet(
+          receiver,
+          new ast.ConditionalExpression(
+              buildIsNull(new ast.VariableGet(receiver)),
+              new ast.NullLiteral(),
+              buildDecomposableMethodInvocation(
+                  new ast.VariableGet(receiver),
+                  scope.buildName(node.methodName),
+                  buildArgumentsForInvocation(node),
+                  element),
+              scope.buildType(node.staticType)));
+    } else {
+      return buildDecomposableMethodInvocation(
+          build(node.target),
+          scope.buildName(node.methodName),
+          buildArgumentsForInvocation(node),
+          element);
+    }
+  }
+
+  ast.Expression visitNamedExpression(NamedExpression node) {
+    return scope.internalError('Unexpected named expression');
+  }
+
+  ast.Expression visitParenthesizedExpression(ParenthesizedExpression node) {
+    return build(node.expression);
+  }
+
+  bool isInVoidContext(Expression node) {
+    AstNode parent = node.parent;
+    return parent is ForStatement &&
+            (parent.updaters.contains(node) || parent.initialization == node) ||
+        parent is ExpressionStatement ||
+        parent is ExpressionFunctionBody && scope.bodyHasVoidReturn(parent);
+  }
+
+  ast.Expression visitPostfixExpression(PostfixExpression node) {
+    String operator = node.operator.value();
+    switch (operator) {
+      case '++':
+      case '--':
+        var leftHand = buildLeftHandValue(node.operand);
+        var binaryOperator = new ast.Name(operator[0]);
+        return leftHand.buildPostfixIncrement(binaryOperator,
+            voidContext: isInVoidContext(node),
+            interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
+
+      default:
+        return scope.internalError('Invalid postfix operator $operator');
+    }
+  }
+
+  ast.Expression visitPrefixExpression(PrefixExpression node) {
+    String operator = node.operator.value();
+    switch (operator) {
+      case '-':
+      case '~':
+        var name = new ast.Name(operator == '-' ? 'unary-' : '~');
+        if (node.operand is SuperExpression) {
+          scope.addTransformerFlag(TransformerFlag.superCalls);
+          return new ast.SuperMethodInvocation(name, new ast.Arguments.empty(),
+              scope.resolveConcreteMethod(node.staticElement));
+        }
+        return new ast.MethodInvocation(
+            build(node.operand),
+            name,
+            new ast.Arguments.empty(),
+            scope.resolveInterfaceMethod(node.staticElement));
+
+      case '!':
+        return new ast.Not(build(node.operand));
+
+      case '++':
+      case '--':
+        var leftHand = buildLeftHandValue(node.operand);
+        var binaryOperator = new ast.Name(operator[0]);
+        return leftHand.buildPrefixIncrement(binaryOperator,
+            interfaceTarget: scope.resolveInterfaceMethod(node.staticElement));
+
+      default:
+        return scope.internalError('Invalid prefix operator $operator');
+    }
+  }
+
+  visitPropertyAccess(PropertyAccess node) {
+    Element element = node.propertyName.staticElement;
+    Element auxiliary = node.propertyName.auxiliaryElements?.staticElement;
+    var getter = scope.resolveInterfaceGet(element, auxiliary);
+    var setter = scope.resolveInterfaceSet(element, auxiliary);
+    Expression target = node.target;
+    if (node.isCascaded) {
+      return PropertyAccessor.make(makeCascadeReceiver(),
+          scope.buildName(node.propertyName), getter, setter);
+    } else if (node.target is SuperExpression) {
+      scope.addTransformerFlag(TransformerFlag.superCalls);
+      return new SuperPropertyAccessor(
+          scope.buildName(node.propertyName),
+          scope.resolveConcreteGet(element, auxiliary),
+          scope.resolveConcreteSet(element, auxiliary));
+    } else if (target is Identifier && target.staticElement is ClassElement) {
+      // Note that this case also covers null-aware static access on a class,
+      // which is equivalent to a regular static access.
+      return scope.staticAccess(node.propertyName.name, element, auxiliary);
+    } else if (node.operator.value() == '?.') {
+      return new NullAwarePropertyAccessor(
+          build(target),
+          scope.buildName(node.propertyName),
+          getter,
+          setter,
+          scope.buildType(node.staticType));
+    } else {
+      return PropertyAccessor.make(
+          build(target), scope.buildName(node.propertyName), getter, setter);
+    }
+  }
+
+  ast.Expression visitRethrowExpression(RethrowExpression node) {
+    return new ast.Rethrow();
+  }
+
+  ast.Expression visitSuperExpression(SuperExpression node) {
+    return scope
+        .emitCompileTimeError(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT);
+  }
+
+  ast.Expression visitThisExpression(ThisExpression node) {
+    return scope.buildThis();
+  }
+
+  ast.Expression visitThrowExpression(ThrowExpression node) {
+    return new ast.Throw(build(node.expression));
+  }
+
+  ast.Expression visitListLiteral(ListLiteral node) {
+    ast.DartType type = node.typeArguments?.arguments?.isNotEmpty ?? false
+        ? scope.buildTypeAnnotation(node.typeArguments.arguments[0])
+        : scope.getInferredTypeArgument(node, 0);
+    return new ast.ListLiteral(node.elements.map(build).toList(),
+        typeArgument: type, isConst: node.constKeyword != null);
+  }
+
+  ast.Expression visitMapLiteral(MapLiteral node) {
+    ast.DartType key, value;
+    if (node.typeArguments != null && node.typeArguments.arguments.length > 1) {
+      key = scope.buildTypeAnnotation(node.typeArguments.arguments[0]);
+      value = scope.buildTypeAnnotation(node.typeArguments.arguments[1]);
+    } else {
+      key = scope.getInferredTypeArgument(node, 0);
+      value = scope.getInferredTypeArgument(node, 1);
+    }
+    return new ast.MapLiteral(node.entries.map(buildMapEntry).toList(),
+        keyType: key, valueType: value, isConst: node.constKeyword != null);
+  }
+
+  ast.MapEntry buildMapEntry(MapLiteralEntry node) {
+    return new ast.MapEntry(build(node.key), build(node.value));
+  }
+
+  ast.Expression visitExpression(Expression node) {
+    return scope.internalError('Unhandled expression ${node.runtimeType}');
+  }
+}
+
+class StringLiteralPartBuilder extends GeneralizingAstVisitor<Null> {
+  final ExpressionScope scope;
+  final List<ast.Expression> output;
+  StringLiteralPartBuilder(this.scope, this.output);
+
+  void build(Expression node) {
+    node.accept(this);
+  }
+
+  void buildInterpolationElement(InterpolationElement node) {
+    node.accept(this);
+  }
+
+  visitSimpleStringLiteral(SimpleStringLiteral node) {
+    output.add(new ast.StringLiteral(node.value));
+  }
+
+  visitAdjacentStrings(AdjacentStrings node) {
+    node.strings.forEach(build);
+  }
+
+  visitStringInterpolation(StringInterpolation node) {
+    node.elements.forEach(buildInterpolationElement);
+  }
+
+  visitInterpolationString(InterpolationString node) {
+    output.add(new ast.StringLiteral(node.value));
+  }
+
+  visitInterpolationExpression(InterpolationExpression node) {
+    output.add(scope.buildExpression(node.expression));
+  }
+}
+
+class TypeAnnotationBuilder extends GeneralizingAstVisitor<ast.DartType> {
+  final TypeScope scope;
+
+  TypeAnnotationBuilder(this.scope);
+
+  ast.DartType build(AstNode node) {
+    return node.accept(this);
+  }
+
+  List<ast.DartType> buildList(Iterable<AstNode> node) {
+    return node.map(build).toList();
+  }
+
+  /// Replace unbound type variables in [type] with 'dynamic' and convert
+  /// to an [ast.DartType].
+  ast.DartType buildClosedTypeFromDartType(DartType type) {
+    return convertType(type, <TypeParameterElement>[]);
+  }
+
+  /// Convert to an [ast.DartType] and keep type variables.
+  ast.DartType buildFromDartType(DartType type) {
+    return convertType(type, null);
+  }
+
+  /// Converts [type] to an [ast.DartType], while replacing unbound type
+  /// variables with 'dynamic'.
+  ///
+  /// If [boundVariables] is null, no type variables are replaced, otherwise all
+  /// type variables except those in [boundVariables] are replaced.  In other
+  /// words, it represents the bound variables, or "all variables" if omitted.
+  ast.DartType convertType(
+      DartType type, List<TypeParameterElement> boundVariables) {
+    if (type is TypeParameterType) {
+      if (boundVariables == null || boundVariables.contains(type)) {
+        var typeParameter = scope.getTypeParameterReference(type.element);
+        if (!scope.allowClassTypeParameters &&
+            typeParameter.parent is ast.Class) {
+          return const ast.InvalidType();
+        }
+        return new ast.TypeParameterType(typeParameter);
+      } else {
+        return const ast.DynamicType();
+      }
+    } else if (type is InterfaceType) {
+      var classNode = scope.getClassReference(type.element);
+      if (type.typeArguments.length == 0) {
+        return new ast.InterfaceType(classNode);
+      }
+      if (type.typeArguments.length != classNode.typeParameters.length) {
+        log.warning('Type parameter arity error in $type');
+        return const ast.InvalidType();
+      }
+      return new ast.InterfaceType(
+          classNode, convertTypeList(type.typeArguments, boundVariables));
+    } else if (type is FunctionType) {
+      // TODO: Avoid infinite recursion in case of illegal circular typedef.
+      boundVariables?.addAll(type.typeParameters);
+      var positionals =
+          concatenate(type.normalParameterTypes, type.optionalParameterTypes);
+      var result = new ast.FunctionType(
+          convertTypeList(positionals, boundVariables),
+          convertType(type.returnType, boundVariables),
+          typeParameters:
+              convertTypeParameterList(type.typeFormals, boundVariables),
+          namedParameters:
+              convertTypeMap(type.namedParameterTypes, boundVariables),
+          requiredParameterCount: type.normalParameterTypes.length);
+      boundVariables?.removeRange(
+          boundVariables.length - type.typeParameters.length,
+          boundVariables.length);
+      return result;
+    } else if (type.isUndefined) {
+      log.warning('Unresolved type found in ${scope.location}');
+      return const ast.InvalidType();
+    } else if (type.isVoid) {
+      return const ast.VoidType();
+    } else if (type.isDynamic) {
+      return const ast.DynamicType();
+    } else {
+      log.severe('Unexpected DartType: $type');
+      return const ast.InvalidType();
+    }
+  }
+
+  static Iterable/*<E>*/ concatenate/*<E>*/(
+          Iterable/*<E>*/ x, Iterable/*<E>*/ y) =>
+      <Iterable<dynamic/*=E*/ >>[x, y].expand((z) => z);
+
+  ast.TypeParameter convertTypeParameter(TypeParameterElement typeParameter,
+      List<TypeParameterElement> boundVariables) {
+    return scope.makeTypeParameter(typeParameter,
+        bound: typeParameter.bound == null
+            ? scope.defaultTypeParameterBound
+            : convertType(typeParameter.bound, boundVariables));
+  }
+
+  List<ast.TypeParameter> convertTypeParameterList(
+      Iterable<TypeParameterElement> typeParameters,
+      List<TypeParameterElement> boundVariables) {
+    if (typeParameters.isEmpty) return const <ast.TypeParameter>[];
+    return typeParameters
+        .map((tp) => convertTypeParameter(tp, boundVariables))
+        .toList();
+  }
+
+  List<ast.DartType> convertTypeList(
+      Iterable<DartType> types, List<TypeParameterElement> boundVariables) {
+    if (types.isEmpty) return const <ast.DartType>[];
+    return types.map((t) => convertType(t, boundVariables)).toList();
+  }
+
+  List<ast.NamedType> convertTypeMap(
+      Map<String, DartType> types, List<TypeParameterElement> boundVariables) {
+    if (types.isEmpty) return const <ast.NamedType>[];
+    List<ast.NamedType> result = <ast.NamedType>[];
+    types.forEach((name, type) {
+      result.add(new ast.NamedType(name, convertType(type, boundVariables)));
+    });
+    sortAndRemoveDuplicates(result);
+    return result;
+  }
+
+  ast.DartType visitSimpleIdentifier(SimpleIdentifier node) {
+    Element element = node.staticElement;
+    switch (ElementKind.of(element)) {
+      case ElementKind.CLASS:
+        return new ast.InterfaceType(scope.getClassReference(element));
+
+      case ElementKind.DYNAMIC:
+        return const ast.DynamicType();
+
+      case ElementKind.FUNCTION_TYPE_ALIAS:
+        FunctionTypeAliasElement functionType = element;
+        return buildClosedTypeFromDartType(functionType.type);
+
+      case ElementKind.TYPE_PARAMETER:
+        var typeParameter = scope.getTypeParameterReference(element);
+        if (!scope.allowClassTypeParameters &&
+            typeParameter.parent is ast.Class) {
+          return const ast.InvalidType();
+        }
+        return new ast.TypeParameterType(typeParameter);
+
+      case ElementKind.COMPILATION_UNIT:
+      case ElementKind.CONSTRUCTOR:
+      case ElementKind.EXPORT:
+      case ElementKind.IMPORT:
+      case ElementKind.LABEL:
+      case ElementKind.LIBRARY:
+      case ElementKind.PREFIX:
+      case ElementKind.UNIVERSE:
+      case ElementKind.ERROR: // This covers the case where nothing was found.
+      case ElementKind.FIELD:
+      case ElementKind.TOP_LEVEL_VARIABLE:
+      case ElementKind.GETTER:
+      case ElementKind.SETTER:
+      case ElementKind.METHOD:
+      case ElementKind.LOCAL_VARIABLE:
+      case ElementKind.PARAMETER:
+      case ElementKind.FUNCTION:
+      case ElementKind.NAME:
+      default:
+        log.severe('Invalid type annotation: $element');
+        return const ast.InvalidType();
+    }
+  }
+
+  visitPrefixedIdentifier(PrefixedIdentifier node) {
+    return build(node.identifier);
+  }
+
+  visitTypeName(TypeName node) {
+    return buildFromDartType(node.type);
+  }
+
+  visitNode(AstNode node) {
+    log.severe('Unexpected type annotation: $node');
+    return new ast.InvalidType();
+  }
+}
+
+class InitializerBuilder extends GeneralizingAstVisitor<ast.Initializer> {
+  final MemberScope scope;
+
+  InitializerBuilder(this.scope);
+
+  ast.Initializer build(ConstructorInitializer node) {
+    return node.accept(this);
+  }
+
+  visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    var target = scope.resolveField(node.fieldName.staticElement);
+    if (target == null) {
+      return new ast.InvalidInitializer();
+    }
+    return new ast.FieldInitializer(
+        target, scope.buildExpression(node.expression));
+  }
+
+  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    var target = scope.resolveConstructor(node.staticElement);
+    if (target == null) {
+      return new ast.InvalidInitializer();
+    }
+    scope.addTransformerFlag(TransformerFlag.superCalls);
+    return new ast.SuperInitializer(
+        target, scope._expressionBuilder.buildArguments(node.argumentList));
+  }
+
+  visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    var target = scope.resolveConstructor(node.staticElement);
+    if (target == null) {
+      return new ast.InvalidInitializer();
+    }
+    return new ast.RedirectingInitializer(
+        target, scope._expressionBuilder.buildArguments(node.argumentList));
+  }
+
+  visitNode(AstNode node) {
+    log.severe('Unexpected constructor initializer: ${node.runtimeType}');
+    return new ast.InvalidInitializer();
+  }
+}
+
+/// Brings a class from hierarchy level to body level.
+//
+// TODO(asgerf): Error recovery during class construction is currently handled
+//   locally, but this can in theory break global invariants in the kernel IR.
+//   To safely compile code with compile-time errors, we may need a recovery
+//   pass to enforce all kernel invariants before it is given to the backend.
+class ClassBodyBuilder extends GeneralizingAstVisitor<Null> {
+  final ClassScope scope;
+  final ExpressionScope annotationScope;
+  final ast.Class currentClass;
+  final ClassElement element;
+  ast.Library get currentLibrary => currentClass.enclosingLibrary;
+
+  ClassBodyBuilder(
+      ReferenceLevelLoader loader, ast.Class currentClass, this.element)
+      : this.currentClass = currentClass,
+        scope = new ClassScope(loader, currentClass.enclosingLibrary),
+        annotationScope =
+            new ExpressionScope(loader, currentClass.enclosingLibrary);
+
+  void build(CompilationUnitMember node) {
+    if (node == null) {
+      buildBrokenClass();
+      return;
+    }
+    node.accept(this);
+  }
+
+  /// Builds an empty class for broken classes that have no AST.
+  ///
+  /// This should only be used to recover from a compile-time error.
+  void buildBrokenClass() {
+    currentClass.name = element.name;
+    currentClass.supertype = scope.getRootClassReference().asRawSupertype;
+    currentClass.constructors.add(
+        new ast.Constructor(new ast.FunctionNode(new ast.InvalidStatement())));
+  }
+
+  void addAnnotations(List<Annotation> annotations) {
+    // Class type parameters are not in scope in the annotation list.
+    for (var annotation in annotations) {
+      currentClass.addAnnotation(annotationScope.buildAnnotation(annotation));
+    }
+  }
+
+  void _buildMemberBody(ast.Member member, Element element, AstNode node) {
+    new MemberBodyBuilder(scope.loader, member, element).build(node);
+  }
+
+  /// True if the given class member should not be emitted, and does not
+  /// correspond to any Kernel member.
+  ///
+  /// This is true for redirecting factories with a resolved target. These are
+  /// always bypassed at the call site.
+  bool _isIgnoredMember(ClassMember node) {
+    return node is ConstructorDeclaration &&
+        node.factoryKeyword != null &&
+        node.element.redirectedConstructor != null;
+  }
+
+  visitClassDeclaration(ClassDeclaration node) {
+    addAnnotations(node.metadata);
+    ast.Class classNode = currentClass;
+    assert(classNode.members.isEmpty); // All members will be added here.
+
+    bool foundConstructor = false;
+    for (var member in node.members) {
+      if (_isIgnoredMember(member)) continue;
+      if (member is FieldDeclaration) {
+        for (var variable in member.fields.variables) {
+          // Ignore fields inserted through error recovery.
+          if (variable.isSynthetic || variable.length == 0) continue;
+          var field = scope.getMemberReference(variable.element);
+          classNode.addMember(field);
+          _buildMemberBody(field, variable.element, variable);
+        }
+      } else {
+        var memberNode = scope.getMemberReference(member.element);
+        classNode.addMember(memberNode);
+        _buildMemberBody(memberNode, member.element, member);
+        if (member is ConstructorDeclaration) {
+          foundConstructor = true;
+        }
+      }
+    }
+
+    if (!foundConstructor) {
+      var defaultConstructor = scope.findDefaultConstructor(node.element);
+      if (defaultConstructor != null) {
+        assert(defaultConstructor.enclosingElement == node.element);
+        if (!defaultConstructor.isSynthetic) {
+          throw 'Non-synthetic default constructor not in list of members. '
+              '${node} $element $defaultConstructor';
+        }
+        var memberNode = scope.getMemberReference(defaultConstructor);
+        classNode.addMember(memberNode);
+        buildDefaultConstructor(memberNode, defaultConstructor);
+      }
+    }
+
+    addDefaultInstanceFieldInitializers(classNode);
+  }
+
+  void buildDefaultConstructor(
+      ast.Constructor constructor, ConstructorElement element) {
+    var function = constructor.function;
+    function.body = new ast.EmptyStatement()..parent = function;
+    var class_ = element.enclosingElement;
+    if (class_.supertype != null) {
+      // DESIGN TODO: If the super class is a mixin application, we will link to
+      // a constructor not in the immediate super class.  This is a problem due
+      // to the fact that mixed-in fields come with initializers which need to
+      // be executed by a constructor.  The mixin transformer takes care of
+      // this by making forwarding constructors and the super initializers will
+      // be rewritten to use them (see `transformations/mixin_full_resolution`).
+      var superConstructor =
+          scope.findDefaultConstructor(class_.supertype.element);
+      var target = scope.resolveConstructor(superConstructor);
+      if (target == null) {
+        constructor.initializers
+            .add(new ast.InvalidInitializer()..parent = constructor);
+      } else {
+        var arguments = new ast.Arguments.empty();
+        constructor.initializers.add(
+            new ast.SuperInitializer(target, arguments)..parent = constructor);
+      }
+    }
+  }
+
+  /// Adds initializers to instance fields that are have no initializer and are
+  /// not initialized by all constructors in the class.
+  void addDefaultInstanceFieldInitializers(ast.Class node) {
+    List<ast.Field> uninitializedFields = new List<ast.Field>();
+    for (var field in node.fields) {
+      if (field.initializer != null || field.isStatic) continue;
+      uninitializedFields.add(field);
+    }
+    if (uninitializedFields.isEmpty) return;
+    constructorLoop:
+    for (var constructor in node.constructors) {
+      var remainingFields = uninitializedFields.toSet();
+      for (var initializer in constructor.initializers) {
+        if (initializer is ast.FieldInitializer) {
+          remainingFields.remove(initializer.field);
+        } else if (initializer is ast.RedirectingInitializer) {
+          // The target constructor will be checked in another iteration.
+          continue constructorLoop;
+        }
+      }
+      for (var field in remainingFields) {
+        if (field.initializer == null) {
+          field.initializer = new ast.NullLiteral()..parent = field;
+        }
+      }
+    }
+  }
+
+  /// True for the `values` field of an `enum` class.
+  static bool _isValuesField(FieldElement field) => field.name == 'values';
+
+  /// True for the `index` field of an `enum` class.
+  static bool _isIndexField(FieldElement field) => field.name == 'index';
+
+  visitEnumDeclaration(EnumDeclaration node) {
+    addAnnotations(node.metadata);
+    ast.Class classNode = currentClass;
+    var intType =
+        new ast.InterfaceType(scope.loader.getCoreClassReference('int'));
+    var indexFieldElement = element.fields.firstWhere(_isIndexField);
+    ast.Field indexField = scope.getMemberReference(indexFieldElement);
+    indexField.type = intType;
+    classNode.addMember(indexField);
+    var parameter = new ast.VariableDeclaration('index', type: intType);
+    var function = new ast.FunctionNode(new ast.EmptyStatement(),
+        positionalParameters: [parameter]);
+    var superConstructor = scope.loader.getRootClassConstructorReference();
+    var constructor = new ast.Constructor(function,
+        name: new ast.Name(''),
+        isConst: true,
+        initializers: [
+          new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)),
+          new ast.SuperInitializer(superConstructor, new ast.Arguments.empty())
+        ]);
+    classNode.addMember(constructor);
+    int index = 0;
+    var enumConstantFields = <ast.Field>[];
+    for (var constant in node.constants) {
+      ast.Field field = scope.getMemberReference(constant.element);
+      field.initializer = new ast.ConstructorInvocation(
+          constructor, new ast.Arguments([new ast.IntLiteral(index)]),
+          isConst: true)..parent = field;
+      field.type = new ast.InterfaceType(classNode);
+      classNode.addMember(field);
+      ++index;
+      enumConstantFields.add(field);
+    }
+    // Add the 'values' field.
+    var valuesFieldElement = element.fields.firstWhere(_isValuesField);
+    ast.Field valuesField = scope.getMemberReference(valuesFieldElement);
+    var enumType = new ast.InterfaceType(classNode);
+    valuesField.type = new ast.InterfaceType(
+        scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]);
+    valuesField.initializer = new ast.ListLiteral(
+        enumConstantFields.map(_makeStaticGet).toList(),
+        isConst: true,
+        typeArgument: enumType)..parent = valuesField;
+    classNode.addMember(valuesField);
+    // TODO: Add the toString method.
+  }
+
+  visitClassTypeAlias(ClassTypeAlias node) {
+    addAnnotations(node.metadata);
+    assert(node.withClause != null && node.withClause.mixinTypes.isNotEmpty);
+    ast.Class classNode = currentClass;
+    for (var constructor in element.constructors) {
+      var constructorNode = scope.getMemberReference(constructor);
+      classNode.addMember(constructorNode);
+      buildMixinConstructor(constructorNode, constructor);
+    }
+  }
+
+  void buildMixinConstructor(
+      ast.Constructor constructor, ConstructorElement element) {
+    var function = constructor.function;
+    function.body = new ast.EmptyStatement()..parent = function;
+    // Call the corresponding constructor in super class.
+    ClassElement classElement = element.enclosingElement;
+    var targetConstructor = classElement.supertype.element.constructors
+        .firstWhere((c) => c.name == element.name);
+    var positionalArguments = constructor.function.positionalParameters
+        .map(_makeVariableGet)
+        .toList();
+    var namedArguments = constructor.function.namedParameters
+        .map(_makeNamedExpressionFrom)
+        .toList();
+    constructor.initializers.add(new ast.SuperInitializer(
+        scope.getMemberReference(targetConstructor),
+        new ast.Arguments(positionalArguments, named: namedArguments))
+      ..parent = constructor);
+  }
+
+  visitNode(AstNode node) {
+    throw 'Unsupported class declaration: ${node.runtimeType}';
+  }
+}
+
+/// Brings a member from reference level to body level.
+class MemberBodyBuilder extends GeneralizingAstVisitor<Null> {
+  final MemberScope scope;
+  final Element element;
+  ast.Member get currentMember => scope.currentMember;
+
+  MemberBodyBuilder(
+      ReferenceLevelLoader loader, ast.Member member, this.element)
+      : scope = new MemberScope(loader, member);
+
+  void build(AstNode node) {
+    if (node != null) {
+      node.accept(this);
+    } else {
+      buildBrokenMember();
+    }
+  }
+
+  /// Builds an empty member.
+  ///
+  /// This should only be used to recover from a compile-time error.
+  void buildBrokenMember() {
+    var member = currentMember;
+    member.name = new ast.Name(element.name, scope.currentLibrary);
+    if (member is ast.Procedure) {
+      member.function = new ast.FunctionNode(new ast.InvalidStatement())
+        ..parent = member;
+    } else if (member is ast.Constructor) {
+      member.function = new ast.FunctionNode(new ast.InvalidStatement())
+        ..parent = member;
+    }
+  }
+
+  void addAnnotations(List<Annotation> annotations) {
+    for (var annotation in annotations) {
+      currentMember.addAnnotation(scope.buildAnnotation(annotation));
+    }
+  }
+
+  void handleNativeBody(FunctionBody body) {
+    if (body is NativeFunctionBody) {
+      currentMember.isExternal = true;
+      currentMember.addAnnotation(new ast.ConstructorInvocation(
+          scope.loader.getCoreClassConstructorReference('ExternalName',
+              library: 'dart:_internal'),
+          new ast.Arguments(<ast.Expression>[
+            new ast.StringLiteral(body.stringLiteral.stringValue)
+          ]),
+          isConst: true));
+    }
+  }
+
+  visitConstructorDeclaration(ConstructorDeclaration node) {
+    if (node.factoryKeyword != null) {
+      buildFactoryConstructor(node);
+    } else {
+      buildGenerativeConstructor(node);
+    }
+  }
+
+  void buildGenerativeConstructor(ConstructorDeclaration node) {
+    addAnnotations(node.metadata);
+    ast.Constructor constructor = currentMember;
+    constructor.function = scope.buildFunctionNode(node.parameters, node.body,
+        inferredReturnType: const ast.VoidType())..parent = constructor;
+    handleNativeBody(node.body);
+    if (node.body is EmptyFunctionBody && !constructor.isExternal) {
+      var function = constructor.function;
+      function.body = new ast.EmptyStatement()..parent = function;
+    }
+    for (var parameter in node.parameters.parameterElements) {
+      if (parameter is FieldFormalParameterElement) {
+        var initializer = new ast.FieldInitializer(
+            scope.getMemberReference(parameter.field),
+            new ast.VariableGet(scope.getVariableReference(parameter)));
+        constructor.initializers.add(initializer..parent = constructor);
+      }
+    }
+    bool hasExplicitConstructorCall = false;
+    for (var initializer in node.initializers) {
+      var node = scope.buildInitializer(initializer);
+      constructor.initializers.add(node..parent = constructor);
+      if (node is ast.SuperInitializer || node is ast.RedirectingInitializer) {
+        hasExplicitConstructorCall = true;
+      }
+    }
+    ClassElement classElement = node.element.enclosingElement;
+    if (classElement.supertype != null && !hasExplicitConstructorCall) {
+      ConstructorElement targetElement =
+          scope.findDefaultConstructor(classElement.supertype.element);
+      ast.Constructor target = scope.resolveConstructor(targetElement);
+      ast.Initializer initializer = target == null
+          ? new ast.InvalidInitializer()
+          : new ast.SuperInitializer(
+              target, new ast.Arguments(<ast.Expression>[]));
+      constructor.initializers.add(initializer..parent = constructor);
+    } else {
+      moveSuperInitializerLast(constructor);
+    }
+  }
+
+  void buildFactoryConstructor(ConstructorDeclaration node) {
+    addAnnotations(node.metadata);
+    ast.Procedure procedure = currentMember;
+    ClassElement classElement = node.element.enclosingElement;
+    ast.Class classNode = procedure.enclosingClass;
+    var types = getFreshTypeParameters(classNode.typeParameters);
+    for (int i = 0; i < classElement.typeParameters.length; ++i) {
+      scope.localTypeParameters[classElement.typeParameters[i]] =
+          types.freshTypeParameters[i];
+    }
+    var function = scope.buildFunctionNode(node.parameters, node.body,
+        typeParameters: types.freshTypeParameters,
+        inferredReturnType: new ast.InterfaceType(classNode,
+            types.freshTypeParameters.map(makeTypeParameterType).toList()));
+    procedure.function = function..parent = procedure;
+    handleNativeBody(node.body);
+    if (node.redirectedConstructor != null) {
+      // Redirecting factories with resolved targets don't show up here.
+      assert(node.element.redirectedConstructor == null);
+      var function = procedure.function;
+      var name = node.redirectedConstructor.type.name.name;
+      if (node.redirectedConstructor.name != null) {
+        name += '.' + node.redirectedConstructor.name.name;
+      }
+      // TODO(asgerf): Sometimes a TypeError should be thrown.
+      function.body = new ast.ExpressionStatement(
+          scope.buildThrowNoSuchMethodError(
+              new ast.NullLiteral(), name, new ast.Arguments.empty()))
+        ..parent = function;
+    }
+  }
+
+  visitMethodDeclaration(MethodDeclaration node) {
+    addAnnotations(node.metadata);
+    ast.Procedure procedure = currentMember;
+    procedure.function = scope.buildFunctionNode(node.parameters, node.body,
+        returnType: node.returnType,
+        inferredReturnType: scope.buildType(node.element.returnType),
+        typeParameters:
+            scope.buildOptionalTypeParameterList(node.typeParameters))
+      ..parent = procedure;
+    handleNativeBody(node.body);
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    addAnnotations(node.metadata);
+    ast.Field field = currentMember;
+    field.type = scope.buildType(node.element.type);
+    if (node.initializer != null) {
+      field.initializer = scope.buildTopLevelExpression(node.initializer)
+        ..parent = field;
+    } else if (field.isStatic) {
+      // Add null initializer to static fields without an initializer.
+      // For instance fields, this is handled when building the class.
+      field.initializer = new ast.NullLiteral()..parent = field;
+    }
+  }
+
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    var function = node.functionExpression;
+    ast.Procedure procedure = currentMember;
+    procedure.function = scope.buildFunctionNode(
+        function.parameters, function.body,
+        returnType: node.returnType,
+        typeParameters:
+            scope.buildOptionalTypeParameterList(function.typeParameters))
+      ..parent = procedure;
+    handleNativeBody(function.body);
+  }
+
+  visitNode(AstNode node) {
+    log.severe('Unexpected class or library member: $node');
+  }
+}
+
+/// Internal exception thrown from the expression or statement builder when a
+/// compilation error is found.
+///
+/// This is then caught at the function level to replace the entire function
+/// body (or field initializer) with a throw.
+class _CompilationError {
+  String message;
+
+  _CompilationError(this.message);
+}
+
+/// Constructor alias for [ast.TypeParameterType], use instead of a closure.
+ast.DartType makeTypeParameterType(ast.TypeParameter parameter) {
+  return new ast.TypeParameterType(parameter);
+}
+
+/// Constructor alias for [ast.VariableGet], use instead of a closure.
+ast.VariableGet _makeVariableGet(ast.VariableDeclaration variable) {
+  return new ast.VariableGet(variable);
+}
+
+/// Constructor alias for [ast.StaticGet], use instead of a closure.
+ast.StaticGet _makeStaticGet(ast.Field field) {
+  return new ast.StaticGet(field);
+}
+
+/// Create a named expression with the name and value of the given variable.
+ast.NamedExpression _makeNamedExpressionFrom(ast.VariableDeclaration variable) {
+  return new ast.NamedExpression(variable.name, new ast.VariableGet(variable));
+}
+
+/// A [StaticAccessor] that throws a NoSuchMethodError when a suitable target
+/// could not be resolved.
+class _StaticAccessor extends StaticAccessor {
+  final ExpressionScope scope;
+  final String name;
+
+  _StaticAccessor(
+      this.scope, this.name, ast.Member readTarget, ast.Member writeTarget)
+      : super(readTarget, writeTarget);
+
+  @override
+  makeInvalidRead() {
+    return scope.buildThrowNoSuchMethodError(
+        new ast.NullLiteral(), name, new ast.Arguments([]));
+  }
+
+  @override
+  makeInvalidWrite(ast.Expression value) {
+    return scope.buildThrowNoSuchMethodError(
+        new ast.NullLiteral(), name, new ast.Arguments([value]));
+  }
+}
+
+bool isTopLevelFunction(Element element) {
+  return element is FunctionElement &&
+      element.enclosingElement is CompilationUnitElement;
+}
+
+bool isLocalFunction(Element element) {
+  return element is FunctionElement &&
+      element.enclosingElement is! CompilationUnitElement &&
+      element.enclosingElement is! LibraryElement;
+}
+
+bool isLocal(Element element) {
+  return isLocalFunction(element) ||
+      element is LocalVariableElement ||
+      element is ParameterElement;
+}
+
+bool isInstanceMethod(Element element) {
+  return element is MethodElement && !element.isStatic;
+}
+
+bool isStaticMethod(Element element) {
+  return element is MethodElement && element.isStatic ||
+      isTopLevelFunction(element);
+}
+
+bool isStaticVariableOrGetter(Element element) {
+  element = desynthesizeGetter(element);
+  return element is FieldElement && element.isStatic ||
+      element is TopLevelVariableElement;
+}
+
+Element desynthesizeGetter(Element element) {
+  if (element == null || !element.isSynthetic) return element;
+  if (element is PropertyAccessorElement) return element.variable;
+  if (element is FieldElement) return element.getter;
+  return element;
+}
+
+Element desynthesizeSetter(Element element) {
+  if (element == null || !element.isSynthetic) return element;
+  if (element is PropertyAccessorElement) return element.variable;
+  if (element is FieldElement) return element.setter;
+  return element;
+}
+
+void sortAndRemoveDuplicates/*<T extends Comparable<T>>*/(List/*<T>*/ list) {
+  list.sort();
+  int deleted = 0;
+  for (int i = 1; i < list.length; ++i) {
+    var item = list[i];
+    if (list[i - 1].compareTo(item) == 0) {
+      ++deleted;
+    } else if (deleted > 0) {
+      list[i - deleted] = item;
+    }
+  }
+  if (deleted > 0) {
+    list.length -= deleted;
+  }
+}
diff --git a/pkg/kernel/lib/analyzer/loader.dart b/pkg/kernel/lib/analyzer/loader.dart
new file mode 100644
index 0000000..1591bcf
--- /dev/null
+++ b/pkg/kernel/lib/analyzer/loader.dart
@@ -0,0 +1,818 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.analyzer.loader;
+
+import 'dart:async';
+import 'dart:io' as io;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:package_config/discovery.dart';
+import 'package:package_config/packages.dart';
+
+import '../ast.dart' as ast;
+import '../repository.dart';
+import '../target/targets.dart' show Target;
+import '../type_algebra.dart';
+import 'analyzer.dart';
+import 'ast_from_analyzer.dart';
+
+/// Options passed to the Dart frontend.
+class DartOptions {
+  /// True if user code should be loaded in strong mode.
+  bool strongMode;
+
+  /// True if the Dart SDK should be loaded in strong mode.
+  bool strongModeSdk;
+  String sdk;
+  String packagePath;
+  Map<Uri, Uri> customUriMappings;
+  Map<String, String> declaredVariables;
+
+  DartOptions(
+      {bool strongMode: false,
+      bool strongModeSdk,
+      this.sdk,
+      this.packagePath,
+      Map<Uri, Uri> customUriMappings,
+      Map<String, String> declaredVariables})
+      : this.customUriMappings = customUriMappings ?? <Uri, Uri>{},
+        this.declaredVariables = declaredVariables ?? <String, String>{},
+        this.strongMode = strongMode,
+        this.strongModeSdk = strongModeSdk ?? strongMode;
+}
+
+abstract class ReferenceLevelLoader {
+  ast.Library getLibraryReference(LibraryElement element);
+  ast.Class getClassReference(ClassElement element);
+  ast.Member getMemberReference(Element element);
+  ast.Class getRootClassReference();
+  ast.Constructor getRootClassConstructorReference();
+  ast.Class getCoreClassReference(String className);
+  ast.Constructor getCoreClassConstructorReference(String className,
+      {String constructorName, String library});
+  ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element);
+  ast.Class getSharedMixinApplicationClass(
+      ast.Library library, ast.Class supertype, ast.Class mixin);
+  bool get strongMode;
+}
+
+class DartLoader implements ReferenceLevelLoader {
+  final Repository repository;
+  final Bimap<ClassElement, ast.Class> _classes =
+      new Bimap<ClassElement, ast.Class>();
+  final Bimap<Element, ast.Member> _members = new Bimap<Element, ast.Member>();
+  final Map<TypeParameterElement, ast.TypeParameter> _classTypeParameters =
+      <TypeParameterElement, ast.TypeParameter>{};
+  final Map<ast.Library, Map<String, ast.Class>> _mixinApplications =
+      <ast.Library, Map<String, ast.Class>>{};
+  final AnalysisContext context;
+  LibraryElement _dartCoreLibrary;
+  final List errors = [];
+  final List libraryElements = [];
+
+  /// Classes that have been referenced, and must be promoted to type level
+  /// so as not to expose partially initialized classes.
+  final List<ast.Class> temporaryClassWorklist = [];
+
+  LibraryElement _libraryBeingLoaded = null;
+
+  bool get strongMode => context.analysisOptions.strongMode;
+
+  DartLoader(this.repository, DartOptions options, Packages packages,
+      {DartSdk dartSdk})
+      : this.context = createContext(options, packages, dartSdk: dartSdk);
+
+  LibraryElement getLibraryElement(ast.Library node) {
+    return context
+        .getLibraryElement(context.sourceFactory.forUri2(node.importUri));
+  }
+
+  String getLibraryName(LibraryElement element) {
+    return element.name.isEmpty ? null : element.name;
+  }
+
+  ast.Library getLibraryReference(LibraryElement element) {
+    return repository.getLibraryReference(element.source.uri)
+      ..name ??= getLibraryName(element)
+      ..fileUri = "file://${element.source.fullName}";
+  }
+
+  void _buildTopLevelMember(ast.Member member, Element element) {
+    var astNode = element.computeNode();
+    assert(member.parent != null);
+    new MemberBodyBuilder(this, member, element).build(astNode);
+  }
+
+  /// True if [element] is in the process of being loaded by
+  /// [_buildLibraryBody].
+  ///
+  /// If this is the case, we should avoid adding new members to the classes
+  /// in the library, since the AST builder will rebuild the member lists.
+  bool isLibraryBeingLoaded(LibraryElement element) {
+    return _libraryBeingLoaded == element;
+  }
+
+  void _buildLibraryBody(LibraryElement element, ast.Library library) {
+    assert(_libraryBeingLoaded == null);
+    _libraryBeingLoaded = element;
+    var classes = <ast.Class>[];
+    var procedures = <ast.Procedure>[];
+    var fields = <ast.Field>[];
+    void loadClass(ClassElement classElement) {
+      var node = getClassReference(classElement);
+      promoteToBodyLevel(node);
+      classes.add(node);
+    }
+
+    void loadProcedure(Element memberElement) {
+      var node = getMemberReference(memberElement);
+      _buildTopLevelMember(node, memberElement);
+      procedures.add(node);
+    }
+
+    void loadField(Element memberElement) {
+      var node = getMemberReference(memberElement);
+      _buildTopLevelMember(node, memberElement);
+      fields.add(node);
+    }
+
+    for (var unit in element.units) {
+      unit.types.forEach(loadClass);
+      unit.enums.forEach(loadClass);
+      for (var accessor in unit.accessors) {
+        if (!accessor.isSynthetic) {
+          loadProcedure(accessor);
+        }
+      }
+      for (var function in unit.functions) {
+        loadProcedure(function);
+      }
+      for (var field in unit.topLevelVariables) {
+        // Ignore fields inserted through error recovery.
+        if (!field.isSynthetic && field.name != '') {
+          loadField(field);
+        }
+      }
+    }
+    libraryElements.add(element);
+    _iterateWorklist();
+    // Ensure everything is stored in the original declaration order.
+    library.classes
+      ..clear()
+      ..addAll(classes)
+      ..addAll(_mixinApplications[library]?.values ?? const []);
+    library.fields
+      ..clear()
+      ..addAll(fields);
+    library.procedures
+      ..clear()
+      ..addAll(procedures);
+    _libraryBeingLoaded = null;
+  }
+
+  LibraryElement getDartCoreLibrary() {
+    return _dartCoreLibrary ??= _findLibraryElement('dart:core');
+  }
+
+  LibraryElement _findLibraryElement(String uri) {
+    var source = context.sourceFactory.forUri(uri);
+    if (source == null) return null;
+    return context.computeLibraryElement(source);
+  }
+
+  ast.Class getRootClassReference() {
+    return getCoreClassReference('Object');
+  }
+
+  ast.Constructor getRootClassConstructorReference() {
+    var element = getDartCoreLibrary().getType('Object').constructors[0];
+    return getMemberReference(element);
+  }
+
+  ast.Class getCoreClassReference(String className) {
+    return getClassReference(getDartCoreLibrary().getType(className));
+  }
+
+  ast.Constructor getCoreClassConstructorReference(String className,
+      {String constructorName, String library}) {
+    LibraryElement libraryElement =
+        library != null ? _findLibraryElement(library) : getDartCoreLibrary();
+    ClassElement element = libraryElement.getType(className);
+    if (element == null) {
+      throw 'Missing core class $className from ${libraryElement.name}';
+    }
+    var constructor = element.constructors.firstWhere((constructor) {
+      return (constructorName == null)
+          ? (constructor.nameLength == 0)
+          : (constructor.name == constructorName);
+    });
+    return getMemberReference(constructor);
+  }
+
+  ClassElement getClassElement(ast.Class node) {
+    return _classes.inverse[node];
+  }
+
+  void addMixinClassToLibrary(ast.Class class_, ast.Library library) {
+    assert(class_.parent == null);
+    library.addClass(class_);
+    var map =
+        _mixinApplications.putIfAbsent(library, () => <String, ast.Class>{});
+    map[class_.name] = class_;
+  }
+
+  /// Returns the IR for a class, at a temporary loading level.
+  ///
+  /// The returned class has the correct name, flags, type parameter arity,
+  /// and enclosing library.
+  ast.Class getClassReference(ClassElement element) {
+    var classNode = _classes[element];
+    if (classNode != null) return classNode;
+    _classes[element] = classNode = new ast.Class(
+        name: element.name,
+        isAbstract: element.isAbstract,
+        fileUri: "file://${element.source.fullName}");
+    classNode.level = ast.ClassLevel.Temporary;
+    var library = getLibraryReference(element.library);
+    library.addClass(classNode);
+    // Initialize type parameter list without bounds.
+    for (var parameter in element.typeParameters) {
+      var parameterNode = new ast.TypeParameter(parameter.name);
+      _classTypeParameters[parameter] = parameterNode;
+      classNode.typeParameters.add(parameterNode);
+      parameterNode.parent = classNode;
+    }
+    // Ensure the class is at least promoted to type level before exposing it
+    // to kernel consumers.
+    temporaryClassWorklist.add(classNode);
+    return classNode;
+  }
+
+  /// Ensures the supertypes and type parameter bounds have been generated for
+  /// the given class.
+  void promoteToTypeLevel(ast.Class classNode) {
+    if (classNode.level.index >= ast.ClassLevel.Type.index) return;
+    classNode.level = ast.ClassLevel.Type;
+    var element = getClassElement(classNode);
+    assert(element != null);
+    var library = getLibraryReference(element.library);
+    var scope = new ClassScope(this, library);
+    // Initialize bounds on type parameters.
+    for (int i = 0; i < classNode.typeParameters.length; ++i) {
+      var parameter = element.typeParameters[i];
+      var parameterNode = classNode.typeParameters[i];
+      parameterNode.bound = parameter.bound == null
+          ? scope.defaultTypeParameterBound
+          : scope.buildType(parameter.bound);
+    }
+    // Initialize supertypes.
+    Iterable<InterfaceType> mixins = element.mixins;
+    if (element.isMixinApplication && mixins.isNotEmpty) {
+      classNode.mixedInType = scope.buildSupertype(mixins.last);
+      mixins = mixins.take(mixins.length - 1);
+    }
+    if (element.supertype != null) {
+      ast.Supertype supertype = scope.buildSupertype(element.supertype);
+      bool useSharedMixin = true;
+      for (var mixin in mixins) {
+        var mixinType = scope.buildSupertype(mixin);
+        if (useSharedMixin &&
+            areDistinctUnboundTypeVariables(supertype, mixinType)) {
+          // Use a shared mixin application class for this library.
+          var mixinClass = getSharedMixinApplicationClass(
+              scope.currentLibrary, supertype.classNode, mixinType.classNode);
+          supertype = new ast.Supertype(
+              mixinClass,
+              supertype.typeArguments.length > mixinType.typeArguments.length
+                  ? supertype.typeArguments
+                  : mixinType.typeArguments);
+        } else {
+          // Generate a new class specific for this mixin application.
+          var freshParameters =
+              getFreshTypeParameters(classNode.typeParameters);
+          var mixinClass = new ast.Class(
+              name: '${classNode.name}^${mixinType.classNode.name}',
+              isAbstract: true,
+              typeParameters: freshParameters.freshTypeParameters,
+              supertype: freshParameters.substituteSuper(supertype),
+              mixedInType: freshParameters.substituteSuper(mixinType));
+          mixinClass.level = ast.ClassLevel.Type;
+          supertype = new ast.Supertype(mixinClass,
+              classNode.typeParameters.map(makeTypeParameterType).toList());
+          addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary);
+          // This class cannot be used from anywhere else, so don't try to
+          // generate shared mixin applications using it.
+          useSharedMixin = false;
+        }
+      }
+      classNode.supertype = supertype;
+      for (var implementedType in element.interfaces) {
+        classNode.implementedTypes.add(scope.buildSupertype(implementedType));
+      }
+    }
+  }
+
+  void promoteToHierarchyLevel(ast.Class classNode) {
+    if (classNode.level.index >= ast.ClassLevel.Hierarchy.index) return;
+    promoteToTypeLevel(classNode);
+    classNode.level = ast.ClassLevel.Hierarchy;
+    var element = getClassElement(classNode);
+    if (element != null) {
+      // Ensure all instance members are at present.
+      for (var field in element.fields) {
+        if (!field.isStatic && !field.isSynthetic) {
+          getMemberReference(field);
+        }
+      }
+      for (var accessor in element.accessors) {
+        if (!accessor.isStatic && !accessor.isSynthetic) {
+          getMemberReference(accessor);
+        }
+      }
+      for (var method in element.methods) {
+        if (!method.isStatic && !method.isSynthetic) {
+          getMemberReference(method);
+        }
+      }
+    }
+    for (var supertype in classNode.supers) {
+      promoteToHierarchyLevel(supertype.classNode);
+    }
+  }
+
+  void promoteToBodyLevel(ast.Class classNode) {
+    if (classNode.level == ast.ClassLevel.Body) return;
+    promoteToHierarchyLevel(classNode);
+    classNode.level = ast.ClassLevel.Body;
+    var element = getClassElement(classNode);
+    if (element == null) return;
+    var astNode = element.computeNode();
+    // Clear out the member references that were put in the class.
+    // The AST builder will load them all put back in the right order.
+    classNode..fields.clear()..procedures.clear()..constructors.clear();
+    new ClassBodyBuilder(this, classNode, element).build(astNode);
+  }
+
+  ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element) {
+    return _classTypeParameters[element];
+  }
+
+  Element getMemberElement(ast.Member node) {
+    return _members.inverse[node];
+  }
+
+  ast.Member getMemberReference(Element element) {
+    assert(element is! Member); // Use the "base element".
+    return _members[element] ??= _buildMemberReference(element);
+  }
+
+  ast.Member _buildMemberReference(Element element) {
+    var node = _buildOrphanedMemberReference(element);
+    // Set the parent pointer and store it in the enclosing class or library.
+    // If the enclosing library is being built from the AST, do not add the
+    // member, since the AST builder will put it in there.
+    var parent = element.enclosingElement;
+    if (parent is ClassElement) {
+      var class_ = getClassReference(parent);
+      node.parent = class_;
+      if (!isLibraryBeingLoaded(element.library)) {
+        class_.addMember(node);
+      }
+    } else {
+      var library = getLibraryReference(element.library);
+      node.parent = library;
+      if (!isLibraryBeingLoaded(element.library)) {
+        library.addMember(node);
+      }
+    }
+    return node;
+  }
+
+  ast.Member _buildOrphanedMemberReference(Element element) {
+    ClassElement classElement = element.enclosingElement is ClassElement
+        ? element.enclosingElement
+        : null;
+    TypeScope scope = classElement != null
+        ? new ClassScope(this, getLibraryReference(element.library))
+        : new TypeScope(this);
+    if (classElement != null) {
+      getClassReference(classElement);
+    }
+    switch (element.kind) {
+      case ElementKind.CONSTRUCTOR:
+        ConstructorElement constructor = element;
+        if (constructor.isFactory) {
+          return new ast.Procedure(
+              _nameOfMember(constructor),
+              ast.ProcedureKind.Factory,
+              scope.buildFunctionInterface(constructor),
+              isAbstract: false,
+              isStatic: true,
+              isExternal: constructor.isExternal,
+              isConst: constructor.isConst,
+              fileUri: "file://${element.source.fullName}");
+        }
+        return new ast.Constructor(scope.buildFunctionInterface(constructor),
+            name: _nameOfMember(element),
+            isConst: constructor.isConst,
+            isExternal: constructor.isExternal);
+
+      case ElementKind.FIELD:
+      case ElementKind.TOP_LEVEL_VARIABLE:
+        VariableElement variable = element;
+        return new ast.Field(_nameOfMember(variable),
+            isStatic: variable.isStatic,
+            isFinal: variable.isFinal,
+            isConst: variable.isConst,
+            type: scope.buildType(variable.type),
+            fileUri: "file://${element.source.fullName}")
+          ..fileOffset = element.nameOffset;
+
+      case ElementKind.METHOD:
+      case ElementKind.GETTER:
+      case ElementKind.SETTER:
+      case ElementKind.FUNCTION:
+        if (element is FunctionElement &&
+            element.enclosingElement is! CompilationUnitElement) {
+          throw 'Function $element is nested in ${element.enclosingElement} '
+              'and hence is not a member';
+        }
+        ExecutableElement executable = element;
+        return new ast.Procedure(
+            _nameOfMember(element),
+            _procedureKindOf(executable),
+            scope.buildFunctionInterface(executable),
+            isAbstract: executable.isAbstract,
+            isStatic: executable.isStatic,
+            isExternal: executable.isExternal,
+            fileUri: "file://${element.source.fullName}");
+
+      default:
+        throw 'Unexpected member kind: $element';
+    }
+  }
+
+  ast.ProcedureKind _procedureKindOf(ExecutableElement element) {
+    if (element is PropertyAccessorElement) {
+      return element.isGetter
+          ? ast.ProcedureKind.Getter
+          : ast.ProcedureKind.Setter;
+    }
+    if (element is MethodElement) {
+      if (element.isOperator) return ast.ProcedureKind.Operator;
+      return ast.ProcedureKind.Method;
+    }
+    if (element is FunctionElement) {
+      return ast.ProcedureKind.Method;
+    }
+    if (element is ConstructorElement) {
+      assert(element.isFactory);
+      return ast.ProcedureKind.Factory;
+    }
+    throw 'Unexpected procedure: $element';
+  }
+
+  ast.Name _nameOfMember(Element element) {
+    // Use 'displayName' to avoid a trailing '=' for setters and 'name' to
+    // ensure unary minus is called 'unary-'.
+    String name =
+        element is PropertyAccessorElement ? element.displayName : element.name;
+    return new ast.Name(name, getLibraryReference(element.library));
+  }
+
+  /// True if the two types have form `C<T1 ... Tm>` and `D<T1 ... Tn>`, and
+  /// `T1 ... TN` are distinct type variables with no upper bound, where
+  /// `N = max(m,n)`.
+  bool areDistinctUnboundTypeVariables(
+      ast.Supertype first, ast.Supertype second) {
+    var seen = new Set<ast.TypeParameter>();
+    if (first.typeArguments.length < second.typeArguments.length) {
+      var tmp = first;
+      first = second;
+      second = tmp;
+    }
+    for (int i = 0; i < first.typeArguments.length; ++i) {
+      var firstArg = first.typeArguments[i];
+      if (!(firstArg is ast.TypeParameterType &&
+          seen.add(firstArg.parameter) &&
+          firstArg.parameter.bound is ast.DynamicType)) {
+        return false;
+      }
+      if (i < second.typeArguments.length &&
+          firstArg != second.typeArguments[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// Returns the canonical mixin application of two classes, instantiated with
+  /// the same list of unbound type variables.
+  ///
+  /// Given two classes:
+  ///     class C<C1 ... Cm>
+  ///     class D<D1 ... Dn>
+  ///
+  /// This creates or reuses a mixin application class in the library of form:
+  ///
+  ///     abstract class C&D<T1 ... TN> = C<T1 ... Tm> with D<T1 ... Tn>
+  ///
+  /// where `N = max(m,n)`.
+  ///
+  /// Such a class can in general contain type errors due to incompatible
+  /// inheritance from `C` and `D`.  This method therefore should only be called
+  /// if a mixin application `C<S1 ... Sm> with D<S1 ... Sn>` is seen, where
+  /// `S1 ... SN` are distinct, unbound type variables.
+  ast.Class getSharedMixinApplicationClass(
+      ast.Library library, ast.Class superclass, ast.Class mixedInClass) {
+    // TODO(asgerf): Avoid potential name clash due to associativity.
+    // As it is, these mixins get the same name:
+    //   (A with B) with C
+    //   A with (B with C)
+    String name = '${superclass.name}&${mixedInClass.name}';
+    return _mixinApplications
+        .putIfAbsent(library, () => <String, ast.Class>{})
+        .putIfAbsent(name, () {
+      var fresh =
+          superclass.typeParameters.length >= mixedInClass.typeParameters.length
+              ? getFreshTypeParameters(superclass.typeParameters)
+              : getFreshTypeParameters(mixedInClass.typeParameters);
+      var typeArguments =
+          fresh.freshTypeParameters.map(makeTypeParameterType).toList();
+      var superArgs = typeArguments.length != superclass.typeParameters.length
+          ? typeArguments.sublist(0, superclass.typeParameters.length)
+          : typeArguments;
+      var mixinArgs = typeArguments.length != mixedInClass.typeParameters.length
+          ? typeArguments.sublist(0, mixedInClass.typeParameters.length)
+          : typeArguments;
+      var result = new ast.Class(
+          name: name,
+          isAbstract: true,
+          typeParameters: fresh.freshTypeParameters,
+          supertype: new ast.Supertype(superclass, superArgs),
+          mixedInType: new ast.Supertype(mixedInClass, mixinArgs),
+          fileUri: mixedInClass.fileUri);
+      result.level = ast.ClassLevel.Type;
+      library.addClass(result);
+      return result;
+    });
+  }
+
+  String formatErrorMessage(
+      AnalysisError error, String filename, LineInfo lines) {
+    var location = lines.getLocation(error.offset);
+    return '[error] ${error.message} ($filename, '
+        'line ${location.lineNumber}, '
+        'col ${location.columnNumber})';
+  }
+
+  void ensureLibraryIsLoaded(ast.Library node) {
+    if (!node.isExternal) return;
+    node.isExternal = false;
+    var source = context.sourceFactory.forUri2(node.importUri);
+    assert(source != null);
+    var element = context.computeLibraryElement(source);
+    context.resolveCompilationUnit(source, element);
+    _buildLibraryBody(element, node);
+    if (node.importUri.scheme != 'dart') {
+      for (var unit in element.units) {
+        LineInfo lines;
+        for (var error in context.computeErrors(unit.source)) {
+          if (error.errorCode is CompileTimeErrorCode ||
+              error.errorCode is ParserErrorCode ||
+              error.errorCode is ScannerErrorCode ||
+              error.errorCode is StrongModeCode) {
+            lines ??= context.computeLineInfo(source);
+            errors.add(formatErrorMessage(error, source.shortName, lines));
+          }
+        }
+      }
+    }
+  }
+
+  void loadEverything({Target target}) {
+    ensureLibraryIsLoaded(getLibraryReference(getDartCoreLibrary()));
+    if (target != null) {
+      for (var uri in target.extraRequiredLibraries) {
+        var library = _findLibraryElement(uri);
+        if (library == null) {
+          errors.add('Could not find required library $uri');
+          continue;
+        }
+        ensureLibraryIsLoaded(getLibraryReference(library));
+      }
+    }
+    for (int i = 0; i < repository.libraries.length; ++i) {
+      ensureLibraryIsLoaded(repository.libraries[i]);
+    }
+  }
+
+  /// Builds a list of sources that have been loaded.
+  ///
+  /// This operation may be expensive and should only be used for diagnostics.
+  List<String> getLoadedFileNames() {
+    var list = <String>[];
+    for (var library in repository.libraries) {
+      LibraryElement element = context.computeLibraryElement(
+          context.sourceFactory.forUri2(library.importUri));
+      for (var unit in element.units) {
+        list.add(unit.source.fullName);
+      }
+    }
+    return list;
+  }
+
+  void _iterateWorklist() {
+    while (temporaryClassWorklist.isNotEmpty) {
+      var element = temporaryClassWorklist.removeLast();
+      promoteToTypeLevel(element);
+    }
+  }
+
+  ast.Program loadProgram(String mainLibrary, {Target target}) {
+    ast.Library library = repository.getLibrary(mainLibrary);
+    ensureLibraryIsLoaded(library);
+    loadEverything(target: target);
+    var program = new ast.Program(repository.libraries);
+    program.mainMethod = library.procedures.firstWhere(
+        (member) => member.name?.name == 'main',
+        orElse: () => null);
+    for (LibraryElement libraryElement in libraryElements) {
+      for (CompilationUnitElement compilationUnitElement
+          in libraryElement.units) {
+        // TODO(jensj): Get this another way?
+        LineInfo lineInfo = compilationUnitElement.computeNode().lineInfo;
+        program.uriToLineStarts[
+                "file://${compilationUnitElement.source.source.fullName}"] =
+            new List<int>.generate(lineInfo.lineCount, lineInfo.getOffsetOfLine,
+                growable: false);
+      }
+    }
+    return program;
+  }
+
+  ast.Library loadLibrary(String mainLibrary) {
+    ast.Library library = repository.getLibrary(mainLibrary);
+    ensureLibraryIsLoaded(library);
+    return library;
+  }
+}
+
+class Bimap<K, V> {
+  final Map<K, V> nodeMap = <K, V>{};
+  final Map<V, K> inverse = <V, K>{};
+
+  bool containsKey(K key) => nodeMap.containsKey(key);
+
+  V operator [](K key) => nodeMap[key];
+
+  void operator []=(K key, V value) {
+    assert(!nodeMap.containsKey(key));
+    nodeMap[key] = value;
+    inverse[value] = key;
+  }
+}
+
+/// Creates [DartLoader]s for a given configuration, while reusing the
+/// [DartSdk] and [Packages] object if possible.
+class DartLoaderBatch {
+  Packages packages;
+  DartSdk dartSdk;
+
+  String lastSdk;
+  String lastPackagePath;
+  bool lastStrongMode;
+
+  Future<DartLoader> getLoader(Repository repository, DartOptions options,
+      {String packageDiscoveryPath}) async {
+    if (dartSdk == null ||
+        lastSdk != options.sdk ||
+        lastStrongMode != options.strongMode) {
+      lastSdk = options.sdk;
+      lastStrongMode = options.strongMode;
+      dartSdk = createDartSdk(options.sdk, strongMode: options.strongModeSdk);
+    }
+    if (packages == null ||
+        lastPackagePath != options.packagePath ||
+        packageDiscoveryPath != null) {
+      lastPackagePath = options.packagePath;
+      packages = await createPackages(options.packagePath,
+          discoveryPath: packageDiscoveryPath);
+    }
+    return new DartLoader(repository, options, packages, dartSdk: dartSdk);
+  }
+}
+
+Future<Packages> createPackages(String packagePath,
+    {String discoveryPath}) async {
+  if (packagePath != null) {
+    var absolutePath = new io.File(packagePath).absolute.path;
+    if (await new io.Directory(packagePath).exists()) {
+      return getPackagesDirectory(new Uri.file(absolutePath));
+    } else if (await new io.File(packagePath).exists()) {
+      return loadPackagesFile(new Uri.file(absolutePath));
+    } else {
+      throw 'Packages not found: $packagePath';
+    }
+  }
+  if (discoveryPath != null) {
+    return findPackagesFromFile(Uri.parse(discoveryPath));
+  }
+  return Packages.noPackages;
+}
+
+AnalysisOptions createAnalysisOptions(bool strongMode) {
+  return new AnalysisOptionsImpl()
+    ..strongMode = strongMode
+    ..generateImplicitErrors = false
+    ..generateSdkErrors = false
+    ..preserveComments = false
+    ..hint = false
+    ..enableSuperMixins = true;
+}
+
+DartSdk createDartSdk(String path, {bool strongMode}) {
+  var resources = PhysicalResourceProvider.INSTANCE;
+  return new FolderBasedDartSdk(resources, resources.getFolder(path))
+    ..context
+        .analysisOptions
+        .setCrossContextOptionsFrom(createAnalysisOptions(strongMode));
+}
+
+class CustomUriResolver extends UriResolver {
+  final ResourceUriResolver _resourceUriResolver;
+  final Map<Uri, Uri> _customUrlMappings;
+
+  CustomUriResolver(this._resourceUriResolver, this._customUrlMappings);
+
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    // TODO(kustermann): Once dartk supports configurable imports we should be
+    // able to get rid of this.
+    if (uri.toString() == 'package:mojo/src/internal_contract.dart') {
+      uri = actualUri = Uri.parse('dart:mojo.internal');
+    }
+
+    Uri baseUri = uri;
+    String relative;
+    String path = uri.path;
+    int index = path.indexOf('/');
+    if (index > 0) {
+      baseUri = uri.replace(path: path.substring(0, index));
+      relative = path.substring(index + 1);
+    }
+    Uri baseMapped = _customUrlMappings[baseUri];
+    if (baseMapped == null) return null;
+
+    Uri mapped = relative != null ? baseMapped.resolve(relative) : baseMapped;
+    return _resourceUriResolver.resolveAbsolute(mapped, actualUri);
+  }
+
+  Uri restoreAbsolute(Source source) {
+    return _resourceUriResolver.restoreAbsolute(source);
+  }
+}
+
+AnalysisContext createContext(DartOptions options, Packages packages,
+    {DartSdk dartSdk}) {
+  dartSdk ??= createDartSdk(options.sdk, strongMode: options.strongModeSdk);
+
+  var resourceProvider = PhysicalResourceProvider.INSTANCE;
+  var resourceUriResolver = new ResourceUriResolver(resourceProvider);
+  List<UriResolver> resolvers = [];
+  var customUriMappings = options.customUriMappings;
+  if (customUriMappings != null && customUriMappings.length > 0) {
+    resolvers
+        .add(new CustomUriResolver(resourceUriResolver, customUriMappings));
+  }
+  resolvers.add(new DartUriResolver(dartSdk));
+  resolvers.add(resourceUriResolver);
+
+  if (packages != null) {
+    var folderMap = <String, List<Folder>>{};
+    packages.asMap().forEach((String packagePath, Uri uri) {
+      String path = resourceProvider.pathContext.fromUri(uri);
+      folderMap[packagePath] = [resourceProvider.getFolder(path)];
+    });
+    resolvers.add(new PackageMapUriResolver(resourceProvider, folderMap));
+  }
+
+  AnalysisContext context = AnalysisEngine.instance.createAnalysisContext()
+    ..sourceFactory = new SourceFactory(resolvers)
+    ..analysisOptions = createAnalysisOptions(options.strongMode);
+
+  options.declaredVariables.forEach((String name, String value) {
+    context.declaredVariables.define(name, value);
+  });
+
+  return context;
+}
diff --git a/pkg/kernel/lib/analyzer/readme.md b/pkg/kernel/lib/analyzer/readme.md
new file mode 100644
index 0000000..5c49769
--- /dev/null
+++ b/pkg/kernel/lib/analyzer/readme.md
@@ -0,0 +1 @@
+A frontend using the Dart analyzer.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
new file mode 100644
index 0000000..0cece08
--- /dev/null
+++ b/pkg/kernel/lib/ast.dart
@@ -0,0 +1,3651 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// -----------------------------------------------------------------------
+///                           ERROR HANDLING
+/// -----------------------------------------------------------------------
+///
+/// As a rule of thumb, errors that can be detected statically are handled by
+/// the frontend, typically by translating the erroneous code into a 'throw' or
+/// a call to 'noSuchMethod'.
+///
+/// For example, there are no arity mismatches in static invocations, and
+/// there are no direct invocations of a constructor on a abstract class.
+///
+/// -----------------------------------------------------------------------
+///                           STATIC vs TOP-LEVEL
+/// -----------------------------------------------------------------------
+///
+/// The term `static` includes both static class members and top-level members.
+///
+/// "Static class member" is the preferred term for non-top level statics.
+///
+/// Static class members are not lifted to the library level because mirrors
+/// and stack traces can observe that they are class members.
+///
+/// -----------------------------------------------------------------------
+///                                 PROCEDURES
+/// -----------------------------------------------------------------------
+///
+/// "Procedure" is an umbrella term for method, getter, setter, index-getter,
+/// index-setter, operator overloader, and factory constructor.
+///
+/// Generative constructors, field initializers, local functions are NOT
+/// procedures.
+///
+/// -----------------------------------------------------------------------
+///                               TRANSFORMATIONS
+/// -----------------------------------------------------------------------
+///
+/// AST transformations can be performed using [TreeNode.replaceWith] or the
+/// [Transformer] visitor class.
+///
+/// Use [Transformer] for bulk transformations that are likely to transform lots
+/// of nodes, and [TreeNode.replaceWith] for sparse transformations that mutate
+/// relatively few nodes.  Or use whichever is more convenient.
+///
+/// The AST can also be mutated by direct field manipulation, but the user then
+/// has to update parent pointers manually.
+///
+library kernel.ast;
+
+import 'visitor.dart';
+export 'visitor.dart';
+
+import 'type_propagation/type_propagation.dart';
+export 'type_propagation/type_propagation.dart';
+
+import 'transformations/flags.dart';
+import 'text/ast_to_text.dart';
+import 'type_algebra.dart';
+import 'type_environment.dart';
+
+/// Any type of node in the IR.
+abstract class Node {
+  const Node();
+
+  accept(Visitor v);
+  visitChildren(Visitor v);
+
+  /// Returns the textual representation of this node for use in debugging.
+  ///
+  /// [toString] should only be used for debugging and short-running test tools
+  /// as it can cause serious memory leaks.
+  ///
+  /// Synthetic names are cached globally to retain consistency across different
+  /// [toString] calls (hence the memory leak).
+  ///
+  /// Nodes that are named, such as [Class] and [Member], return their
+  /// (possibly synthesized) name, whereas other AST nodes return the complete
+  /// textual representation of their subtree.
+  String toString() => debugNodeToString(this);
+}
+
+/// A mutable AST node with a parent pointer.
+///
+/// This is anything other than [Name] and [DartType] nodes.
+abstract class TreeNode extends Node {
+  static int _hashCounter = 0;
+  final int hashCode = _hashCounter = (_hashCounter + 1) & 0x3fffffff;
+  static const int noOffset = -1;
+
+  TreeNode parent;
+
+  /// Offset in the source file it comes from. Valid values are from 0 and up,
+  /// or -1 ([noOffset]) if the file offset is not available
+  /// (this is the default if none is specifically set).
+  int fileOffset = noOffset;
+
+  accept(TreeVisitor v);
+  visitChildren(Visitor v);
+  transformChildren(Transformer v);
+
+  /// Replaces [child] with [replacement].
+  ///
+  /// The caller is responsible for ensuring that the AST remains a tree.  In
+  /// particular, [replacement] should be an orphan or be part of an orphaned
+  /// subtree.
+  ///
+  /// Has no effect if [child] is not actually a child of this node.
+  ///
+  /// If [replacement] is `null`, this will [remove] the [child] node.
+  void replaceChild(TreeNode child, TreeNode replacement) {
+    transformChildren(new _ChildReplacer(child, replacement));
+  }
+
+  /// Inserts another node in place of this one.
+  ///
+  /// The caller is responsible for ensuring that the AST remains a tree.  In
+  /// particular, [replacement] should be an orphan or be part of an orphaned
+  /// subtree.
+  ///
+  /// If [replacement] is `null`, this will [remove] the node.
+  void replaceWith(TreeNode replacement) {
+    parent.replaceChild(this, replacement);
+    parent = null;
+  }
+
+  /// Removes this node from the [List] it is currently stored in, or assigns
+  /// `null` to the field on the parent currently pointing to the node.
+  ///
+  /// Has no effect if the node is orphaned or if the parent pointer is stale.
+  void remove() {
+    parent?.replaceChild(this, null);
+    parent = null;
+  }
+
+  Program get enclosingProgram => parent?.enclosingProgram;
+
+  /// Returns the best known source location of the given AST node, or `null` if
+  /// the node is orphaned.
+  ///
+  /// This getter is intended for diagnostics and debugging, and should be
+  /// avoided in production code.
+  Location get location {
+    if (fileOffset == noOffset) return parent?.location;
+    return _getLocationInEnclosingFile(fileOffset);
+  }
+
+  Location _getLocationInEnclosingFile(int offset) {
+    return parent?._getLocationInEnclosingFile(offset);
+  }
+}
+
+// ------------------------------------------------------------------------
+//                      LIBRARIES and CLASSES
+// ------------------------------------------------------------------------
+
+class Library extends TreeNode implements Comparable<Library> {
+  /// An absolute import path to this library.
+  ///
+  /// The [Uri] should have the `dart`, `package`, or `file` scheme.
+  Uri importUri;
+
+  /// The uri of the source file this library was loaded from.
+  String fileUri;
+
+  /// If true, the library is part of another build unit and its contents
+  /// are only partially loaded.
+  ///
+  /// Classes of an external library are loaded at one of the [ClassLevel]s
+  /// other than [ClassLevel.Body].  Members in an external library have no
+  /// body, but have their typed interface present.
+  ///
+  /// If the libary is non-external, then its classes are at [ClassLevel.Body]
+  /// and all members are loaded.
+  bool isExternal;
+
+  String name;
+  final List<Class> classes;
+  final List<Procedure> procedures;
+  final List<Field> fields;
+
+  Library(this.importUri,
+      {this.name,
+      this.isExternal: false,
+      List<Class> classes,
+      List<Procedure> procedures,
+      List<Field> fields})
+      : this.classes = classes ?? <Class>[],
+        this.procedures = procedures ?? <Procedure>[],
+        this.fields = fields ?? <Field>[] {
+    setParents(this.classes, this);
+    setParents(this.procedures, this);
+    setParents(this.fields, this);
+  }
+
+  /// Returns the top-level fields and procedures defined in this library.
+  ///
+  /// This getter is for convenience, not efficiency.  Consider manually
+  /// iterating the members to speed up code in production.
+  Iterable<Member> get members =>
+      <Iterable<Member>>[fields, procedures].expand((x) => x);
+
+  void addMember(Member member) {
+    member.parent = this;
+    if (member is Procedure) {
+      procedures.add(member);
+    } else if (member is Field) {
+      fields.add(member);
+    } else {
+      throw new ArgumentError(member);
+    }
+  }
+
+  void addClass(Class class_) {
+    class_.parent = this;
+    classes.add(class_);
+  }
+
+  accept(TreeVisitor v) => v.visitLibrary(this);
+
+  visitChildren(Visitor v) {
+    visitList(classes, v);
+    visitList(procedures, v);
+    visitList(fields, v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(classes, v, this);
+    transformList(procedures, v, this);
+    transformList(fields, v, this);
+  }
+
+  static int _libraryIdCounter = 0;
+  int _libraryId = ++_libraryIdCounter;
+
+  int compareTo(Library other) => _libraryId - other._libraryId;
+
+  /// Returns a possibly synthesized name for this library, consistent with
+  /// the names across all [toString] calls.
+  String toString() => debugLibraryName(this);
+
+  Location _getLocationInEnclosingFile(int offset) {
+    return enclosingProgram.getLocation(fileUri, offset);
+  }
+}
+
+/// The degree to which the contents of a class have been loaded into memory.
+///
+/// Each level imply the requirements of the previous ones.
+enum ClassLevel {
+  /// Temporary loading level for internal use by IR producers.  Consumers of
+  /// kernel code should not expect to see classes at this level.
+  Temporary,
+
+  /// The class may be used as a type, and it may contain members that are
+  /// referenced from this build unit.
+  ///
+  /// The type parameters and their bounds are present.
+  ///
+  /// There is no guarantee that all members are present.
+  ///
+  /// All supertypes of this class are at [Type] level or higher.
+  Type,
+
+  /// All instance members of the class are present.
+  ///
+  /// All supertypes of this class are at [Hierarchy] level or higher.
+  ///
+  /// This level exists so supertypes of a fully loaded class contain all the
+  /// members needed to detect override constraints.
+  Hierarchy,
+
+  /// All members of the class are fully loaded and are in the correct order.
+  ///
+  /// Annotations are present on classes and members.
+  ///
+  /// All supertypes of this class are at [Hierarchy] level or higher,
+  /// not necessarily at [Body] level.
+  Body,
+}
+
+/// Declaration of a regular class or a mixin application.
+///
+/// Mixin applications may not contain fields or procedures, as they implicitly
+/// use those from its mixed-in type.  However, the IR does not enforce this
+/// rule directly, as doing so can obstruct transformations.  It is possible to
+/// transform a mixin application to become a regular class, and vice versa.
+class Class extends TreeNode {
+  /// The degree to which the contents of the class have been loaded.
+  ClassLevel level = ClassLevel.Body;
+
+  /// List of metadata annotations on the class.
+  ///
+  /// This defaults to an immutable empty list. Use [addAnnotation] to add
+  /// annotations if needed.
+  List<Expression> annotations = const <Expression>[];
+
+  /// Name of the class.
+  ///
+  /// Must be non-null and must be unique within the library.
+  ///
+  /// The name may contain characters that are not valid in a Dart identifier,
+  /// in particular, the symbol '&' is used in class names generated for mixin
+  /// applications.
+  String name;
+  bool isAbstract;
+
+  /// The uri of the source file this class was loaded from.
+  String fileUri;
+
+  final List<TypeParameter> typeParameters;
+
+  /// The immediate super type, or `null` if this is the root class.
+  Supertype supertype;
+
+  /// The mixed-in type if this is a mixin application, otherwise `null`.
+  Supertype mixedInType;
+
+  /// The types from the `implements` clause.
+  final List<Supertype> implementedTypes;
+
+  /// Fields declared in the class.
+  ///
+  /// For mixin applications this should be empty.
+  final List<Field> fields;
+
+  /// Constructors declared in the class.
+  final List<Constructor> constructors;
+
+  /// Procedures declared in the class.
+  ///
+  /// For mixin applications this should be empty.
+  final List<Procedure> procedures;
+
+  Class(
+      {this.name,
+      this.isAbstract: false,
+      this.supertype,
+      this.mixedInType,
+      List<TypeParameter> typeParameters,
+      List<InterfaceType> implementedTypes,
+      List<Constructor> constructors,
+      List<Procedure> procedures,
+      List<Field> fields,
+      this.fileUri})
+      : this.typeParameters = typeParameters ?? <TypeParameter>[],
+        this.implementedTypes = implementedTypes ?? <Supertype>[],
+        this.fields = fields ?? <Field>[],
+        this.constructors = constructors ?? <Constructor>[],
+        this.procedures = procedures ?? <Procedure>[] {
+    setParents(this.typeParameters, this);
+    setParents(this.constructors, this);
+    setParents(this.procedures, this);
+    setParents(this.fields, this);
+  }
+
+  /// The immediate super class, or `null` if this is the root class.
+  Class get superclass => supertype?.classNode;
+
+  /// The mixed-in class if this is a mixin application, otherwise `null`.
+  ///
+  /// Note that this may itself be a mixin application.  Use [mixin] to get the
+  /// class that has the fields and procedures.
+  Class get mixedInClass => mixedInType?.classNode;
+
+  /// The class that declares the field and procedures of this class.
+  Class get mixin => mixedInClass?.mixin ?? this;
+
+  bool get isMixinApplication => mixedInType != null;
+
+  /// Members declared in this class.
+  ///
+  /// This getter is for convenience, not efficiency.  Consider manually
+  /// iterating the members to speed up code in production.
+  Iterable<Member> get members =>
+      <Iterable<Member>>[fields, constructors, procedures].expand((x) => x);
+
+  /// The immediately extended, mixed-in, and implemented types.
+  ///
+  /// This getter is for convenience, not efficiency.  Consider manually
+  /// iterating the super types to speed up code in production.
+  Iterable<Supertype> get supers => <Iterable<Supertype>>[
+        supertype == null ? const [] : [supertype],
+        mixedInType == null ? const [] : [mixedInType],
+        implementedTypes
+      ].expand((x) => x);
+
+  /// The library containing this class.
+  Library get enclosingLibrary => parent;
+
+  /// Adds a member to this class.
+  ///
+  /// Throws an error if attempting to add a field or procedure to a mixin
+  /// application.
+  void addMember(Member member) {
+    member.parent = this;
+    if (member is Constructor) {
+      constructors.add(member);
+    } else if (member is Procedure) {
+      procedures.add(member);
+    } else if (member is Field) {
+      fields.add(member);
+    } else {
+      throw new ArgumentError(member);
+    }
+  }
+
+  void addAnnotation(Expression node) {
+    if (annotations.isEmpty) {
+      annotations = <Expression>[];
+    }
+    annotations.add(node);
+    node.parent = this;
+  }
+
+  accept(TreeVisitor v) => v.visitClass(this);
+  acceptReference(Visitor v) => v.visitClassReference(this);
+
+  /// If true, the class is part of an external library, that is, it is defined
+  /// in another build unit.  Only a subset of its members are present.
+  ///
+  /// These classes should be loaded at either [ClassLevel.Type] or
+  /// [ClassLevel.Hierarchy] level.
+  bool get isInExternalLibrary => enclosingLibrary.isExternal;
+
+  Supertype get asRawSupertype {
+    return new Supertype(this,
+        new List<DartType>.filled(typeParameters.length, const DynamicType()));
+  }
+
+  Supertype get asThisSupertype {
+    return new Supertype(this, _getAsTypeArguments(typeParameters));
+  }
+
+  InterfaceType _rawType;
+  InterfaceType get rawType => _rawType ??= new InterfaceType(this);
+
+  InterfaceType _thisType;
+  InterfaceType get thisType {
+    return _thisType ??=
+        new InterfaceType(this, _getAsTypeArguments(typeParameters));
+  }
+
+  InterfaceType _bottomType;
+  InterfaceType get bottomType {
+    return _bottomType ??= new InterfaceType(this,
+        new List<DartType>.filled(typeParameters.length, const BottomType()));
+  }
+
+  /// Returns a possibly synthesized name for this class, consistent with
+  /// the names used across all [toString] calls.
+  String toString() => debugQualifiedClassName(this);
+
+  visitChildren(Visitor v) {
+    visitList(annotations, v);
+    visitList(typeParameters, v);
+    supertype?.accept(v);
+    mixedInType?.accept(v);
+    visitList(implementedTypes, v);
+    visitList(constructors, v);
+    visitList(procedures, v);
+    visitList(fields, v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(annotations, v, this);
+    transformList(typeParameters, v, this);
+    if (supertype != null) {
+      supertype = v.visitSupertype(supertype);
+    }
+    if (mixedInType != null) {
+      mixedInType = v.visitSupertype(mixedInType);
+    }
+    transformSupertypeList(implementedTypes, v);
+    transformList(constructors, v, this);
+    transformList(procedures, v, this);
+    transformList(fields, v, this);
+  }
+
+  Location _getLocationInEnclosingFile(int offset) {
+    return enclosingProgram.getLocation(fileUri, offset);
+  }
+}
+
+// ------------------------------------------------------------------------
+//                            MEMBERS
+// ------------------------------------------------------------------------
+
+/// A indirect reference to a member, which can be updated to point at another
+/// member at a later time.
+class _MemberAccessor {
+  Member target;
+  _MemberAccessor(this.target);
+}
+
+abstract class Member extends TreeNode {
+  /// List of metadata annotations on the member.
+  ///
+  /// This defaults to an immutable empty list. Use [addAnnotation] to add
+  /// annotations if needed.
+  List<Expression> annotations = const <Expression>[];
+  Name name;
+
+  /// Flags summarizing the kinds of AST nodes contained in this member, for
+  /// speeding up transformations that only affect certain types of nodes.
+  ///
+  /// See [TransformerFlag] for the meaning of each bit.
+  ///
+  /// These should not be used for any purpose other than skipping certain
+  /// members if it can be determined that no work is needed in there.
+  ///
+  /// It is valid for these flags to be false positives in rare cases, so
+  /// transformers must tolerate the case where a flag is spuriously set.
+  ///
+  /// This value is not serialized; it is populated by the frontend and the
+  /// deserializer.
+  //
+  // TODO(asgerf): It might be worthwhile to put this on classes as well.
+  int transformerFlags = 0;
+
+  Member(this.name);
+
+  Class get enclosingClass => parent is Class ? parent : null;
+  Library get enclosingLibrary => parent is Class ? parent.parent : parent;
+
+  accept(MemberVisitor v);
+  acceptReference(MemberReferenceVisitor v);
+
+  /// If true, the member is part of an external library, that is, it is defined
+  /// in another build unit.  Such members have no body or initializer present
+  /// in the IR.
+  bool get isInExternalLibrary => enclosingLibrary.isExternal;
+
+  /// Returns true if this is an abstract procedure.
+  bool get isAbstract => false;
+
+  /// True if this is a field or non-setter procedure.
+  ///
+  /// Note that operators and factories return `true`, even though there are
+  /// normally no calls to their getter.
+  bool get hasGetter;
+
+  /// True if this is a setter or a mutable field.
+  bool get hasSetter;
+
+  /// True if this is a non-static field or procedure.
+  bool get isInstanceMember;
+
+  /// True if the member has the `external` modifier, implying that the
+  /// implementation is provided by the backend, and is not necessarily written
+  /// in Dart.
+  ///
+  /// Members can have this modifier independently of whether the enclosing
+  /// library is external.
+  bool get isExternal;
+  void set isExternal(bool value);
+
+  /// The body of the procedure or constructor, or `null` if this is a field.
+  FunctionNode get function => null;
+
+  /// Returns a possibly synthesized name for this member, consistent with
+  /// the names used across all [toString] calls.
+  String toString() => debugQualifiedMemberName(this);
+
+  void addAnnotation(Expression node) {
+    if (annotations.isEmpty) {
+      annotations = <Expression>[];
+    }
+    annotations.add(node);
+    node.parent = this;
+  }
+
+  DartType get getterType;
+  DartType get setterType;
+
+  bool get containsSuperCalls {
+    return transformerFlags & TransformerFlag.superCalls != 0;
+  }
+
+  _MemberAccessor get _getterInterface;
+  _MemberAccessor get _setterInterface;
+}
+
+/// A field declaration.
+///
+/// The implied getter and setter for the field are not represented explicitly,
+/// but can be made explicit if needed.
+class Field extends Member {
+  _MemberAccessor _getterInterface, _setterInterface;
+
+  DartType type; // Not null. Defaults to DynamicType.
+  InferredValue inferredValue; // May be null.
+  int flags = 0;
+  Expression initializer; // May be null.
+
+  /// The uri of the source file this field was loaded from.
+  String fileUri;
+
+  Field(Name name,
+      {this.type: const DynamicType(),
+      this.inferredValue,
+      this.initializer,
+      bool isFinal: false,
+      bool isConst: false,
+      bool isStatic: false,
+      bool hasImplicitGetter,
+      bool hasImplicitSetter,
+      int transformerFlags: 0,
+      this.fileUri})
+      : super(name) {
+    _getterInterface = new _MemberAccessor(this);
+    _setterInterface = new _MemberAccessor(this);
+    assert(type != null);
+    initializer?.parent = this;
+    this.isFinal = isFinal;
+    this.isConst = isConst;
+    this.isStatic = isStatic;
+    this.hasImplicitGetter = hasImplicitGetter ?? !isStatic;
+    this.hasImplicitSetter = hasImplicitSetter ?? (!isStatic && !isFinal);
+    this.transformerFlags = transformerFlags;
+  }
+
+  static const int FlagFinal = 1 << 0; // Must match serialized bit positions.
+  static const int FlagConst = 1 << 1;
+  static const int FlagStatic = 1 << 2;
+  static const int FlagHasImplicitGetter = 1 << 3;
+  static const int FlagHasImplicitSetter = 1 << 4;
+
+  bool get isFinal => flags & FlagFinal != 0;
+  bool get isConst => flags & FlagConst != 0;
+  bool get isStatic => flags & FlagStatic != 0;
+
+  /// If true, a getter should be generated for this field.
+  ///
+  /// If false, there may or may not exist an explicit getter in the same class
+  /// with the same name as the field.
+  ///
+  /// By default, all non-static fields have implicit getters.
+  bool get hasImplicitGetter => flags & FlagHasImplicitGetter != 0;
+
+  /// If true, a setter should be generated for this field.
+  ///
+  /// If false, there may or may not exist an explicit setter in the same class
+  /// with the same name as the field.
+  ///
+  /// Final fields never have implicit setters, but a field without an implicit
+  /// setter is not necessarily final, as it may be mutated by direct field
+  /// access.
+  ///
+  /// By default, all non-static, non-final fields have implicit getters.
+  bool get hasImplicitSetter => flags & FlagHasImplicitSetter != 0;
+
+  void set isFinal(bool value) {
+    flags = value ? (flags | FlagFinal) : (flags & ~FlagFinal);
+  }
+
+  void set isConst(bool value) {
+    flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
+  }
+
+  void set isStatic(bool value) {
+    flags = value ? (flags | FlagStatic) : (flags & ~FlagStatic);
+  }
+
+  void set hasImplicitGetter(bool value) {
+    flags = value
+        ? (flags | FlagHasImplicitGetter)
+        : (flags & ~FlagHasImplicitGetter);
+  }
+
+  void set hasImplicitSetter(bool value) {
+    flags = value
+        ? (flags | FlagHasImplicitSetter)
+        : (flags & ~FlagHasImplicitSetter);
+  }
+
+  /// True if the field is neither final nor const.
+  bool get isMutable => flags & (FlagFinal | FlagConst) == 0;
+  bool get isInstanceMember => !isStatic;
+  bool get hasGetter => true;
+  bool get hasSetter => isMutable;
+
+  bool get isExternal => false;
+  void set isExternal(bool value) {
+    if (value) throw 'Fields cannot be external';
+  }
+
+  accept(MemberVisitor v) => v.visitField(this);
+
+  acceptReference(MemberReferenceVisitor v) => v.visitFieldReference(this);
+
+  visitChildren(Visitor v) {
+    visitList(annotations, v);
+    type?.accept(v);
+    inferredValue?.accept(v);
+    name?.accept(v);
+    initializer?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    type = v.visitDartType(type);
+    transformList(annotations, v, this);
+    if (initializer != null) {
+      initializer = initializer.accept(v);
+      initializer?.parent = this;
+    }
+  }
+
+  DartType get getterType => type;
+  DartType get setterType => isMutable ? type : const BottomType();
+
+  /// Makes all [PropertyGet]s that have this field as its interface target
+  /// use [getter] as its interface target instead.
+  ///
+  /// That can be used to introduce an explicit getter for a field instead of
+  /// its implicit getter.
+  ///
+  /// This method only updates the stored interface target -- the caller must
+  /// ensure that [getter] actually becomes the target for dispatches that
+  /// would previously hit the implicit field getter.
+  ///
+  /// [DirectPropertyGet]s are not affected, and will continue to access the
+  /// field directly. [PropertyGet] nodes created after the call will not be
+  /// affected until the method is called again.
+  ///
+  /// Existing [ClassHierarchy] instances are not affected by this call.
+  void replaceGetterInterfaceWith(Procedure getter) {
+    _getterInterface.target = getter;
+    _getterInterface = new _MemberAccessor(this);
+  }
+
+  /// Makes all [PropertySet]s that have this field as its interface target
+  /// use [setter] as its interface target instead.
+  ///
+  /// That can be used to introduce an explicit setter for a field instead of
+  /// its implicit setter.
+  ///
+  /// This method only updates the stored interface target -- the caller must
+  /// ensure that [setter] actually becomes the target for dispatches that
+  /// would previously hit the implicit field setter.
+  ///
+  /// [DirectPropertySet] and [FieldInitializer]s are not affected, and will
+  /// continue to access the field directly.  [PropertySet] nodes created after
+  /// the call will not be affected until the method is called again.
+  ///
+  /// Existing [ClassHierarchy] instances are not affected by this call.
+  void replaceSetterInterfaceWith(Procedure setter) {
+    _setterInterface.target = setter;
+    _setterInterface = new _MemberAccessor(this);
+  }
+
+  Location _getLocationInEnclosingFile(int offset) {
+    return enclosingProgram.getLocation(fileUri, offset);
+  }
+}
+
+/// A generative constructor, possibly redirecting.
+///
+/// Note that factory constructors are treated as [Procedure]s.
+///
+/// Constructors do not take type parameters.  Type arguments from a constructor
+/// invocation should be matched with the type parameters declared in the class.
+///
+/// For unnamed constructors, the name is an empty string (in a [Name]).
+class Constructor extends Member {
+  int flags = 0;
+  FunctionNode function;
+  List<Initializer> initializers;
+
+  Constructor(this.function,
+      {Name name,
+      bool isConst: false,
+      bool isExternal: false,
+      List<Initializer> initializers,
+      int transformerFlags: 0})
+      : this.initializers = initializers ?? <Initializer>[],
+        super(name) {
+    function?.parent = this;
+    setParents(this.initializers, this);
+    this.isConst = isConst;
+    this.isExternal = isExternal;
+    this.transformerFlags = transformerFlags;
+  }
+
+  static const int FlagConst = 1 << 0; // Must match serialized bit positions.
+  static const int FlagExternal = 1 << 1;
+
+  bool get isConst => flags & FlagConst != 0;
+  bool get isExternal => flags & FlagExternal != 0;
+
+  void set isConst(bool value) {
+    flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
+  }
+
+  void set isExternal(bool value) {
+    flags = value ? (flags | FlagExternal) : (flags & ~FlagExternal);
+  }
+
+  bool get isInstanceMember => false;
+  bool get hasGetter => false;
+  bool get hasSetter => false;
+
+  accept(MemberVisitor v) => v.visitConstructor(this);
+
+  acceptReference(MemberReferenceVisitor v) =>
+      v.visitConstructorReference(this);
+
+  visitChildren(Visitor v) {
+    visitList(annotations, v);
+    name?.accept(v);
+    function?.accept(v);
+    visitList(initializers, v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(annotations, v, this);
+    if (function != null) {
+      function = function.accept(v);
+      function?.parent = this;
+    }
+    transformList(initializers, v, this);
+  }
+
+  DartType get getterType => const BottomType();
+  DartType get setterType => const BottomType();
+
+  _MemberAccessor get _getterInterface {
+    throw 'Constructors cannot be used as getters';
+  }
+
+  _MemberAccessor get _setterInterface {
+    throw 'Constructors cannot be used as setters';
+  }
+}
+
+/// A method, getter, setter, index-getter, index-setter, operator overloader,
+/// or factory.
+///
+/// Procedures can have the static, abstract, and/or external modifier, although
+/// only the static and external modifiers may be used together.
+///
+/// For non-static procedures the name is required for dynamic dispatch.
+/// For external procedures the name is required for identifying the external
+/// implementation.
+///
+/// For methods, getters, and setters the name is just as it was declared.
+/// For setters this does not include a trailing `=`.
+/// For index-getters/setters, this is `[]` and `[]=`.
+/// For operators, this is the token for the operator, e.g. `+` or `==`,
+/// except for the unary minus operator, whose name is `unary-`.
+class Procedure extends Member {
+  _MemberAccessor _reference;
+  ProcedureKind kind;
+  int flags = 0;
+  FunctionNode function; // Body is null if and only if abstract or external.
+
+  /// The uri of the source file this procedure was loaded from.
+  String fileUri;
+
+  Procedure(Name name, this.kind, this.function,
+      {bool isAbstract: false,
+      bool isStatic: false,
+      bool isExternal: false,
+      bool isConst: false,
+      int transformerFlags: 0,
+      this.fileUri})
+      : super(name) {
+    _reference = new _MemberAccessor(this);
+    function?.parent = this;
+    this.isAbstract = isAbstract;
+    this.isStatic = isStatic;
+    this.isExternal = isExternal;
+    this.isConst = isConst;
+    this.transformerFlags = transformerFlags;
+  }
+
+  static const int FlagStatic = 1 << 0; // Must match serialized bit positions.
+  static const int FlagAbstract = 1 << 1;
+  static const int FlagExternal = 1 << 2;
+  static const int FlagConst = 1 << 3; // Only for external const factories.
+
+  bool get isStatic => flags & FlagStatic != 0;
+  bool get isAbstract => flags & FlagAbstract != 0;
+  bool get isExternal => flags & FlagExternal != 0;
+
+  /// True if this has the `const` modifier.  This is only possible for external
+  /// constant factories, such as `String.fromEnvironment`.
+  bool get isConst => flags & FlagConst != 0;
+
+  void set isStatic(bool value) {
+    flags = value ? (flags | FlagStatic) : (flags & ~FlagStatic);
+  }
+
+  void set isAbstract(bool value) {
+    flags = value ? (flags | FlagAbstract) : (flags & ~FlagAbstract);
+  }
+
+  void set isExternal(bool value) {
+    flags = value ? (flags | FlagExternal) : (flags & ~FlagExternal);
+  }
+
+  void set isConst(bool value) {
+    flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
+  }
+
+  bool get isInstanceMember => !isStatic;
+  bool get isGetter => kind == ProcedureKind.Getter;
+  bool get isSetter => kind == ProcedureKind.Setter;
+  bool get isAccessor => isGetter || isSetter;
+  bool get hasGetter => kind != ProcedureKind.Setter;
+  bool get hasSetter => kind == ProcedureKind.Setter;
+
+  accept(MemberVisitor v) => v.visitProcedure(this);
+
+  acceptReference(MemberReferenceVisitor v) => v.visitProcedureReference(this);
+
+  visitChildren(Visitor v) {
+    visitList(annotations, v);
+    name?.accept(v);
+    function?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(annotations, v, this);
+    if (function != null) {
+      function = function.accept(v);
+      function?.parent = this;
+    }
+  }
+
+  DartType get getterType {
+    return isGetter ? function.returnType : function.functionType;
+  }
+
+  DartType get setterType {
+    return isSetter
+        ? function.positionalParameters[0].type
+        : const BottomType();
+  }
+
+  _MemberAccessor get _getterInterface => _reference;
+  _MemberAccessor get _setterInterface => _reference;
+}
+
+enum ProcedureKind {
+  Method,
+  Getter,
+  Setter,
+  Operator,
+  Factory,
+}
+
+// ------------------------------------------------------------------------
+//                     CONSTRUCTOR INITIALIZERS
+// ------------------------------------------------------------------------
+
+/// Part of an initializer list in a constructor.
+abstract class Initializer extends TreeNode {
+  accept(InitializerVisitor v);
+}
+
+/// An initializer with a compile-time error.
+///
+/// Should throw an exception at runtime.
+//
+// DESIGN TODO: The frontend should use this in a lot more cases to catch
+// invalid cases.
+class InvalidInitializer extends Initializer {
+  accept(InitializerVisitor v) => v.visitInvalidInitializer(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+/// A field assignment `field = value` occurring in the initializer list of
+/// a constructor.
+///
+/// This node has nothing to do with declaration-site field initializers; those
+/// are [Expression]s stored in [Field.initializer].
+//
+// TODO: The frontend should check that all final fields are initialized
+//  exactly once, and that no fields are assigned twice in the initializer list.
+class FieldInitializer extends Initializer {
+  /// Reference to the field being initialized.  Not null.
+  Field field;
+  Expression value;
+
+  FieldInitializer(this.field, this.value) {
+    value?.parent = this;
+  }
+
+  accept(InitializerVisitor v) => v.visitFieldInitializer(this);
+
+  visitChildren(Visitor v) {
+    field?.acceptReference(v);
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// A super call `super(x,y)` occurring in the initializer list of a
+/// constructor.
+///
+/// There are no type arguments on this call.
+//
+// TODO: The frontend should check that there is no more than one super call.
+//
+// DESIGN TODO: Consider if the frontend should insert type arguments derived
+// from the extends clause.
+class SuperInitializer extends Initializer {
+  /// Reference to the constructor being invoked in the super class. Not null.
+  Constructor target;
+  Arguments arguments;
+
+  SuperInitializer(this.target, this.arguments) {
+    arguments?.parent = this;
+  }
+
+  accept(InitializerVisitor v) => v.visitSuperInitializer(this);
+
+  visitChildren(Visitor v) {
+    target?.acceptReference(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+}
+
+/// A redirecting call `this(x,y)` occurring in the initializer list of
+/// a constructor.
+//
+// TODO: The frontend should check that this is the only initializer and if the
+// constructor has a body or if there is a cycle in the initializer calls.
+class RedirectingInitializer extends Initializer {
+  /// Reference to the constructor being invoked in the same class. Not null.
+  Constructor target;
+  Arguments arguments;
+
+  RedirectingInitializer(this.target, this.arguments) {
+    arguments?.parent = this;
+  }
+
+  accept(InitializerVisitor v) => v.visitRedirectingInitializer(this);
+
+  visitChildren(Visitor v) {
+    target?.acceptReference(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+}
+
+/// Binding of a temporary variable in the initializer list of a constructor.
+///
+/// The variable is in scope for the remainder of the initializer list, but is
+/// not in scope in the constructor body.
+class LocalInitializer extends Initializer {
+  VariableDeclaration variable;
+
+  LocalInitializer(this.variable) {
+    variable?.parent = this;
+  }
+
+  accept(InitializerVisitor v) => v.visitLocalInitializer(this);
+
+  visitChildren(Visitor v) {
+    variable?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (variable != null) {
+      variable = variable.accept(v);
+      variable?.parent = this;
+    }
+  }
+}
+
+// ------------------------------------------------------------------------
+//                            FUNCTIONS
+// ------------------------------------------------------------------------
+
+/// A function declares parameters and has a body.
+///
+/// This may occur in a procedure, constructor, function expression, or local
+/// function declaration.
+class FunctionNode extends TreeNode {
+  AsyncMarker asyncMarker;
+  List<TypeParameter> typeParameters;
+  int requiredParameterCount;
+  List<VariableDeclaration> positionalParameters;
+  List<VariableDeclaration> namedParameters;
+  InferredValue inferredReturnValue; // May be null.
+  DartType returnType; // Not null.
+  Statement body;
+
+  FunctionNode(this.body,
+      {List<TypeParameter> typeParameters,
+      List<VariableDeclaration> positionalParameters,
+      List<VariableDeclaration> namedParameters,
+      int requiredParameterCount,
+      this.returnType: const DynamicType(),
+      this.inferredReturnValue,
+      this.asyncMarker: AsyncMarker.Sync})
+      : this.positionalParameters =
+            positionalParameters ?? <VariableDeclaration>[],
+        this.requiredParameterCount =
+            requiredParameterCount ?? positionalParameters?.length ?? 0,
+        this.namedParameters = namedParameters ?? <VariableDeclaration>[],
+        this.typeParameters = typeParameters ?? <TypeParameter>[] {
+    assert(returnType != null);
+    setParents(this.typeParameters, this);
+    setParents(this.positionalParameters, this);
+    setParents(this.namedParameters, this);
+    body?.parent = this;
+  }
+
+  static DartType _getTypeOfVariable(VariableDeclaration node) => node.type;
+
+  static NamedType _getNamedTypeOfVariable(VariableDeclaration node) {
+    return new NamedType(node.name, node.type);
+  }
+
+  FunctionType get functionType {
+    TreeNode parent = this.parent;
+    List<NamedType> named =
+        namedParameters.map(_getNamedTypeOfVariable).toList(growable: false);
+    named.sort();
+    return new FunctionType(
+        positionalParameters.map(_getTypeOfVariable).toList(growable: false),
+        returnType,
+        namedParameters: named,
+        typeParameters: parent is Constructor
+            ? parent.enclosingClass.typeParameters
+            : typeParameters,
+        requiredParameterCount: requiredParameterCount);
+  }
+
+  accept(TreeVisitor v) => v.visitFunctionNode(this);
+
+  visitChildren(Visitor v) {
+    visitList(typeParameters, v);
+    visitList(positionalParameters, v);
+    visitList(namedParameters, v);
+    returnType?.accept(v);
+    inferredReturnValue?.accept(v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(typeParameters, v, this);
+    transformList(positionalParameters, v, this);
+    transformList(namedParameters, v, this);
+    returnType = v.visitDartType(returnType);
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+enum AsyncMarker {
+  // Do not change the order of these, the frontends depend on it.
+  Sync,
+  SyncStar,
+  Async,
+  AsyncStar,
+
+  // `SyncYielding` is a marker that tells Dart VM that this function is an
+  // artificial closure introduced by an async transformer which desugared all
+  // async syntax into a combination of native yields and helper method calls.
+  //
+  // Native yields (formatted as `[yield]`) are semantically close to
+  // `yield x` statement: they denote a yield/resume point within a function
+  // but are completely decoupled from the notion of iterators. When
+  // execution of the closure reaches `[yield] x` it stops and return the
+  // value of `x` to the caller. If closure is called again it continues
+  // to the next statement after this yield as if it was suspended and resumed.
+  //
+  // Consider this example:
+  //
+  //   g() {
+  //     var :await_jump_var = 0;
+  //     var :await_ctx_var;
+  //
+  //     f(x) yielding {
+  //       [yield] '${x}:0';
+  //       [yield] '${x}:1';
+  //       [yield] '${x}:2';
+  //     }
+  //
+  //     return f;
+  //   }
+  //
+  //   print(f('a'));  /* prints 'a:0', :await_jump_var = 1  */
+  //   print(f('b'));  /* prints 'b:1', :await_jump_var = 2  */
+  //   print(f('c'));  /* prints 'c:2', :await_jump_var = 3  */
+  //
+  // Note: currently Dart VM implicitly relies on async transformer to
+  // inject certain artificial variables into g (like `:await_jump_var`).
+  // As such SyncYielding and native yield are not intended to be used on their
+  // own, but are rather an implementation artifact of the async transformer
+  // itself.
+  SyncYielding,
+}
+
+// ------------------------------------------------------------------------
+//                                EXPRESSIONS
+// ------------------------------------------------------------------------
+
+abstract class Expression extends TreeNode {
+  /// Returns the static type of the expression.
+  ///
+  /// Should only be used on code compiled in strong mode, as this method
+  /// assumes the IR is strongly typed.
+  DartType getStaticType(TypeEnvironment types);
+
+  /// Returns the static type of the expression as an instantiation of
+  /// [superclass].
+  ///
+  /// Should only be used on code compiled in strong mode, as this method
+  /// assumes the IR is strongly typed.
+  ///
+  /// This method futhermore assumes that the type of the expression actually
+  /// is a subtype of (some instantiation of) the given [superclass].
+  /// If this is not the case, either an exception is thrown or the raw type of
+  /// [superclass] is returned.
+  InterfaceType getStaticTypeAsInstanceOf(
+      Class superclass, TypeEnvironment types) {
+    // This method assumes the program is correctly typed, so if the superclass
+    // is not generic, we can just return its raw type without computing the
+    // type of this expression.  It also ensures that all types are considered
+    // subtypes of Object (not just interface types), and function types are
+    // considered subtypes of Function.
+    if (superclass.typeParameters.isEmpty) {
+      return superclass.rawType;
+    }
+    var type = getStaticType(types);
+    while (type is TypeParameterType) {
+      type = (type as TypeParameterType).parameter.bound;
+    }
+    if (type is InterfaceType) {
+      var upcastType = types.hierarchy.getTypeAsInstanceOf(type, superclass);
+      if (upcastType != null) return upcastType;
+    } else if (type is BottomType) {
+      return superclass.bottomType;
+    }
+    types.typeError(this, '$type is not a subtype of $superclass');
+    return superclass.rawType;
+  }
+
+  accept(ExpressionVisitor v);
+}
+
+/// An expression containing compile-time errors.
+///
+/// Should throw a runtime error when evaluated.
+class InvalidExpression extends Expression {
+  DartType getStaticType(TypeEnvironment types) => const BottomType();
+
+  accept(ExpressionVisitor v) => v.visitInvalidExpression(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+/// Read a local variable, a local function, or a function parameter.
+class VariableGet extends Expression {
+  VariableDeclaration variable;
+  DartType promotedType; // Null if not promoted.
+
+  VariableGet(this.variable, [this.promotedType]);
+
+  DartType getStaticType(TypeEnvironment types) {
+    return promotedType ?? variable.type;
+  }
+
+  accept(ExpressionVisitor v) => v.visitVariableGet(this);
+
+  visitChildren(Visitor v) {
+    promotedType?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (promotedType != null) {
+      promotedType = v.visitDartType(promotedType);
+    }
+  }
+}
+
+/// Assign a local variable or function parameter.
+///
+/// Evaluates to the value of [value].
+class VariableSet extends Expression {
+  VariableDeclaration variable;
+  Expression value;
+
+  VariableSet(this.variable, this.value) {
+    value?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
+
+  accept(ExpressionVisitor v) => v.visitVariableSet(this);
+
+  visitChildren(Visitor v) {
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `x.field`.
+///
+/// This may invoke a getter, read a field, or tear off a method.
+class PropertyGet extends Expression {
+  Expression receiver;
+  Name name;
+
+  _MemberAccessor _interfaceTargetReference;
+
+  PropertyGet(this.receiver, this.name, [Member interfaceTarget]) {
+    receiver?.parent = this;
+    this.interfaceTarget = interfaceTarget;
+  }
+
+  Member get interfaceTarget => _interfaceTargetReference?.target;
+
+  void set interfaceTarget(Member newTarget) {
+    _interfaceTargetReference = newTarget?._getterInterface;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    var interfaceTarget = this.interfaceTarget;
+    if (interfaceTarget != null) {
+      Class superclass = interfaceTarget.enclosingClass;
+      var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
+      return Substitution
+          .fromInterfaceType(receiverType)
+          .substituteType(interfaceTarget.getterType);
+    }
+    // Treat the properties of Object specially.
+    String nameString = name.name;
+    if (nameString == 'hashCode') {
+      return types.intType;
+    } else if (nameString == 'runtimeType') {
+      return types.typeType;
+    }
+    return const DynamicType();
+  }
+
+  accept(ExpressionVisitor v) => v.visitPropertyGet(this);
+
+  visitChildren(Visitor v) {
+    receiver?.accept(v);
+    name?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept(v);
+      receiver?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `x.field = value`.
+///
+/// This may invoke a setter or assign a field.
+///
+/// Evaluates to the value of [value].
+class PropertySet extends Expression {
+  Expression receiver;
+  Name name;
+  Expression value;
+
+  _MemberAccessor _interfaceTargetReference;
+
+  PropertySet(this.receiver, this.name, this.value, [Member interfaceTarget]) {
+    receiver?.parent = this;
+    value?.parent = this;
+    this.interfaceTarget = interfaceTarget;
+  }
+
+  Member get interfaceTarget => _interfaceTargetReference?.target;
+
+  void set interfaceTarget(Member newTarget) {
+    _interfaceTargetReference = newTarget?._setterInterface;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
+
+  accept(ExpressionVisitor v) => v.visitPropertySet(this);
+
+  visitChildren(Visitor v) {
+    receiver?.accept(v);
+    name?.accept(v);
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept(v);
+      receiver?.parent = this;
+    }
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// Directly read a field, call a getter, or tear off a method.
+class DirectPropertyGet extends Expression {
+  Expression receiver;
+  Member target;
+
+  DirectPropertyGet(this.receiver, this.target) {
+    receiver?.parent = this;
+  }
+
+  visitChildren(Visitor v) {
+    receiver?.accept(v);
+    target?.acceptReference(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept(v);
+      receiver?.parent = this;
+    }
+  }
+
+  accept(ExpressionVisitor v) => v.visitDirectPropertyGet(this);
+
+  DartType getStaticType(TypeEnvironment types) {
+    Class superclass = target.enclosingClass;
+    var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
+    return Substitution
+        .fromInterfaceType(receiverType)
+        .substituteType(target.getterType);
+  }
+}
+
+/// Directly assign a field, or call a setter.
+///
+/// Evaluates to the value of [value].
+class DirectPropertySet extends Expression {
+  Expression receiver;
+  Member target;
+  Expression value;
+
+  DirectPropertySet(this.receiver, this.target, this.value) {
+    receiver?.parent = this;
+    value?.parent = this;
+  }
+
+  visitChildren(Visitor v) {
+    receiver?.accept(v);
+    target?.acceptReference(v);
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept(v);
+      receiver?.parent = this;
+    }
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+
+  accept(ExpressionVisitor v) => v.visitDirectPropertySet(this);
+
+  DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
+}
+
+/// Directly call an instance method, bypassing ordinary dispatch.
+class DirectMethodInvocation extends Expression {
+  Expression receiver;
+  Procedure target;
+  Arguments arguments;
+
+  DirectMethodInvocation(this.receiver, this.target, this.arguments) {
+    receiver?.parent = this;
+    arguments?.parent = this;
+  }
+
+  visitChildren(Visitor v) {
+    receiver?.accept(v);
+    target?.acceptReference(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept(v);
+      receiver?.parent = this;
+    }
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+
+  accept(ExpressionVisitor v) => v.visitDirectMethodInvocation(this);
+
+  DartType getStaticType(TypeEnvironment types) {
+    if (types.isOverloadedArithmeticOperator(target)) {
+      return types.getTypeOfOverloadedArithmetic(receiver.getStaticType(types),
+          arguments.positional[0].getStaticType(types));
+    }
+    Class superclass = target.enclosingClass;
+    var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
+    var returnType = Substitution
+        .fromInterfaceType(receiverType)
+        .substituteType(target.function.returnType);
+    return Substitution
+        .fromPairs(target.function.typeParameters, arguments.types)
+        .substituteType(returnType);
+  }
+}
+
+/// Expression of form `super.field`.
+///
+/// This may invoke a getter, read a field, or tear off a method.
+class SuperPropertyGet extends Expression {
+  Name name;
+  _MemberAccessor _interfaceTargetReference;
+
+  SuperPropertyGet(this.name, [Member interfaceTarget]) {
+    _interfaceTargetReference = interfaceTarget?._getterInterface;
+  }
+
+  Member get interfaceTarget => _interfaceTargetReference?.target;
+
+  void set interfaceTarget(Member newTarget) {
+    _interfaceTargetReference = newTarget?._getterInterface;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    Class declaringClass = interfaceTarget.enclosingClass;
+    if (declaringClass.typeParameters.isEmpty) {
+      return interfaceTarget.getterType;
+    }
+    var receiver =
+        types.hierarchy.getTypeAsInstanceOf(types.thisType, declaringClass);
+    return Substitution
+        .fromInterfaceType(receiver)
+        .substituteType(interfaceTarget.getterType);
+  }
+
+  accept(ExpressionVisitor v) => v.visitSuperPropertyGet(this);
+
+  visitChildren(Visitor v) {
+    name?.accept(v);
+  }
+
+  transformChildren(Transformer v) {}
+}
+
+/// Expression of form `super.field = value`.
+///
+/// This may invoke a setter or assign a field.
+///
+/// Evaluates to the value of [value].
+class SuperPropertySet extends Expression {
+  Name name;
+  Expression value;
+  _MemberAccessor _interfaceTargetReference;
+
+  SuperPropertySet(this.name, this.value, [Member interfaceTarget]) {
+    value?.parent = this;
+    _interfaceTargetReference = interfaceTarget?._setterInterface;
+  }
+
+  Member get interfaceTarget => _interfaceTargetReference?.target;
+
+  void set interfaceTarget(Member newTarget) {
+    _interfaceTargetReference = newTarget?._setterInterface;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
+
+  accept(ExpressionVisitor v) => v.visitSuperPropertySet(this);
+
+  visitChildren(Visitor v) {
+    name?.accept(v);
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// Read a static field, call a static getter, or tear off a static method.
+class StaticGet extends Expression {
+  /// A static field, getter, or method (for tear-off).
+  Member target;
+
+  StaticGet(this.target);
+
+  DartType getStaticType(TypeEnvironment types) => target.getterType;
+
+  accept(ExpressionVisitor v) => v.visitStaticGet(this);
+
+  visitChildren(Visitor v) {
+    target?.acceptReference(v);
+  }
+
+  transformChildren(Transformer v) {}
+}
+
+/// Assign a static field or call a static setter.
+///
+/// Evaluates to the value of [value].
+class StaticSet extends Expression {
+  /// A mutable static field or a static setter.
+  Member target;
+  Expression value;
+
+  StaticSet(this.target, this.value) {
+    value?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
+
+  accept(ExpressionVisitor v) => v.visitStaticSet(this);
+
+  visitChildren(Visitor v) {
+    target?.acceptReference(v);
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// The arguments to a function call, divided into type arguments,
+/// positional arguments, and named arguments.
+class Arguments extends TreeNode {
+  final List<DartType> types;
+  final List<Expression> positional;
+  final List<NamedExpression> named;
+
+  Arguments(this.positional,
+      {List<DartType> types, List<NamedExpression> named})
+      : this.types = types ?? <DartType>[],
+        this.named = named ?? <NamedExpression>[] {
+    setParents(this.positional, this);
+    setParents(this.named, this);
+  }
+
+  Arguments.empty()
+      : types = <DartType>[],
+        positional = <Expression>[],
+        named = <NamedExpression>[];
+
+  accept(TreeVisitor v) => v.visitArguments(this);
+
+  visitChildren(Visitor v) {
+    visitList(types, v);
+    visitList(positional, v);
+    visitList(named, v);
+  }
+
+  transformChildren(Transformer v) {
+    transformTypeList(types, v);
+    transformList(positional, v, this);
+    transformList(named, v, this);
+  }
+}
+
+/// A named argument, `name: value`.
+class NamedExpression extends TreeNode {
+  String name;
+  Expression value;
+
+  NamedExpression(this.name, this.value) {
+    value?.parent = this;
+  }
+
+  accept(TreeVisitor v) => v.visitNamedExpression(this);
+
+  visitChildren(Visitor v) {
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// Common super class for [MethodInvocation], [SuperMethodInvocation],
+/// [StaticInvocation], and [ConstructorInvocation].
+abstract class InvocationExpression extends Expression {
+  Arguments get arguments;
+  set arguments(Arguments value);
+
+  /// Name of the invoked method.
+  ///
+  /// May be `null` if the target is a synthetic static member without a name.
+  Name get name;
+}
+
+/// Expression of form `x.foo(y)`.
+class MethodInvocation extends InvocationExpression {
+  Expression receiver;
+  Name name;
+  Arguments arguments;
+
+  Procedure interfaceTarget;
+
+  MethodInvocation(this.receiver, this.name, this.arguments,
+      [this.interfaceTarget]) {
+    receiver?.parent = this;
+    arguments?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    if (interfaceTarget != null) {
+      if (types.isOverloadedArithmeticOperator(interfaceTarget)) {
+        return types.getTypeOfOverloadedArithmetic(
+            receiver.getStaticType(types),
+            arguments.positional[0].getStaticType(types));
+      }
+      Class superclass = interfaceTarget.enclosingClass;
+      var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
+      var returnType = Substitution
+          .fromInterfaceType(receiverType)
+          .substituteType(interfaceTarget.function.returnType);
+      return Substitution
+          .fromPairs(interfaceTarget.function.typeParameters, arguments.types)
+          .substituteType(returnType);
+    }
+    if (name.name == 'call') {
+      var receiverType = receiver.getStaticType(types);
+      if (receiverType is FunctionType) {
+        if (receiverType.typeParameters.length != arguments.types.length) {
+          return const BottomType();
+        }
+        return Substitution
+            .fromPairs(receiverType.typeParameters, arguments.types)
+            .substituteType(receiverType.returnType);
+      }
+    }
+    if (name.name == '==') {
+      // We use this special case to simplify generation of '==' checks.
+      return types.boolType;
+    }
+    return const DynamicType();
+  }
+
+  accept(ExpressionVisitor v) => v.visitMethodInvocation(this);
+
+  visitChildren(Visitor v) {
+    receiver?.accept(v);
+    name?.accept(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept(v);
+      receiver?.parent = this;
+    }
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `super.foo(x)`.
+///
+/// The provided arguments might not match the parameters of the target.
+class SuperMethodInvocation extends InvocationExpression {
+  Name name;
+  Arguments arguments;
+
+  Member interfaceTarget;
+
+  SuperMethodInvocation(this.name, this.arguments, this.interfaceTarget) {
+    arguments?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    if (interfaceTarget == null) return const DynamicType();
+    Class superclass = interfaceTarget.enclosingClass;
+    var receiverType =
+        types.hierarchy.getTypeAsInstanceOf(types.thisType, superclass);
+    var returnType = Substitution
+        .fromInterfaceType(receiverType)
+        .substituteType(interfaceTarget.function.returnType);
+    return Substitution
+        .fromPairs(interfaceTarget.function.typeParameters, arguments.types)
+        .substituteType(returnType);
+  }
+
+  accept(ExpressionVisitor v) => v.visitSuperMethodInvocation(this);
+
+  visitChildren(Visitor v) {
+    name?.accept(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `foo(x)`, or `const foo(x)` if the target is an
+/// external constant factory.
+///
+/// The provided arguments might not match the parameters of the target.
+class StaticInvocation extends InvocationExpression {
+  Procedure target;
+  Arguments arguments;
+
+  /// True if this is a constant call to an external constant factory.
+  bool isConst;
+
+  Name get name => target?.name;
+
+  StaticInvocation(this.target, this.arguments, {this.isConst: false}) {
+    arguments?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    return Substitution
+        .fromPairs(target.function.typeParameters, arguments.types)
+        .substituteType(target.function.returnType);
+  }
+
+  accept(ExpressionVisitor v) => v.visitStaticInvocation(this);
+
+  visitChildren(Visitor v) {
+    target?.acceptReference(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `new Foo(x)` or `const Foo(x)`.
+///
+/// The provided arguments might not match the parameters of the target.
+//
+// DESIGN TODO: Should we pass type arguments in a separate field
+// `classTypeArguments`? They are quite different from type arguments to
+// generic functions.
+class ConstructorInvocation extends InvocationExpression {
+  Constructor target;
+  Arguments arguments;
+  bool isConst;
+
+  Name get name => target?.name;
+
+  ConstructorInvocation(this.target, this.arguments, {this.isConst: false}) {
+    arguments?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    return arguments.types.isEmpty
+        ? target.enclosingClass.rawType
+        : new InterfaceType(target.enclosingClass, arguments.types);
+  }
+
+  accept(ExpressionVisitor v) => v.visitConstructorInvocation(this);
+
+  visitChildren(Visitor v) {
+    target?.acceptReference(v);
+    arguments?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (arguments != null) {
+      arguments = arguments.accept(v);
+      arguments?.parent = this;
+    }
+  }
+
+  InterfaceType get constructedType {
+    return arguments.types.isEmpty
+        ? target.enclosingClass.rawType
+        : new InterfaceType(target.enclosingClass, arguments.types);
+  }
+}
+
+/// Expression of form `!x`.
+///
+/// The `is!` and `!=` operators are desugared into [Not] nodes with `is` and
+/// `==` expressions inside, respectively.
+class Not extends Expression {
+  Expression operand;
+
+  Not(this.operand) {
+    operand?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => types.boolType;
+
+  accept(ExpressionVisitor v) => v.visitNot(this);
+
+  visitChildren(Visitor v) {
+    operand?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (operand != null) {
+      operand = operand.accept(v);
+      operand?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `x && y` or `x || y`
+class LogicalExpression extends Expression {
+  Expression left;
+  String operator; // && or || or ??
+  Expression right;
+
+  LogicalExpression(this.left, this.operator, this.right) {
+    left?.parent = this;
+    right?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => types.boolType;
+
+  accept(ExpressionVisitor v) => v.visitLogicalExpression(this);
+
+  visitChildren(Visitor v) {
+    left?.accept(v);
+    right?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (left != null) {
+      left = left.accept(v);
+      left?.parent = this;
+    }
+    if (right != null) {
+      right = right.accept(v);
+      right?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `x ? y : z`.
+class ConditionalExpression extends Expression {
+  Expression condition;
+  Expression then;
+  Expression otherwise;
+
+  /// The static type of the expression. Should not be `null`.
+  DartType staticType;
+
+  ConditionalExpression(
+      this.condition, this.then, this.otherwise, this.staticType) {
+    condition?.parent = this;
+    then?.parent = this;
+    otherwise?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => staticType;
+
+  accept(ExpressionVisitor v) => v.visitConditionalExpression(this);
+
+  visitChildren(Visitor v) {
+    condition?.accept(v);
+    then?.accept(v);
+    otherwise?.accept(v);
+    staticType?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (condition != null) {
+      condition = condition.accept(v);
+      condition?.parent = this;
+    }
+    if (then != null) {
+      then = then.accept(v);
+      then?.parent = this;
+    }
+    if (otherwise != null) {
+      otherwise = otherwise.accept(v);
+      otherwise?.parent = this;
+    }
+    if (staticType != null) {
+      staticType = v.visitDartType(staticType);
+    }
+  }
+}
+
+/// Convert expressions to strings and concatenate them.  Semantically, calls
+/// `toString` on every argument, checks that a string is returned, and returns
+/// the concatenation of all the strings.
+///
+/// If [expressions] is empty then an empty string is returned.
+///
+/// These arise from string interpolations and adjacent string literals.
+class StringConcatenation extends Expression {
+  final List<Expression> expressions;
+
+  StringConcatenation(this.expressions) {
+    setParents(expressions, this);
+  }
+
+  DartType getStaticType(TypeEnvironment types) => types.stringType;
+
+  accept(ExpressionVisitor v) => v.visitStringConcatenation(this);
+
+  visitChildren(Visitor v) {
+    visitList(expressions, v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(expressions, v, this);
+  }
+}
+
+/// Expression of form `x is T`.
+class IsExpression extends Expression {
+  Expression operand;
+  DartType type;
+
+  IsExpression(this.operand, this.type) {
+    operand?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => types.boolType;
+
+  accept(ExpressionVisitor v) => v.visitIsExpression(this);
+
+  visitChildren(Visitor v) {
+    operand?.accept(v);
+    type?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (operand != null) {
+      operand = operand.accept(v);
+      operand?.parent = this;
+    }
+    type = v.visitDartType(type);
+  }
+}
+
+/// Expression of form `x as T`.
+class AsExpression extends Expression {
+  Expression operand;
+  DartType type;
+
+  AsExpression(this.operand, this.type) {
+    operand?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => type;
+
+  accept(ExpressionVisitor v) => v.visitAsExpression(this);
+
+  visitChildren(Visitor v) {
+    operand?.accept(v);
+    type?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (operand != null) {
+      operand = operand.accept(v);
+      operand?.parent = this;
+    }
+    type = v.visitDartType(type);
+  }
+}
+
+/// An integer, double, boolean, string, or null constant.
+abstract class BasicLiteral extends Expression {
+  Object get value;
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class StringLiteral extends BasicLiteral {
+  String value;
+
+  StringLiteral(this.value);
+
+  DartType getStaticType(TypeEnvironment types) => types.stringType;
+
+  accept(ExpressionVisitor v) => v.visitStringLiteral(this);
+}
+
+class IntLiteral extends BasicLiteral {
+  int value;
+
+  IntLiteral(this.value);
+
+  DartType getStaticType(TypeEnvironment types) => types.intType;
+
+  accept(ExpressionVisitor v) => v.visitIntLiteral(this);
+}
+
+class DoubleLiteral extends BasicLiteral {
+  double value;
+
+  DoubleLiteral(this.value);
+
+  DartType getStaticType(TypeEnvironment types) => types.doubleType;
+
+  accept(ExpressionVisitor v) => v.visitDoubleLiteral(this);
+}
+
+class BoolLiteral extends BasicLiteral {
+  bool value;
+
+  BoolLiteral(this.value);
+
+  DartType getStaticType(TypeEnvironment types) => types.boolType;
+
+  accept(ExpressionVisitor v) => v.visitBoolLiteral(this);
+}
+
+class NullLiteral extends BasicLiteral {
+  Object get value => null;
+
+  DartType getStaticType(TypeEnvironment types) => const BottomType();
+
+  accept(ExpressionVisitor v) => v.visitNullLiteral(this);
+}
+
+class SymbolLiteral extends Expression {
+  String value; // Everything strictly after the '#'.
+
+  SymbolLiteral(this.value);
+
+  DartType getStaticType(TypeEnvironment types) => types.symbolType;
+
+  accept(ExpressionVisitor v) => v.visitSymbolLiteral(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class TypeLiteral extends Expression {
+  DartType type;
+
+  TypeLiteral(this.type);
+
+  DartType getStaticType(TypeEnvironment types) => types.typeType;
+
+  accept(ExpressionVisitor v) => v.visitTypeLiteral(this);
+
+  visitChildren(Visitor v) {
+    type?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    type = v.visitDartType(type);
+  }
+}
+
+class ThisExpression extends Expression {
+  DartType getStaticType(TypeEnvironment types) => types.thisType;
+
+  accept(ExpressionVisitor v) => v.visitThisExpression(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class Rethrow extends Expression {
+  DartType getStaticType(TypeEnvironment types) => const BottomType();
+
+  accept(ExpressionVisitor v) => v.visitRethrow(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class Throw extends Expression {
+  Expression expression;
+
+  Throw(this.expression) {
+    expression?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => const BottomType();
+
+  accept(ExpressionVisitor v) => v.visitThrow(this);
+
+  visitChildren(Visitor v) {
+    expression?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (expression != null) {
+      expression = expression.accept(v);
+      expression?.parent = this;
+    }
+  }
+}
+
+class ListLiteral extends Expression {
+  bool isConst;
+  DartType typeArgument; // Not null, defaults to DynamicType.
+  final List<Expression> expressions;
+
+  ListLiteral(this.expressions,
+      {this.typeArgument: const DynamicType(), this.isConst: false}) {
+    assert(typeArgument != null);
+    setParents(expressions, this);
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    return types.literalListType(typeArgument);
+  }
+
+  accept(ExpressionVisitor v) => v.visitListLiteral(this);
+
+  visitChildren(Visitor v) {
+    typeArgument?.accept(v);
+    visitList(expressions, v);
+  }
+
+  transformChildren(Transformer v) {
+    typeArgument = v.visitDartType(typeArgument);
+    transformList(expressions, v, this);
+  }
+}
+
+class MapLiteral extends Expression {
+  bool isConst;
+  DartType keyType; // Not null, defaults to DynamicType.
+  DartType valueType; // Not null, defaults to DynamicType.
+  final List<MapEntry> entries;
+
+  MapLiteral(this.entries,
+      {this.keyType: const DynamicType(),
+      this.valueType: const DynamicType(),
+      this.isConst: false}) {
+    assert(keyType != null);
+    assert(valueType != null);
+    setParents(entries, this);
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    return types.literalMapType(keyType, valueType);
+  }
+
+  accept(ExpressionVisitor v) => v.visitMapLiteral(this);
+
+  visitChildren(Visitor v) {
+    keyType?.accept(v);
+    valueType?.accept(v);
+    visitList(entries, v);
+  }
+
+  transformChildren(Transformer v) {
+    keyType = v.visitDartType(keyType);
+    valueType = v.visitDartType(valueType);
+    transformList(entries, v, this);
+  }
+}
+
+class MapEntry extends TreeNode {
+  Expression key;
+  Expression value;
+
+  MapEntry(this.key, this.value) {
+    key?.parent = this;
+    value?.parent = this;
+  }
+
+  accept(TreeVisitor v) => v.visitMapEntry(this);
+
+  visitChildren(Visitor v) {
+    key?.accept(v);
+    value?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (key != null) {
+      key = key.accept(v);
+      key?.parent = this;
+    }
+    if (value != null) {
+      value = value.accept(v);
+      value?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `await x`.
+class AwaitExpression extends Expression {
+  Expression operand;
+
+  AwaitExpression(this.operand) {
+    operand?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) {
+    return types.unfutureType(operand.getStaticType(types));
+  }
+
+  accept(ExpressionVisitor v) => v.visitAwaitExpression(this);
+
+  visitChildren(Visitor v) {
+    operand?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (operand != null) {
+      operand = operand.accept(v);
+      operand?.parent = this;
+    }
+  }
+}
+
+/// Expression of form `(x,y) => ...` or `(x,y) { ... }`
+///
+/// The arrow-body form `=> e` is desugared into `return e;`.
+class FunctionExpression extends Expression {
+  FunctionNode function;
+
+  FunctionExpression(this.function) {
+    function?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => function.functionType;
+
+  accept(ExpressionVisitor v) => v.visitFunctionExpression(this);
+
+  visitChildren(Visitor v) {
+    function?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (function != null) {
+      function = function.accept(v);
+      function?.parent = this;
+    }
+  }
+}
+
+/// Synthetic expression of form `let v = x in y`
+class Let extends Expression {
+  VariableDeclaration variable; // Must have an initializer.
+  Expression body;
+
+  Let(this.variable, this.body) {
+    variable?.parent = this;
+    body?.parent = this;
+  }
+
+  DartType getStaticType(TypeEnvironment types) => body.getStaticType(types);
+
+  accept(ExpressionVisitor v) => v.visitLet(this);
+
+  visitChildren(Visitor v) {
+    variable?.accept(v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (variable != null) {
+      variable = variable.accept(v);
+      variable?.parent = this;
+    }
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+// ------------------------------------------------------------------------
+//                              STATEMENTS
+// ------------------------------------------------------------------------
+
+abstract class Statement extends TreeNode {
+  accept(StatementVisitor v);
+}
+
+/// A statement with a compile-time error.
+///
+/// Should throw an exception at runtime.
+class InvalidStatement extends Statement {
+  accept(StatementVisitor v) => v.visitInvalidStatement(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class ExpressionStatement extends Statement {
+  Expression expression;
+
+  ExpressionStatement(this.expression) {
+    expression?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitExpressionStatement(this);
+
+  visitChildren(Visitor v) {
+    expression?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (expression != null) {
+      expression = expression.accept(v);
+      expression?.parent = this;
+    }
+  }
+}
+
+class Block extends Statement {
+  final List<Statement> statements;
+
+  Block(this.statements) {
+    setParents(statements, this);
+  }
+
+  accept(StatementVisitor v) => v.visitBlock(this);
+
+  visitChildren(Visitor v) {
+    visitList(statements, v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(statements, v, this);
+  }
+
+  void addStatement(Statement node) {
+    statements.add(node);
+    node.parent = this;
+  }
+}
+
+class EmptyStatement extends Statement {
+  accept(StatementVisitor v) => v.visitEmptyStatement(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class AssertStatement extends Statement {
+  Expression condition;
+  Expression message; // May be null.
+
+  AssertStatement(this.condition, [this.message]) {
+    condition?.parent = this;
+    message?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitAssertStatement(this);
+
+  visitChildren(Visitor v) {
+    condition?.accept(v);
+    message?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (condition != null) {
+      condition = condition.accept(v);
+      condition?.parent = this;
+    }
+    if (message != null) {
+      message = message.accept(v);
+      message?.parent = this;
+    }
+  }
+}
+
+/// A target of a [Break] statement.
+///
+/// The label itself has no name; breaks reference the statement directly.
+///
+/// The frontend does not generate labeled statements without uses.
+class LabeledStatement extends Statement {
+  Statement body;
+
+  LabeledStatement(this.body) {
+    body?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitLabeledStatement(this);
+
+  visitChildren(Visitor v) {
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+/// Breaks out of an enclosing [LabeledStatement].
+///
+/// Both `break` and loop `continue` statements are translated into this node.
+///
+/// For example, the following loop with a `continue` will be desugared:
+///
+///     while(x) {
+///       if (y) continue;
+///       BODY'
+///     }
+///
+///     ==>
+///
+///     while(x) {
+///       L: {
+///         if (y) break L;
+///         BODY'
+///       }
+///     }
+//
+class BreakStatement extends Statement {
+  LabeledStatement target;
+
+  BreakStatement(this.target);
+
+  accept(StatementVisitor v) => v.visitBreakStatement(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class WhileStatement extends Statement {
+  Expression condition;
+  Statement body;
+
+  WhileStatement(this.condition, this.body) {
+    condition?.parent = this;
+    body?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitWhileStatement(this);
+
+  visitChildren(Visitor v) {
+    condition?.accept(v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (condition != null) {
+      condition = condition.accept(v);
+      condition?.parent = this;
+    }
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+class DoStatement extends Statement {
+  Statement body;
+  Expression condition;
+
+  DoStatement(this.body, this.condition) {
+    body?.parent = this;
+    condition?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitDoStatement(this);
+
+  visitChildren(Visitor v) {
+    body?.accept(v);
+    condition?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+    if (condition != null) {
+      condition = condition.accept(v);
+      condition?.parent = this;
+    }
+  }
+}
+
+class ForStatement extends Statement {
+  final List<VariableDeclaration> variables; // May be empty, but not null.
+  Expression condition; // May be null.
+  final List<Expression> updates; // May be empty, but not null.
+  Statement body;
+
+  ForStatement(this.variables, this.condition, this.updates, this.body) {
+    setParents(variables, this);
+    condition?.parent = this;
+    setParents(updates, this);
+    body?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitForStatement(this);
+
+  visitChildren(Visitor v) {
+    visitList(variables, v);
+    condition?.accept(v);
+    visitList(updates, v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(variables, v, this);
+    if (condition != null) {
+      condition = condition.accept(v);
+      condition?.parent = this;
+    }
+    transformList(updates, v, this);
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+class ForInStatement extends Statement {
+  VariableDeclaration variable; // Has no initializer.
+  Expression iterable;
+  Statement body;
+  bool isAsync; // True if this is an 'await for' loop.
+
+  ForInStatement(this.variable, this.iterable, this.body,
+      {this.isAsync: false}) {
+    variable?.parent = this;
+    iterable?.parent = this;
+    body?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitForInStatement(this);
+
+  visitChildren(Visitor v) {
+    variable?.accept(v);
+    iterable?.accept(v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (variable != null) {
+      variable = variable.accept(v);
+      variable?.parent = this;
+    }
+    if (iterable != null) {
+      iterable = iterable.accept(v);
+      iterable?.parent = this;
+    }
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+/// Statement of form `switch (e) { case x: ... }`.
+///
+/// Adjacent case clauses have been merged into a single [SwitchCase]. A runtime
+/// exception must be thrown if one [SwitchCase] falls through to another case.
+class SwitchStatement extends Statement {
+  Expression expression;
+  final List<SwitchCase> cases;
+
+  SwitchStatement(this.expression, this.cases) {
+    expression?.parent = this;
+    setParents(cases, this);
+  }
+
+  accept(StatementVisitor v) => v.visitSwitchStatement(this);
+
+  visitChildren(Visitor v) {
+    expression?.accept(v);
+    visitList(cases, v);
+  }
+
+  transformChildren(Transformer v) {
+    if (expression != null) {
+      expression = expression.accept(v);
+      expression?.parent = this;
+    }
+    transformList(cases, v, this);
+  }
+}
+
+/// A group of `case` clauses and/or a `default` clause.
+///
+/// This is a potential target of [ContinueSwitchStatement].
+class SwitchCase extends TreeNode {
+  final List<Expression> expressions;
+  Statement body;
+  bool isDefault;
+
+  SwitchCase(this.expressions, this.body, {this.isDefault: false}) {
+    setParents(expressions, this);
+    body?.parent = this;
+  }
+
+  SwitchCase.defaultCase(this.body)
+      : isDefault = true,
+        expressions = <Expression>[] {
+    body?.parent = this;
+  }
+
+  SwitchCase.empty()
+      : expressions = <Expression>[],
+        body = null,
+        isDefault = false;
+
+  accept(TreeVisitor v) => v.visitSwitchCase(this);
+
+  visitChildren(Visitor v) {
+    visitList(expressions, v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(expressions, v, this);
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+/// Jump to a case in an enclosing switch.
+class ContinueSwitchStatement extends Statement {
+  SwitchCase target;
+
+  ContinueSwitchStatement(this.target);
+
+  accept(StatementVisitor v) => v.visitContinueSwitchStatement(this);
+
+  visitChildren(Visitor v) {}
+  transformChildren(Transformer v) {}
+}
+
+class IfStatement extends Statement {
+  Expression condition;
+  Statement then;
+  Statement otherwise;
+
+  IfStatement(this.condition, this.then, this.otherwise) {
+    condition?.parent = this;
+    then?.parent = this;
+    otherwise?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitIfStatement(this);
+
+  visitChildren(Visitor v) {
+    condition?.accept(v);
+    then?.accept(v);
+    otherwise?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (condition != null) {
+      condition = condition.accept(v);
+      condition?.parent = this;
+    }
+    if (then != null) {
+      then = then.accept(v);
+      then?.parent = this;
+    }
+    if (otherwise != null) {
+      otherwise = otherwise.accept(v);
+      otherwise?.parent = this;
+    }
+  }
+}
+
+class ReturnStatement extends Statement {
+  Expression expression; // May be null.
+
+  ReturnStatement([this.expression]) {
+    expression?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitReturnStatement(this);
+
+  visitChildren(Visitor v) {
+    expression?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (expression != null) {
+      expression = expression.accept(v);
+      expression?.parent = this;
+    }
+  }
+}
+
+class TryCatch extends Statement {
+  Statement body;
+  List<Catch> catches;
+
+  TryCatch(this.body, this.catches) {
+    body?.parent = this;
+    setParents(catches, this);
+  }
+
+  accept(StatementVisitor v) => v.visitTryCatch(this);
+
+  visitChildren(Visitor v) {
+    body?.accept(v);
+    visitList(catches, v);
+  }
+
+  transformChildren(Transformer v) {
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+    transformList(catches, v, this);
+  }
+}
+
+class Catch extends TreeNode {
+  DartType guard; // Not null, defaults to dynamic.
+  VariableDeclaration exception; // May be null.
+  VariableDeclaration stackTrace; // May be null.
+  Statement body;
+
+  Catch(this.exception, this.body,
+      {this.guard: const DynamicType(), this.stackTrace}) {
+    assert(guard != null);
+    exception?.parent = this;
+    stackTrace?.parent = this;
+    body?.parent = this;
+  }
+
+  accept(TreeVisitor v) => v.visitCatch(this);
+
+  visitChildren(Visitor v) {
+    guard?.accept(v);
+    exception?.accept(v);
+    stackTrace?.accept(v);
+    body?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    guard = v.visitDartType(guard);
+    if (exception != null) {
+      exception = exception.accept(v);
+      exception?.parent = this;
+    }
+    if (stackTrace != null) {
+      stackTrace = stackTrace.accept(v);
+      stackTrace?.parent = this;
+    }
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+  }
+}
+
+class TryFinally extends Statement {
+  Statement body;
+  Statement finalizer;
+
+  TryFinally(this.body, this.finalizer) {
+    body?.parent = this;
+    finalizer?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitTryFinally(this);
+
+  visitChildren(Visitor v) {
+    body?.accept(v);
+    finalizer?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (body != null) {
+      body = body.accept(v);
+      body?.parent = this;
+    }
+    if (finalizer != null) {
+      finalizer = finalizer.accept(v);
+      finalizer?.parent = this;
+    }
+  }
+}
+
+/// Statement of form `yield x` or `yield* x`.
+///
+/// For native yield semantics see `AsyncMarker.SyncYielding`.
+class YieldStatement extends Statement {
+  Expression expression;
+  int flags = 0;
+
+  YieldStatement(this.expression,
+      {bool isYieldStar: false, bool isNative: false}) {
+    expression?.parent = this;
+    this.isYieldStar = isYieldStar;
+    this.isNative = isNative;
+  }
+
+  static const int FlagYieldStar = 1 << 0;
+  static const int FlagNative = 1 << 1;
+
+  bool get isYieldStar => flags & FlagYieldStar != 0;
+  bool get isNative => flags & FlagNative != 0;
+
+  void set isYieldStar(bool value) {
+    flags = value ? (flags | FlagYieldStar) : (flags & ~FlagYieldStar);
+  }
+
+  void set isNative(bool value) {
+    flags = value ? (flags | FlagNative) : (flags & ~FlagNative);
+  }
+
+  accept(StatementVisitor v) => v.visitYieldStatement(this);
+
+  visitChildren(Visitor v) {
+    expression?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (expression != null) {
+      expression = expression.accept(v);
+      expression?.parent = this;
+    }
+  }
+}
+
+/// Declaration of a local variable.
+///
+/// This may occur as a statement, but is also used in several non-statement
+/// contexts, such as in [ForStatement], [Catch], and [FunctionNode].
+///
+/// When this occurs as a statement, it must be a direct child of a [Block].
+//
+// DESIGN TODO: Should we remove the 'final' modifier from variables?
+class VariableDeclaration extends Statement {
+  /// For named parameters, this is the name of the parameter. No two named
+  /// parameters (in the same parameter list) can have the same name.
+  ///
+  /// In all other cases, the name is cosmetic, may be empty or null,
+  /// and is not necessarily unique.
+  String name;
+  int flags = 0;
+  DartType type; // Not null, defaults to dynamic.
+  InferredValue inferredValue; // May be null.
+
+  /// For locals, this is the initial value.
+  /// For parameters, this is the default value.
+  ///
+  /// Should be null in other cases.
+  Expression initializer; // May be null.
+
+  VariableDeclaration(this.name,
+      {this.initializer,
+      this.type: const DynamicType(),
+      this.inferredValue,
+      bool isFinal: false,
+      bool isConst: false}) {
+    assert(type != null);
+    initializer?.parent = this;
+    this.isFinal = isFinal;
+    this.isConst = isConst;
+  }
+
+  /// Creates a synthetic variable with the given expression as initializer.
+  VariableDeclaration.forValue(this.initializer,
+      {bool isFinal: true,
+      bool isConst: false,
+      this.type: const DynamicType()}) {
+    assert(type != null);
+    initializer?.parent = this;
+    this.isFinal = isFinal;
+    this.isConst = isConst;
+  }
+
+  static const int FlagFinal = 1 << 0; // Must match serialized bit positions.
+  static const int FlagConst = 1 << 1;
+  static const int FlagInScope = 1 << 2; // Temporary flag used by verifier.
+
+  bool get isFinal => flags & FlagFinal != 0;
+  bool get isConst => flags & FlagConst != 0;
+
+  void set isFinal(bool value) {
+    flags = value ? (flags | FlagFinal) : (flags & ~FlagFinal);
+  }
+
+  void set isConst(bool value) {
+    flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
+  }
+
+  accept(StatementVisitor v) => v.visitVariableDeclaration(this);
+
+  visitChildren(Visitor v) {
+    type?.accept(v);
+    inferredValue?.accept(v);
+    initializer?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    type = v.visitDartType(type);
+    if (initializer != null) {
+      initializer = initializer.accept(v);
+      initializer?.parent = this;
+    }
+  }
+
+  /// Returns a possibly synthesized name for this variable, consistent with
+  /// the names used across all [toString] calls.
+  String toString() => debugVariableDeclarationName(this);
+}
+
+/// Declaration a local function.
+///
+/// The body of the function may use [variable] as its self-reference.
+class FunctionDeclaration extends Statement {
+  VariableDeclaration variable; // Is final and has no initializer.
+  FunctionNode function;
+
+  FunctionDeclaration(this.variable, this.function) {
+    variable?.parent = this;
+    function?.parent = this;
+  }
+
+  accept(StatementVisitor v) => v.visitFunctionDeclaration(this);
+
+  visitChildren(Visitor v) {
+    variable?.accept(v);
+    function?.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    if (variable != null) {
+      variable = variable.accept(v);
+      variable?.parent = this;
+    }
+    if (function != null) {
+      function = function.accept(v);
+      function?.parent = this;
+    }
+  }
+}
+
+// ------------------------------------------------------------------------
+//                                NAMES
+// ------------------------------------------------------------------------
+
+/// A public name, or a private name qualified by a library.
+///
+/// Names are only used for expressions with dynamic dispatch, as all
+/// statically resolved references are represented in nameless form.
+///
+/// [Name]s are immutable and compare based on structural equality, and they
+/// are not AST nodes.
+///
+/// The [toString] method returns a human-readable string that includes the
+/// library name for private names; uniqueness is not guaranteed.
+abstract class Name implements Node {
+  final int hashCode;
+  final String name;
+  Library get library;
+  bool get isPrivate;
+
+  Name._internal(this.hashCode, this.name);
+
+  factory Name(String name, [Library library]) {
+    /// Use separate subclasses for the public and private case to save memory
+    /// for public names.
+    if (name.startsWith('_')) {
+      assert(library != null);
+      return new _PrivateName(name, library);
+    } else {
+      return new _PublicName(name);
+    }
+  }
+
+  bool operator ==(other) {
+    return other is Name && name == other.name && library == other.library;
+  }
+
+  accept(Visitor v) => v.visitName(this);
+
+  visitChildren(Visitor v) {
+    // DESIGN TODO: Should we visit the library as a library reference?
+  }
+}
+
+class _PrivateName extends Name {
+  final Library library;
+  bool get isPrivate => true;
+
+  _PrivateName(String name, Library library)
+      : this.library = library,
+        super._internal(_computeHashCode(name, library), name);
+
+  String toString() => library != null ? '$library::$name' : name;
+
+  static int _computeHashCode(String name, Library library) {
+    return 131 * name.hashCode + 17 * library.hashCode;
+  }
+}
+
+class _PublicName extends Name {
+  Library get library => null;
+  bool get isPrivate => false;
+
+  _PublicName(String name) : super._internal(name.hashCode, name);
+
+  String toString() => name;
+}
+
+// ------------------------------------------------------------------------
+//                             TYPES
+// ------------------------------------------------------------------------
+
+/// A syntax-independent notion of a type.
+///
+/// [DartType]s are not AST nodes and may be shared between different parents.
+///
+/// [DartType] objects should be treated as unmodifiable objects, although
+/// immutability is not enforced for List fields, and [TypeParameter]s are
+/// cyclic structures that are constructed by mutation.
+///
+/// The `==` operator on [DartType]s compare based on type equality, not
+/// object identity.
+abstract class DartType extends Node {
+  const DartType();
+
+  accept(DartTypeVisitor v);
+
+  bool operator ==(Object other);
+}
+
+/// The type arising from invalid type annotations.
+///
+/// Can usually be treated as 'dynamic', but should occasionally be handled
+/// differently, e.g. `x is ERROR` should evaluate to false.
+class InvalidType extends DartType {
+  final int hashCode = 12345;
+
+  const InvalidType();
+
+  accept(DartTypeVisitor v) => v.visitInvalidType(this);
+  visitChildren(Visitor v) {}
+
+  bool operator ==(Object other) => other is InvalidType;
+}
+
+class DynamicType extends DartType {
+  final int hashCode = 54321;
+
+  const DynamicType();
+
+  accept(DartTypeVisitor v) => v.visitDynamicType(this);
+  visitChildren(Visitor v) {}
+
+  bool operator ==(Object other) => other is DynamicType;
+}
+
+class VoidType extends DartType {
+  final int hashCode = 123121;
+
+  const VoidType();
+
+  accept(DartTypeVisitor v) => v.visitVoidType(this);
+  visitChildren(Visitor v) {}
+
+  bool operator ==(Object other) => other is VoidType;
+}
+
+class BottomType extends DartType {
+  final int hashCode = 514213;
+
+  const BottomType();
+
+  accept(DartTypeVisitor v) => v.visitBottomType(this);
+  visitChildren(Visitor v) {}
+
+  bool operator ==(Object other) => other is BottomType;
+}
+
+class InterfaceType extends DartType {
+  final Class classNode;
+  final List<DartType> typeArguments;
+
+  /// The [typeArguments] list must not be modified after this call. If the
+  /// list is omitted, 'dynamic' type arguments are filled in.
+  InterfaceType(Class classNode, [List<DartType> typeArguments])
+      : this.classNode = classNode,
+        this.typeArguments = typeArguments ?? _defaultTypeArguments(classNode);
+
+  static List<DartType> _defaultTypeArguments(Class classNode) {
+    if (classNode.typeParameters.length == 0) {
+      // Avoid allocating a list in this very common case.
+      return const <DartType>[];
+    } else {
+      return new List<DartType>.filled(
+          classNode.typeParameters.length, const DynamicType());
+    }
+  }
+
+  accept(DartTypeVisitor v) => v.visitInterfaceType(this);
+
+  visitChildren(Visitor v) {
+    classNode.acceptReference(v);
+    visitList(typeArguments, v);
+  }
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    if (other is InterfaceType) {
+      if (classNode != other.classNode) return false;
+      if (typeArguments.length != other.typeArguments.length) return false;
+      for (int i = 0; i < typeArguments.length; ++i) {
+        if (typeArguments[i] != other.typeArguments[i]) return false;
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  int get hashCode {
+    int hash = 0x3fffffff & classNode.hashCode;
+    for (int i = 0; i < typeArguments.length; ++i) {
+      hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode));
+    }
+    return hash;
+  }
+}
+
+/// A possibly generic function type.
+class FunctionType extends DartType {
+  final List<TypeParameter> typeParameters;
+  final int requiredParameterCount;
+  final List<DartType> positionalParameters;
+  final List<NamedType> namedParameters; // Must be sorted.
+  final DartType returnType;
+  int _hashCode;
+
+  FunctionType(List<DartType> positionalParameters, this.returnType,
+      {this.namedParameters: const <NamedType>[],
+      this.typeParameters: const <TypeParameter>[],
+      int requiredParameterCount})
+      : this.positionalParameters = positionalParameters,
+        this.requiredParameterCount =
+            requiredParameterCount ?? positionalParameters.length;
+
+  accept(DartTypeVisitor v) => v.visitFunctionType(this);
+
+  visitChildren(Visitor v) {
+    visitList(typeParameters, v);
+    visitList(positionalParameters, v);
+    visitList(namedParameters, v);
+    returnType.accept(v);
+  }
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    if (other is FunctionType) {
+      if (typeParameters.length != other.typeParameters.length ||
+          requiredParameterCount != other.requiredParameterCount ||
+          positionalParameters.length != other.positionalParameters.length ||
+          namedParameters.length != other.namedParameters.length) {
+        return false;
+      }
+      if (typeParameters.isEmpty) {
+        for (int i = 0; i < positionalParameters.length; ++i) {
+          if (positionalParameters[i] != other.positionalParameters[i]) {
+            return false;
+          }
+        }
+        for (int i = 0; i < namedParameters.length; ++i) {
+          if (namedParameters[i] != other.namedParameters[i]) {
+            return false;
+          }
+        }
+        return returnType == other.returnType;
+      } else {
+        // Structural equality does not tell us if two generic function types
+        // are the same type.  If they are unifiable without substituting any
+        // type variables, they are equal.
+        return unifyTypes(this, other, new Set<TypeParameter>()) != null;
+      }
+    } else {
+      return false;
+    }
+  }
+
+  /// Returns a variant of this function type that does not declare any type
+  /// parameters.
+  ///
+  /// Any uses of its type parameters become free variables in the returned
+  /// type.
+  FunctionType get withoutTypeParameters {
+    if (typeParameters.isEmpty) return this;
+    return new FunctionType(positionalParameters, returnType,
+        requiredParameterCount: requiredParameterCount,
+        namedParameters: namedParameters);
+  }
+
+  int get hashCode => _hashCode ??= _computeHashCode();
+
+  int _computeHashCode() {
+    int hash = 1237;
+    hash = 0x3fffffff & (hash * 31 + requiredParameterCount);
+    for (int i = 0; i < typeParameters.length; ++i) {
+      TypeParameter parameter = typeParameters[i];
+      _temporaryHashCodeTable[parameter] = _temporaryHashCodeTable.length;
+      hash = 0x3fffffff & (hash * 31 + parameter.bound.hashCode);
+    }
+    for (int i = 0; i < positionalParameters.length; ++i) {
+      hash = 0x3fffffff & (hash * 31 + positionalParameters[i].hashCode);
+    }
+    for (int i = 0; i < namedParameters.length; ++i) {
+      hash = 0x3fffffff & (hash * 31 + namedParameters[i].hashCode);
+    }
+    hash = 0x3fffffff & (hash * 31 + returnType.hashCode);
+    for (int i = 0; i < typeParameters.length; ++i) {
+      // Remove the type parameters from the scope again.
+      _temporaryHashCodeTable.remove(typeParameters[i]);
+    }
+    return hash;
+  }
+}
+
+/// A named parameter in [FunctionType].
+class NamedType extends Node implements Comparable<NamedType> {
+  final String name;
+  final DartType type;
+
+  NamedType(this.name, this.type);
+
+  bool operator ==(Object other) {
+    return other is NamedType && name == other.name && type == other.type;
+  }
+
+  int get hashCode {
+    return name.hashCode * 31 + type.hashCode * 37;
+  }
+
+  int compareTo(NamedType other) => name.compareTo(other.name);
+
+  accept(Visitor v) => v.visitNamedType(this);
+
+  void visitChildren(Visitor v) {
+    type.accept(v);
+  }
+}
+
+/// Stores the hash code of function type parameters while computing the hash
+/// code of a [FunctionType] object.
+///
+/// This ensures that distinct [FunctionType] objects get the same hash code
+/// if they represent the same type, even though their type parameters are
+/// represented by different objects.
+final Map<TypeParameter, int> _temporaryHashCodeTable = <TypeParameter, int>{};
+
+/// Reference to a type variable.
+class TypeParameterType extends DartType {
+  TypeParameter parameter;
+
+  TypeParameterType(this.parameter);
+
+  accept(DartTypeVisitor v) => v.visitTypeParameterType(this);
+
+  visitChildren(Visitor v) {}
+
+  bool operator ==(Object other) {
+    return other is TypeParameterType && parameter == other.parameter;
+  }
+
+  int get hashCode => _temporaryHashCodeTable[parameter] ?? parameter.hashCode;
+}
+
+/// Declaration of a type variable.
+///
+/// Type parameters declared in a [Class] or [FunctionNode] are part of the AST,
+/// have a parent pointer to its declaring class or function, and will be seen
+/// by tree visitors.
+///
+/// Type parameters declared by a [FunctionType] are orphans and have a `null`
+/// parent pointer.  [TypeParameter] objects should not be shared between
+/// different [FunctionType] objects.
+class TypeParameter extends TreeNode {
+  String name; // Cosmetic name.
+
+  /// The bound on the type variable.
+  ///
+  /// Should not be null except temporarily during IR construction.  Should
+  /// be set to the root class for type parameters without an explicit bound.
+  DartType bound;
+
+  TypeParameter([this.name, this.bound]);
+
+  accept(TreeVisitor v) => v.visitTypeParameter(this);
+
+  visitChildren(Visitor v) {
+    bound.accept(v);
+  }
+
+  transformChildren(Transformer v) {
+    bound = v.visitDartType(bound);
+  }
+
+  /// Returns a possibly synthesized name for this type parameter, consistent
+  /// with the names used across all [toString] calls.
+  String toString() => debugQualifiedTypeParameterName(this);
+}
+
+class Supertype extends Node {
+  final Class classNode;
+  final List<DartType> typeArguments;
+
+  Supertype(this.classNode, this.typeArguments);
+
+  accept(Visitor v) => v.visitSupertype(this);
+
+  visitChildren(Visitor v) {
+    classNode.acceptReference(v);
+    visitList(typeArguments, v);
+  }
+
+  InterfaceType get asInterfaceType {
+    return new InterfaceType(classNode, typeArguments);
+  }
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    if (other is Supertype) {
+      if (classNode != other.classNode) return false;
+      if (typeArguments.length != other.typeArguments.length) return false;
+      for (int i = 0; i < typeArguments.length; ++i) {
+        if (typeArguments[i] != other.typeArguments[i]) return false;
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  int get hashCode {
+    int hash = 0x3fffffff & classNode.hashCode;
+    for (int i = 0; i < typeArguments.length; ++i) {
+      hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode));
+    }
+    return hash;
+  }
+}
+
+// ------------------------------------------------------------------------
+//                                PROGRAM
+// ------------------------------------------------------------------------
+
+/// A way to bundle up all the libraries in a program.
+class Program extends TreeNode {
+  final List<Library> libraries;
+
+  /// Map from a source file uri to a line-starts table.
+  /// Given a source file uri and a offset in that file one can translate
+  /// it to a line:column position in that file.
+  final Map<String, List<int>> uriToLineStarts;
+
+  /// Reference to the main method in one of the libraries.
+  Procedure mainMethod;
+
+  Program([List<Library> libraries, Map<String, List<int>> uriToLineStarts])
+      : libraries = libraries ?? <Library>[],
+        uriToLineStarts = uriToLineStarts ?? {} {
+    setParents(libraries, this);
+  }
+
+  accept(TreeVisitor v) => v.visitProgram(this);
+
+  visitChildren(Visitor v) {
+    visitList(libraries, v);
+    mainMethod?.acceptReference(v);
+  }
+
+  transformChildren(Transformer v) {
+    transformList(libraries, v, this);
+  }
+
+  Program get enclosingProgram => this;
+
+  /// Translates an offset to line and column numbers in the given file.
+  Location getLocation(String file, int offset) {
+    List<int> lines = uriToLineStarts[file];
+    int low = 0, high = lines.length - 1;
+    while (low < high) {
+      int mid = high - ((high - low) >> 1); // Get middle, rounding up.
+      int pivot = lines[mid];
+      if (pivot <= offset) {
+        low = mid;
+      } else {
+        high = mid - 1;
+      }
+    }
+    int lineIndex = low;
+    int lineStart = lines[lineIndex];
+    int lineNumber = 1 + lineIndex;
+    int columnNumber = offset - lineStart;
+    return new Location(file, lineNumber, columnNumber);
+  }
+}
+
+/// A tuple with file, line, and column number, for displaying human-readable
+/// locations.
+class Location {
+  final String file;
+  final int line; // 1-based.
+  final int column; // 1-based.
+
+  Location(this.file, this.line, this.column);
+
+  String toString() => '$file:$line:$column';
+}
+
+// ------------------------------------------------------------------------
+//                             INTERNAL FUNCTIONS
+// ------------------------------------------------------------------------
+
+void setParents(List<TreeNode> nodes, TreeNode parent) {
+  for (int i = 0; i < nodes.length; ++i) {
+    nodes[i].parent = parent;
+  }
+}
+
+void visitList(List<Node> nodes, Visitor visitor) {
+  for (int i = 0; i < nodes.length; ++i) {
+    nodes[i].accept(visitor);
+  }
+}
+
+void visitIterable(Iterable<Node> nodes, Visitor visitor) {
+  for (var node in nodes) {
+    node.accept(visitor);
+  }
+}
+
+void transformTypeList(List<DartType> nodes, Transformer visitor) {
+  int storeIndex = 0;
+  for (int i = 0; i < nodes.length; ++i) {
+    var result = visitor.visitDartType(nodes[i]);
+    if (result != null) {
+      nodes[storeIndex] = result;
+      ++storeIndex;
+    }
+  }
+  if (storeIndex < nodes.length) {
+    nodes.length = storeIndex;
+  }
+}
+
+void transformSupertypeList(List<Supertype> nodes, Transformer visitor) {
+  int storeIndex = 0;
+  for (int i = 0; i < nodes.length; ++i) {
+    var result = visitor.visitSupertype(nodes[i]);
+    if (result != null) {
+      nodes[storeIndex] = result;
+      ++storeIndex;
+    }
+  }
+  if (storeIndex < nodes.length) {
+    nodes.length = storeIndex;
+  }
+}
+
+void transformList(List<TreeNode> nodes, Transformer visitor, TreeNode parent) {
+  int storeIndex = 0;
+  for (int i = 0; i < nodes.length; ++i) {
+    var result = nodes[i].accept(visitor);
+    if (result != null) {
+      nodes[storeIndex] = result;
+      result.parent = parent;
+      ++storeIndex;
+    }
+  }
+  if (storeIndex < nodes.length) {
+    nodes.length = storeIndex;
+  }
+}
+
+List<DartType> _getAsTypeArguments(List<TypeParameter> typeParameters) {
+  if (typeParameters.isEmpty) return const <DartType>[];
+  return new List<DartType>.generate(
+      typeParameters.length, (i) => new TypeParameterType(typeParameters[i]),
+      growable: false);
+}
+
+class _ChildReplacer extends Transformer {
+  final TreeNode child;
+  final TreeNode replacement;
+
+  _ChildReplacer(this.child, this.replacement);
+
+  @override
+  defaultTreeNode(TreeNode node) {
+    if (node == child) {
+      return replacement;
+    } else {
+      return node;
+    }
+  }
+}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
new file mode 100644
index 0000000..1b228b8
--- /dev/null
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -0,0 +1,941 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.ast_from_binary;
+
+import '../ast.dart';
+import 'tag.dart';
+import 'loader.dart';
+import 'dart:convert';
+import 'package:kernel/transformations/flags.dart';
+
+class ParseError {
+  String filename;
+  int byteIndex;
+  String message;
+  String path;
+
+  ParseError(this.message, {this.filename, this.byteIndex, this.path});
+
+  String toString() => '$filename:$byteIndex: $message at $path';
+}
+
+class BinaryBuilder {
+  final BinaryReferenceLoader loader;
+  final List<Library> importTable = <Library>[];
+  final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
+  final List<LabeledStatement> labelStack = <LabeledStatement>[];
+  int labelStackBase = 0;
+  final List<SwitchCase> switchCaseStack = <SwitchCase>[];
+  final List<TypeParameter> typeParameterStack = <TypeParameter>[];
+  final String filename;
+  final List<int> _bytes;
+  int _byteIndex = 0;
+  Library _currentLibrary;
+  List<String> _stringTable;
+  List<String> _sourceUriTable;
+  int _transformerFlags = 0;
+
+  // If something goes wrong, this list should indicate what library,
+  // class, and member was being built.
+  List<String> debugPath = <String>[];
+
+  BinaryBuilder(this.loader, this._bytes, [this.filename]);
+
+  fail(String message) {
+    throw new ParseError(message,
+        byteIndex: _byteIndex, filename: filename, path: debugPath.join('::'));
+  }
+
+  int readByte() => _bytes[_byteIndex++];
+
+  int readUInt() {
+    var byte = readByte();
+    if (byte & 0x80 == 0) {
+      // 0xxxxxxx
+      return byte;
+    } else if (byte & 0x40 == 0) {
+      // 10xxxxxx
+      return ((byte & 0x3F) << 8) | readByte();
+    } else {
+      // 11xxxxxx
+      return ((byte & 0x3F) << 24) |
+          (readByte() << 16) |
+          (readByte() << 8) |
+          readByte();
+    }
+  }
+
+  int readMagicWord() {
+    return (readByte() << 24) |
+        (readByte() << 16) |
+        (readByte() << 8) |
+        readByte();
+  }
+
+  String readStringEntry() {
+    int numBytes = readUInt();
+    // Utf8Decoder will skip leading BOM characters, but we must preserve them.
+    // Collect leading BOMs before passing the bytes onto Utf8Decoder.
+    int numByteOrderMarks = 0;
+    while (_byteIndex + 2 < _bytes.length &&
+        _bytes[_byteIndex] == 0xef &&
+        _bytes[_byteIndex + 1] == 0xbb &&
+        _bytes[_byteIndex + 2] == 0xbf) {
+      ++numByteOrderMarks;
+      _byteIndex += 3;
+      numBytes -= 3;
+    }
+    String string =
+        const Utf8Decoder().convert(_bytes, _byteIndex, _byteIndex + numBytes);
+    _byteIndex += numBytes;
+    if (numByteOrderMarks > 0) {
+      return '\ufeff' * numByteOrderMarks + string;
+    }
+    return string;
+  }
+
+  void readStringTable() {
+    int length = readUInt();
+    _stringTable = new List<String>(length);
+    for (int i = 0; i < length; ++i) {
+      _stringTable[i] = readStringEntry();
+    }
+  }
+
+  String readUriReference() {
+    return _sourceUriTable[readUInt()];
+  }
+
+  void readSourceUriTable() {
+    int length = readUInt();
+    _sourceUriTable = new List<String>(length);
+    for (int i = 0; i < length; ++i) {
+      _sourceUriTable[i] = readStringEntry();
+    }
+  }
+
+  String readStringReference() {
+    return _stringTable[readUInt()];
+  }
+
+  String readStringOrNullIfEmpty() {
+    var string = readStringReference();
+    return string.isEmpty ? null : string;
+  }
+
+  InferredValue readOptionalInferredValue() {
+    if (readAndCheckOptionTag()) {
+      Class baseClass = readClassReference(allowNull: true);
+      BaseClassKind baseClassKind = BaseClassKind.values[readByte()];
+      int valueBits = readByte();
+      return new InferredValue(baseClass, baseClassKind, valueBits);
+    }
+    return null;
+  }
+
+  bool readAndCheckOptionTag() {
+    int tag = readByte();
+    if (tag == Tag.Nothing) {
+      return false;
+    } else if (tag == Tag.Something) {
+      return true;
+    } else {
+      throw fail('Invalid Option tag: $tag');
+    }
+  }
+
+  List<Expression> readAnnotationList(TreeNode parent) {
+    int length = readUInt();
+    if (length == 0) return const <Expression>[];
+    List<Expression> list = new List<Expression>(length);
+    for (int i = 0; i < length; ++i) {
+      list[i] = readExpression()..parent = parent;
+    }
+    return list;
+  }
+
+  void _fillTreeNodeList(
+      List<TreeNode> list, TreeNode buildObject(), TreeNode parent) {
+    list.length = readUInt();
+    for (int i = 0; i < list.length; ++i) {
+      list[i] = buildObject()..parent = parent;
+    }
+  }
+
+  void _fillNonTreeNodeList(List<Node> list, Node buildObject()) {
+    list.length = readUInt();
+    for (int i = 0; i < list.length; ++i) {
+      list[i] = buildObject();
+    }
+  }
+
+  Program readProgramFile() {
+    int magic = readMagicWord();
+    if (magic != Tag.ProgramFile) {
+      throw fail('This is not a binary dart file. '
+          'Magic number was: ${magic.toRadixString(16)}');
+    }
+    readStringTable();
+    Map<String, List<int>> uriToLineStarts = readUriToLineStarts();
+    importTable.length = readUInt();
+    for (int i = 0; i < importTable.length; ++i) {
+      importTable[i] = new Library(null);
+    }
+    for (int i = 0; i < importTable.length; ++i) {
+      _currentLibrary = importTable[i];
+      readLibrary();
+    }
+    var mainMethod = readMemberReference(allowNull: true);
+    return new Program(importTable, uriToLineStarts)..mainMethod = mainMethod;
+  }
+
+  Map<String, List<int>> readUriToLineStarts() {
+    readSourceUriTable();
+    int length = _sourceUriTable.length;
+    Map<String, List<int>> uriToLineStarts = {};
+    for (int i = 0; i < length; ++i) {
+      String uri = _sourceUriTable[i];
+      int lineCount = readUInt();
+      List<int> lineStarts = new List<int>(lineCount);
+      int previousLineStart = 0;
+      for (int j = 0; j < lineCount; ++j) {
+        int lineStart = readUInt() + previousLineStart;
+        lineStarts[j] = lineStart;
+        previousLineStart = lineStart;
+      }
+      uriToLineStarts[uri] = lineStarts;
+    }
+    return uriToLineStarts;
+  }
+
+  void _fillLazilyLoadedList(
+      List<TreeNode> list, void buildObject(int tag, int index)) {
+    int length = readUInt();
+    list.length = length;
+    for (int i = 0; i < length; ++i) {
+      int tag = readByte();
+      buildObject(tag, i);
+    }
+  }
+
+  Library readLibraryReference() {
+    int index = readUInt();
+    return importTable[index];
+  }
+
+  Class readClassReference({bool allowNull: false}) {
+    int tag = readByte();
+    if (tag == Tag.NullReference) {
+      if (!allowNull) {
+        throw 'Expected a class reference to be valid but was `null`.';
+      }
+      return null;
+    } else {
+      var library = readLibraryReference();
+      int index = readUInt();
+      return loader.getClassReference(library, tag, index);
+    }
+  }
+
+  Member readMemberReference({bool allowNull: false}) {
+    int tag = readByte();
+    switch (tag) {
+      case Tag.LibraryFieldReference:
+      case Tag.LibraryProcedureReference:
+        var library = readLibraryReference();
+        var index = readUInt();
+        return loader.getLibraryMemberReference(library, tag, index);
+
+      case Tag.ClassFieldReference:
+      case Tag.ClassConstructorReference:
+      case Tag.ClassProcedureReference:
+        var classNode = readClassReference();
+        var index = readUInt();
+        return loader.getClassMemberReference(classNode, tag, index);
+
+      case Tag.NullReference:
+        if (!allowNull) {
+          throw 'Expected a member reference to be valid but was `null`.';
+        }
+        return null;
+
+      default:
+        throw fail('Invalid member reference tag: $tag');
+    }
+  }
+
+  Name readName() {
+    String text = readStringReference();
+    if (text.isNotEmpty && text[0] == '_') {
+      return new Name(text, readLibraryReference());
+    } else {
+      return new Name(text);
+    }
+  }
+
+  Uri readImportUri() {
+    return Uri.parse(readStringReference());
+  }
+
+  void readLibrary() {
+    int flags = readByte();
+    _currentLibrary.isExternal = (flags & 0x1) != 0;
+    _currentLibrary.name = readStringOrNullIfEmpty();
+    _currentLibrary.importUri = readImportUri();
+    debugPath.add(_currentLibrary.name ??
+        _currentLibrary.importUri?.toString() ??
+        'library');
+
+    // TODO(jensj): We currently save (almost the same) uri twice.
+    _currentLibrary.fileUri = readUriReference();
+
+    _fillLazilyLoadedList(_currentLibrary.classes, (int tag, int index) {
+      readClass(loader.getClassReference(_currentLibrary, tag, index), tag);
+    });
+    _fillLazilyLoadedList(_currentLibrary.fields, (int tag, int index) {
+      readField(
+          loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
+    });
+    _fillLazilyLoadedList(_currentLibrary.procedures, (int tag, int index) {
+      readProcedure(
+          loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
+    });
+    debugPath.removeLast();
+  }
+
+  void readClass(Class node, int tag) {
+    assert(node != null);
+    switch (tag) {
+      case Tag.NormalClass:
+        readNormalClass(node);
+        break;
+      case Tag.MixinClass:
+        readMixinClass(node);
+        break;
+      default:
+        throw fail('Invalid class tag: $tag');
+    }
+  }
+
+  void readNormalClass(Class node) {
+    int flags = readByte();
+    node.isAbstract = flags & 0x1 != 0;
+    node.level = _currentLibrary.isExternal
+        ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy
+        : ClassLevel.Body;
+    node.name = readStringOrNullIfEmpty();
+    node.fileUri = readUriReference();
+    node.annotations = readAnnotationList(node);
+    debugPath.add(node.name ?? 'normal-class');
+    readAndPushTypeParameterList(node.typeParameters, node);
+    node.supertype = readSupertypeOption();
+    _fillNonTreeNodeList(node.implementedTypes, readSupertype);
+    _fillLazilyLoadedList(node.fields, (int tag, int index) {
+      readField(loader.getClassMemberReference(node, tag, index), tag);
+    });
+    _fillLazilyLoadedList(node.constructors, (int tag, int index) {
+      readConstructor(loader.getClassMemberReference(node, tag, index), tag);
+    });
+    _fillLazilyLoadedList(node.procedures, (int tag, int index) {
+      readProcedure(loader.getClassMemberReference(node, tag, index), tag);
+    });
+    typeParameterStack.length = 0;
+    debugPath.removeLast();
+  }
+
+  void readMixinClass(Class node) {
+    int flags = readByte();
+    node.isAbstract = flags & 0x1 != 0;
+    node.level = _currentLibrary.isExternal
+        ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy
+        : ClassLevel.Body;
+    node.name = readStringOrNullIfEmpty();
+    node.fileUri = readUriReference();
+    node.annotations = readAnnotationList(node);
+    debugPath.add(node.name ?? 'mixin-class');
+    readAndPushTypeParameterList(node.typeParameters, node);
+    node.supertype = readSupertype();
+    node.mixedInType = readSupertype();
+    _fillNonTreeNodeList(node.implementedTypes, readDartType);
+    _fillLazilyLoadedList(node.constructors, (int tag, int index) {
+      readConstructor(loader.getClassMemberReference(node, tag, index), tag);
+    });
+    typeParameterStack.length = 0;
+    debugPath.removeLast();
+  }
+
+  int getAndResetTransformerFlags() {
+    int flags = _transformerFlags;
+    _transformerFlags = 0;
+    return flags;
+  }
+
+  /// Adds the given flag to the current [Member.transformerFlags].
+  void addTransformerFlag(int flags) {
+    _transformerFlags |= flags;
+  }
+
+  void readField(Field node, int tag) {
+    // Note: as with readProcedure and readConstructor, the tag parameter
+    // is unused, but we pass it in to clarify that the tag has already been
+    // consumed from the input.
+    assert(tag == Tag.Field);
+    node.fileOffset = readOffset();
+    node.flags = readByte();
+    node.name = readName();
+    node.fileUri = readUriReference();
+    node.annotations = readAnnotationList(node);
+    debugPath.add(node.name?.name ?? 'field');
+    node.type = readDartType();
+    node.inferredValue = readOptionalInferredValue();
+    node.initializer = readExpressionOption();
+    node.initializer?.parent = node;
+    node.transformerFlags = getAndResetTransformerFlags();
+    debugPath.removeLast();
+  }
+
+  void readConstructor(Constructor node, int tag) {
+    assert(tag == Tag.Constructor);
+    node.flags = readByte();
+    node.name = readName();
+    node.annotations = readAnnotationList(node);
+    debugPath.add(node.name?.name ?? 'constructor');
+    node.function = readFunctionNode()..parent = node;
+    pushVariableDeclarations(node.function.positionalParameters);
+    pushVariableDeclarations(node.function.namedParameters);
+    _fillTreeNodeList(node.initializers, readInitializer, node);
+    variableStack.length = 0;
+    node.transformerFlags = getAndResetTransformerFlags();
+    debugPath.removeLast();
+  }
+
+  void readProcedure(Procedure node, int tag) {
+    assert(tag == Tag.Procedure);
+    int kindIndex = readByte();
+    node.kind = ProcedureKind.values[kindIndex];
+    node.flags = readByte();
+    node.name = readName();
+    node.fileUri = readUriReference();
+    node.annotations = readAnnotationList(node);
+    debugPath.add(node.name?.name ?? 'procedure');
+    node.function = readFunctionNodeOption();
+    node.function?.parent = node;
+    node.transformerFlags = getAndResetTransformerFlags();
+    debugPath.removeLast();
+  }
+
+  Initializer readInitializer() {
+    int tag = readByte();
+    switch (tag) {
+      case Tag.InvalidInitializer:
+        return new InvalidInitializer();
+      case Tag.FieldInitializer:
+        return new FieldInitializer(readMemberReference(), readExpression());
+      case Tag.SuperInitializer:
+        return new SuperInitializer(readMemberReference(), readArguments());
+      case Tag.RedirectingInitializer:
+        return new RedirectingInitializer(
+            readMemberReference(), readArguments());
+      case Tag.LocalInitializer:
+        return new LocalInitializer(readAndPushVariableDeclaration());
+      default:
+        throw fail('Invalid initializer tag: $tag');
+    }
+  }
+
+  FunctionNode readFunctionNodeOption() {
+    return readAndCheckOptionTag() ? readFunctionNode() : null;
+  }
+
+  FunctionNode readFunctionNode() {
+    AsyncMarker asyncMarker = AsyncMarker.values[readByte()];
+    int typeParameterStackHeight = typeParameterStack.length;
+    var typeParameters = readAndPushTypeParameterList();
+    var requiredParameterCount = readUInt();
+    int variableStackHeight = variableStack.length;
+    var positional = readAndPushVariableDeclarationList();
+    var named = readAndPushVariableDeclarationList();
+    var returnType = readDartType();
+    var inferredReturnValue = readOptionalInferredValue();
+    int oldLabelStackBase = labelStackBase;
+    labelStackBase = labelStack.length;
+    var body = readStatementOption();
+    labelStackBase = oldLabelStackBase;
+    variableStack.length = variableStackHeight;
+    typeParameterStack.length = typeParameterStackHeight;
+    return new FunctionNode(body,
+        typeParameters: typeParameters,
+        requiredParameterCount: requiredParameterCount,
+        positionalParameters: positional,
+        namedParameters: named,
+        returnType: returnType,
+        inferredReturnValue: inferredReturnValue,
+        asyncMarker: asyncMarker);
+  }
+
+  void pushVariableDeclaration(VariableDeclaration variable) {
+    variableStack.add(variable);
+  }
+
+  void pushVariableDeclarations(List<VariableDeclaration> variables) {
+    variableStack.addAll(variables);
+  }
+
+  VariableDeclaration readVariableReference() {
+    int index = readUInt();
+    if (index >= variableStack.length) {
+      throw fail('Invalid variable index: $index');
+    }
+    return variableStack[index];
+  }
+
+  String logicalOperatorToString(int index) {
+    switch (index) {
+      case 0:
+        return '&&';
+      case 1:
+        return '||';
+      default:
+        throw fail('Invalid logical operator index: $index');
+    }
+  }
+
+  List<Expression> readExpressionList() {
+    return new List<Expression>.generate(readUInt(), (i) => readExpression());
+  }
+
+  Expression readExpressionOption() {
+    return readAndCheckOptionTag() ? readExpression() : null;
+  }
+
+  Expression readExpression() {
+    int tagByte = readByte();
+    int tag = tagByte & Tag.SpecializedTagHighBit == 0
+        ? tagByte
+        : (tagByte & Tag.SpecializedTagMask);
+    switch (tag) {
+      case Tag.InvalidExpression:
+        return new InvalidExpression();
+      case Tag.VariableGet:
+        return new VariableGet(readVariableReference(), readDartTypeOption());
+      case Tag.SpecializedVariableGet:
+        int index = tagByte & Tag.SpecializedPayloadMask;
+        return new VariableGet(variableStack[index]);
+      case Tag.VariableSet:
+        return new VariableSet(readVariableReference(), readExpression());
+      case Tag.SpecializedVariableSet:
+        int index = tagByte & Tag.SpecializedPayloadMask;
+        return new VariableSet(variableStack[index], readExpression());
+      case Tag.PropertyGet:
+        int offset = readOffset();
+        return new PropertyGet(
+            readExpression(), readName(), readMemberReference(allowNull: true))
+          ..fileOffset = offset;
+      case Tag.PropertySet:
+        int offset = readOffset();
+        return new PropertySet(readExpression(), readName(), readExpression(),
+            readMemberReference(allowNull: true))..fileOffset = offset;
+      case Tag.SuperPropertyGet:
+        addTransformerFlag(TransformerFlag.superCalls);
+        return new SuperPropertyGet(
+            readName(), readMemberReference(allowNull: true));
+      case Tag.SuperPropertySet:
+        addTransformerFlag(TransformerFlag.superCalls);
+        return new SuperPropertySet(
+            readName(), readExpression(), readMemberReference(allowNull: true));
+      case Tag.DirectPropertyGet:
+        return new DirectPropertyGet(readExpression(), readMemberReference());
+      case Tag.DirectPropertySet:
+        return new DirectPropertySet(
+            readExpression(), readMemberReference(), readExpression());
+      case Tag.StaticGet:
+        int offset = readOffset();
+        return new StaticGet(readMemberReference())
+          ..fileOffset = offset;
+      case Tag.StaticSet:
+        return new StaticSet(readMemberReference(), readExpression());
+      case Tag.MethodInvocation:
+        int offset = readOffset();
+        return new MethodInvocation(
+            readExpression(),
+            readName(),
+            readArguments(),
+            readMemberReference(allowNull: true))..fileOffset = offset;
+      case Tag.SuperMethodInvocation:
+        int offset = readOffset();
+        addTransformerFlag(TransformerFlag.superCalls);
+        return new SuperMethodInvocation(
+            readName(), readArguments(), readMemberReference(allowNull: true))
+          ..fileOffset = offset;
+      case Tag.DirectMethodInvocation:
+        return new DirectMethodInvocation(
+            readExpression(), readMemberReference(), readArguments());
+      case Tag.StaticInvocation:
+        int offset = readOffset();
+        return new StaticInvocation(readMemberReference(), readArguments(),
+            isConst: false)..fileOffset = offset;
+      case Tag.ConstStaticInvocation:
+        int offset = readOffset();
+        return new StaticInvocation(readMemberReference(), readArguments(),
+            isConst: true)..fileOffset = offset;
+      case Tag.ConstructorInvocation:
+        int offset = readOffset();
+        return new ConstructorInvocation(readMemberReference(), readArguments(),
+            isConst: false)..fileOffset = offset;
+      case Tag.ConstConstructorInvocation:
+        int offset = readOffset();
+        return new ConstructorInvocation(readMemberReference(), readArguments(),
+            isConst: true)..fileOffset = offset;
+      case Tag.Not:
+        return new Not(readExpression());
+      case Tag.LogicalExpression:
+        return new LogicalExpression(readExpression(),
+            logicalOperatorToString(readByte()), readExpression());
+      case Tag.ConditionalExpression:
+        return new ConditionalExpression(readExpression(), readExpression(),
+            readExpression(), readDartTypeOption());
+      case Tag.StringConcatenation:
+        return new StringConcatenation(readExpressionList());
+      case Tag.IsExpression:
+        return new IsExpression(readExpression(), readDartType());
+      case Tag.AsExpression:
+        return new AsExpression(readExpression(), readDartType());
+      case Tag.StringLiteral:
+        return new StringLiteral(readStringReference());
+      case Tag.SpecializedIntLiteral:
+        int biasedValue = tagByte & Tag.SpecializedPayloadMask;
+        return new IntLiteral(biasedValue - Tag.SpecializedIntLiteralBias);
+      case Tag.PositiveIntLiteral:
+        return new IntLiteral(readUInt());
+      case Tag.NegativeIntLiteral:
+        return new IntLiteral(-readUInt());
+      case Tag.BigIntLiteral:
+        return new IntLiteral(int.parse(readStringReference()));
+      case Tag.DoubleLiteral:
+        return new DoubleLiteral(double.parse(readStringReference()));
+      case Tag.TrueLiteral:
+        return new BoolLiteral(true);
+      case Tag.FalseLiteral:
+        return new BoolLiteral(false);
+      case Tag.NullLiteral:
+        return new NullLiteral();
+      case Tag.SymbolLiteral:
+        return new SymbolLiteral(readStringReference());
+      case Tag.TypeLiteral:
+        return new TypeLiteral(readDartType());
+      case Tag.ThisExpression:
+        return new ThisExpression();
+      case Tag.Rethrow:
+        return new Rethrow();
+      case Tag.Throw:
+        int offset = readOffset();
+        return new Throw(readExpression())..fileOffset = offset;
+      case Tag.ListLiteral:
+        var typeArgument = readDartType();
+        return new ListLiteral(readExpressionList(),
+            typeArgument: typeArgument, isConst: false);
+      case Tag.ConstListLiteral:
+        var typeArgument = readDartType();
+        return new ListLiteral(readExpressionList(),
+            typeArgument: typeArgument, isConst: true);
+      case Tag.MapLiteral:
+        var keyType = readDartType();
+        var valueType = readDartType();
+        return new MapLiteral(readMapEntryList(),
+            keyType: keyType, valueType: valueType, isConst: false);
+      case Tag.ConstMapLiteral:
+        var keyType = readDartType();
+        var valueType = readDartType();
+        return new MapLiteral(readMapEntryList(),
+            keyType: keyType, valueType: valueType, isConst: true);
+      case Tag.AwaitExpression:
+        return new AwaitExpression(readExpression());
+      case Tag.FunctionExpression:
+        return new FunctionExpression(readFunctionNode());
+      case Tag.Let:
+        var variable = readVariableDeclaration();
+        int stackHeight = variableStack.length;
+        pushVariableDeclaration(variable);
+        var body = readExpression();
+        variableStack.length = stackHeight;
+        return new Let(variable, body);
+      default:
+        throw fail('Invalid expression tag: $tag');
+    }
+  }
+
+  List<MapEntry> readMapEntryList() {
+    return new List<MapEntry>.generate(readUInt(), (i) => readMapEntry());
+  }
+
+  MapEntry readMapEntry() {
+    return new MapEntry(readExpression(), readExpression());
+  }
+
+  List<Statement> readStatementList() {
+    return new List<Statement>.generate(readUInt(), (i) => readStatement());
+  }
+
+  Statement readStatementOrNullIfEmpty() {
+    var node = readStatement();
+    if (node is EmptyStatement) {
+      return null;
+    } else {
+      return node;
+    }
+  }
+
+  Statement readStatementOption() {
+    return readAndCheckOptionTag() ? readStatement() : null;
+  }
+
+  Statement readStatement() {
+    int tag = readByte();
+    switch (tag) {
+      case Tag.InvalidStatement:
+        return new InvalidStatement();
+      case Tag.ExpressionStatement:
+        return new ExpressionStatement(readExpression());
+      case Tag.Block:
+        return readBlock();
+      case Tag.EmptyStatement:
+        return new EmptyStatement();
+      case Tag.AssertStatement:
+        return new AssertStatement(readExpression(), readExpressionOption());
+      case Tag.LabeledStatement:
+        var label = new LabeledStatement(null);
+        labelStack.add(label);
+        label.body = readStatement()..parent = label;
+        labelStack.removeLast();
+        return label;
+      case Tag.BreakStatement:
+        int index = readUInt();
+        return new BreakStatement(labelStack[labelStackBase + index]);
+      case Tag.WhileStatement:
+        return new WhileStatement(readExpression(), readStatement());
+      case Tag.DoStatement:
+        return new DoStatement(readStatement(), readExpression());
+      case Tag.ForStatement:
+        int variableStackHeight = variableStack.length;
+        var variables = readAndPushVariableDeclarationList();
+        var condition = readExpressionOption();
+        var updates = readExpressionList();
+        var body = readStatement();
+        variableStack.length = variableStackHeight;
+        return new ForStatement(variables, condition, updates, body);
+      case Tag.ForInStatement:
+      case Tag.AsyncForInStatement:
+        bool isAsync = tag == Tag.AsyncForInStatement;
+        int variableStackHeight = variableStack.length;
+        var variable = readAndPushVariableDeclaration();
+        var iterable = readExpression();
+        var body = readStatement();
+        variableStack.length = variableStackHeight;
+        return new ForInStatement(variable, iterable, body, isAsync: isAsync);
+      case Tag.SwitchStatement:
+        var expression = readExpression();
+        int count = readUInt();
+        List<SwitchCase> cases =
+            new List<SwitchCase>.generate(count, (i) => new SwitchCase.empty());
+        switchCaseStack.addAll(cases);
+        for (int i = 0; i < cases.length; ++i) {
+          var caseNode = cases[i];
+          _fillTreeNodeList(caseNode.expressions, readExpression, caseNode);
+          caseNode.isDefault = readByte() == 1;
+          caseNode.body = readStatement()..parent = caseNode;
+        }
+        switchCaseStack.length -= count;
+        return new SwitchStatement(expression, cases);
+      case Tag.ContinueSwitchStatement:
+        int index = readUInt();
+        return new ContinueSwitchStatement(switchCaseStack[index]);
+      case Tag.IfStatement:
+        return new IfStatement(
+            readExpression(), readStatement(), readStatementOrNullIfEmpty());
+      case Tag.ReturnStatement:
+        return new ReturnStatement(readExpressionOption());
+      case Tag.TryCatch:
+        return new TryCatch(readStatement(), readCatchList());
+      case Tag.TryFinally:
+        return new TryFinally(readStatement(), readStatement());
+      case Tag.YieldStatement:
+        int flags = readByte();
+        return new YieldStatement(readExpression(),
+            isYieldStar: flags & YieldStatement.FlagYieldStar != 0,
+            isNative: flags & YieldStatement.FlagNative != 0);
+      case Tag.VariableDeclaration:
+        var variable = readVariableDeclaration();
+        variableStack.add(variable); // Will be popped by the enclosing scope.
+        return variable;
+      case Tag.FunctionDeclaration:
+        var variable = readVariableDeclaration();
+        variableStack.add(variable); // Will be popped by the enclosing scope.
+        var function = readFunctionNode();
+        return new FunctionDeclaration(variable, function);
+      default:
+        throw fail('Invalid statement tag: $tag');
+    }
+  }
+
+  List<Catch> readCatchList() {
+    return new List<Catch>.generate(readUInt(), (i) => readCatch());
+  }
+
+  Catch readCatch() {
+    int variableStackHeight = variableStack.length;
+    var guard = readDartType();
+    var exception = readAndPushVariableDeclarationOption();
+    var stackTrace = readAndPushVariableDeclarationOption();
+    var body = readStatement();
+    variableStack.length = variableStackHeight;
+    return new Catch(exception, body, guard: guard, stackTrace: stackTrace);
+  }
+
+  Block readBlock() {
+    int stackHeight = variableStack.length;
+    var body = readStatementList();
+    variableStack.length = stackHeight;
+    return new Block(body);
+  }
+
+  Supertype readSupertype() {
+    InterfaceType type = readDartType();
+    return new Supertype(type.classNode, type.typeArguments);
+  }
+
+  Supertype readSupertypeOption() {
+    return readAndCheckOptionTag() ? readSupertype() : null;
+  }
+
+  List<Supertype> readSupertypeList() {
+    return new List<Supertype>.generate(readUInt(), (i) => readSupertype());
+  }
+
+  List<DartType> readDartTypeList() {
+    return new List<DartType>.generate(readUInt(), (i) => readDartType());
+  }
+
+  List<NamedType> readNamedTypeList() {
+    return new List<NamedType>.generate(readUInt(), (i) => readNamedType());
+  }
+
+  NamedType readNamedType() {
+    return new NamedType(readStringReference(), readDartType());
+  }
+
+  DartType readDartTypeOption() {
+    return readAndCheckOptionTag() ? readDartType() : null;
+  }
+
+  DartType readDartType() {
+    int tag = readByte();
+    switch (tag) {
+      case Tag.BottomType:
+        return const BottomType();
+      case Tag.InvalidType:
+        return const InvalidType();
+      case Tag.DynamicType:
+        return const DynamicType();
+      case Tag.VoidType:
+        return const VoidType();
+      case Tag.InterfaceType:
+        return new InterfaceType(readClassReference(), readDartTypeList());
+      case Tag.SimpleInterfaceType:
+        return new InterfaceType(readClassReference(), const <DartType>[]);
+      case Tag.FunctionType:
+        int typeParameterStackHeight = typeParameterStack.length;
+        var typeParameters = readAndPushTypeParameterList();
+        var requiredParameterCount = readUInt();
+        var positional = readDartTypeList();
+        var named = readNamedTypeList();
+        var returnType = readDartType();
+        typeParameterStack.length = typeParameterStackHeight;
+        return new FunctionType(positional, returnType,
+            typeParameters: typeParameters,
+            requiredParameterCount: requiredParameterCount,
+            namedParameters: named);
+      case Tag.SimpleFunctionType:
+        var positional = readDartTypeList();
+        var returnType = readDartType();
+        return new FunctionType(positional, returnType);
+      case Tag.TypeParameterType:
+        int index = readUInt();
+        return new TypeParameterType(typeParameterStack[index]);
+      default:
+        throw fail('Invalid dart type tag: $tag');
+    }
+  }
+
+  List<TypeParameter> readAndPushTypeParameterList(
+      [List<TypeParameter> list, TreeNode parent]) {
+    int length = readUInt();
+    if (length == 0) return list ?? <TypeParameter>[];
+    if (list == null) {
+      list = new List<TypeParameter>.generate(
+          length, (i) => new TypeParameter(null, null)..parent = parent);
+    } else {
+      list.length = length;
+      for (int i = 0; i < length; ++i) {
+        list[i] = new TypeParameter(null, null)..parent = parent;
+      }
+    }
+    typeParameterStack.addAll(list);
+    for (int i = 0; i < list.length; ++i) {
+      readTypeParameter(list[i]);
+    }
+    return list;
+  }
+
+  void readTypeParameter(TypeParameter node) {
+    node.name = readStringOrNullIfEmpty();
+    node.bound = readDartType();
+  }
+
+  Arguments readArguments() {
+    var typeArguments = readDartTypeList();
+    var positional = readExpressionList();
+    var named = readNamedExpressionList();
+    return new Arguments(positional, types: typeArguments, named: named);
+  }
+
+  List<NamedExpression> readNamedExpressionList() {
+    return new List<NamedExpression>.generate(
+        readUInt(), (i) => readNamedExpression());
+  }
+
+  NamedExpression readNamedExpression() {
+    return new NamedExpression(readStringReference(), readExpression());
+  }
+
+  List<VariableDeclaration> readAndPushVariableDeclarationList() {
+    return new List<VariableDeclaration>.generate(
+        readUInt(), (i) => readAndPushVariableDeclaration());
+  }
+
+  VariableDeclaration readAndPushVariableDeclarationOption() {
+    return readAndCheckOptionTag() ? readAndPushVariableDeclaration() : null;
+  }
+
+  VariableDeclaration readAndPushVariableDeclaration() {
+    var variable = readVariableDeclaration();
+    variableStack.add(variable);
+    return variable;
+  }
+
+  VariableDeclaration readVariableDeclaration() {
+    int flags = readByte();
+    return new VariableDeclaration(readStringOrNullIfEmpty(),
+        type: readDartType(),
+        inferredValue: readOptionalInferredValue(),
+        initializer: readExpressionOption(),
+        isFinal: flags & 0x1 != 0,
+        isConst: flags & 0x2 != 0);
+  }
+
+  int readOffset() {
+    // Offset is saved as unsigned,
+    // but actually ranges from -1 and up (thus the -1)
+    return readUInt() - 1;
+  }
+}
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
new file mode 100644
index 0000000..68f3687
--- /dev/null
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -0,0 +1,1226 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.ast_to_binary;
+
+import '../ast.dart';
+import '../import_table.dart';
+import 'tag.dart';
+import 'dart:convert';
+import 'dart:typed_data';
+import 'dart:collection';
+
+/// Writes to a binary file.
+///
+/// A [BinaryPrinter] can be used to write one file and must then be
+/// discarded.
+class BinaryPrinter extends Visitor {
+  ImportTable _importTable;
+
+  VariableIndexer _variableIndexer;
+  LabelIndexer _labelIndexer;
+  SwitchCaseIndexer _switchCaseIndexer;
+  final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
+  final GlobalIndexer _globalIndexer;
+  final StringIndexer _stringIndexer = new StringIndexer();
+  final StringIndexer _sourceUriIndexer = new StringIndexer();
+
+  final BufferedSink _sink;
+
+  /// Create a printer that writes to the given [sink].
+  ///
+  /// The BinaryPrinter will use its own buffer, so the [sink] does not need
+  /// one.
+  ///
+  /// If multiple binaries are to be written based on the same IR, a shared
+  /// [globalIndexer] may be passed in to avoid rebuilding the same indices
+  /// in every printer.
+  BinaryPrinter(Sink<List<int>> sink, {GlobalIndexer globalIndexer})
+      : _sink = new BufferedSink(sink),
+        _globalIndexer = globalIndexer ?? new GlobalIndexer();
+
+  void _flush() {
+    _sink.flushAndDestroy();
+  }
+
+  void writeByte(int byte) {
+    _sink.addByte(byte);
+  }
+
+  void writeBytes(List<int> bytes) {
+    _sink.addBytes(bytes);
+  }
+
+  void writeUInt30(int value) {
+    assert(value >= 0 && value >> 30 == 0);
+    if (value < 0x80) {
+      writeByte(value);
+    } else if (value < 0x4000) {
+      writeByte((value >> 8) | 0x80);
+      writeByte(value & 0xFF);
+    } else {
+      writeByte((value >> 24) | 0xC0);
+      writeByte((value >> 16) & 0xFF);
+      writeByte((value >> 8) & 0xFF);
+      writeByte(value & 0xFF);
+    }
+  }
+
+  void writeMagicWord(int value) {
+    writeByte((value >> 24) & 0xFF);
+    writeByte((value >> 16) & 0xFF);
+    writeByte((value >> 8) & 0xFF);
+    writeByte(value & 0xFF);
+  }
+
+  void writeStringTableEntry(String string) {
+    List<int> utf8Bytes = const Utf8Encoder().convert(string);
+    writeUInt30(utf8Bytes.length);
+    writeBytes(utf8Bytes);
+  }
+
+  void writeStringTable(StringIndexer indexer) {
+    writeUInt30(indexer.numberOfStrings);
+    for (var entry in indexer.entries) {
+      writeStringTableEntry(entry.value);
+    }
+  }
+
+  void writeStringReference(String string) {
+    writeUInt30(_stringIndexer[string]);
+  }
+
+  void writeUriReference(String string) {
+    int index = _sourceUriIndexer[string];
+    if (index == null) {
+      // Assume file was loaded without linking. Bail out to empty string.
+      index = _sourceUriIndexer[""];
+    }
+    writeUInt30(index);
+  }
+
+  void writeList(List items, writeItem(x)) {
+    writeUInt30(items.length);
+    items.forEach(writeItem);
+  }
+
+  void writeNodeList(List<Node> nodes) {
+    writeList(nodes, writeNode);
+  }
+
+  void writeNode(Node node) {
+    node.accept(this);
+  }
+
+  void writeOptionalNode(Node node) {
+    if (node == null) {
+      writeByte(Tag.Nothing);
+    } else {
+      writeByte(Tag.Something);
+      writeNode(node);
+    }
+  }
+
+  void writeOptionalInferredValue(InferredValue node) {
+    if (node == null) {
+      writeByte(Tag.Nothing);
+    } else {
+      writeByte(Tag.Something);
+      writeClassReference(node.baseClass, allowNull: true);
+      writeByte(node.baseClassKind.index);
+      writeByte(node.valueBits);
+    }
+  }
+
+  void writeProgramFile(Program program) {
+    writeMagicWord(Tag.ProgramFile);
+    _importTable = new ProgramImportTable(program);
+    _stringIndexer.build(program);
+    writeStringTable(_stringIndexer);
+    writeUriToLineStarts(program);
+    writeList(program.libraries, writeNode);
+    writeMemberReference(program.mainMethod, allowNull: true);
+    _flush();
+  }
+
+  void writeUriToLineStarts(Program program) {
+    program.uriToLineStarts.keys.forEach((uri) {
+      _sourceUriIndexer.put(uri);
+    });
+    writeStringTable(_sourceUriIndexer);
+    for (int i = 0; i < _sourceUriIndexer.entries.length; i++) {
+      String uri = _sourceUriIndexer.entries[i].value;
+      List<int> lineStarts = program.uriToLineStarts[uri] ?? [];
+      writeUInt30(lineStarts.length);
+      int previousLineStart = 0;
+      lineStarts.forEach((lineStart) {
+        writeUInt30(lineStart - previousLineStart);
+        previousLineStart = lineStart;
+      });
+    }
+  }
+
+  void writeLibraryImportTable(LibraryImportTable imports) {
+    writeList(imports.importPaths, writeStringReference);
+  }
+
+  void writeLibraryReference(Library node) {
+    int index = _importTable.getImportIndex(node);
+    if (index == -1) {
+      throw 'Missing import for library: ${node.importUri}';
+    }
+    writeUInt30(index);
+  }
+
+  void writeClassIndex(Class node) {
+    writeUInt30(_globalIndexer[node]);
+  }
+
+  void writeClassReference(Class node, {bool allowNull: false}) {
+    if (node == null) {
+      if (allowNull) {
+        writeByte(Tag.NullReference);
+      } else {
+        throw 'Expected a class reference to be valid but was `null`.';
+      }
+    } else {
+      node.acceptReference(this);
+    }
+  }
+
+  void writeMemberReference(Member node, {bool allowNull: false}) {
+    if (node == null) {
+      if (allowNull) {
+        writeByte(Tag.NullReference);
+      } else {
+        throw 'Expected a member reference to be valid but was `null`.';
+      }
+    } else {
+      node.acceptReference(this);
+    }
+  }
+
+  writeOffset(TreeNode node) {
+    // TODO(jensj): Delta-encoding.
+    // File offset ranges from -1 and up,
+    // but is here saved as unsigned (thus the +1)
+    writeUInt30(node.fileOffset + 1);
+  }
+
+  void visitClassReference(Class node) {
+    var library = node.enclosingLibrary;
+    writeByte(node.isMixinApplication
+        ? Tag.MixinClassReference
+        : Tag.NormalClassReference);
+    writeLibraryReference(library);
+    writeClassIndex(node);
+  }
+
+  void visitFieldReference(Field node) {
+    if (node.enclosingClass != null) {
+      writeByte(Tag.ClassFieldReference);
+      Class classNode = node.enclosingClass;
+      writeClassReference(classNode);
+      writeUInt30(_globalIndexer[node]);
+    } else {
+      writeByte(Tag.LibraryFieldReference);
+      writeLibraryReference(node.enclosingLibrary);
+      writeUInt30(_globalIndexer[node]);
+    }
+  }
+
+  void visitConstructorReference(Constructor node) {
+    writeByte(Tag.ClassConstructorReference);
+    writeClassReference(node.enclosingClass);
+    writeUInt30(_globalIndexer[node]);
+  }
+
+  void visitProcedureReference(Procedure node) {
+    if (node.enclosingClass != null) {
+      writeByte(Tag.ClassProcedureReference);
+      Class classNode = node.enclosingClass;
+      writeClassReference(classNode);
+      writeUInt30(_globalIndexer[node]);
+    } else {
+      writeByte(Tag.LibraryProcedureReference);
+      writeLibraryReference(node.enclosingLibrary);
+      writeUInt30(_globalIndexer[node]);
+    }
+  }
+
+  void writeName(Name node) {
+    writeStringReference(node.name);
+    // TODO: Consider a more compressed format for private names within the
+    // enclosing library.
+    if (node.isPrivate) {
+      writeLibraryReference(node.library);
+    }
+  }
+
+  bool insideExternalLibrary = false;
+
+  visitLibrary(Library node) {
+    insideExternalLibrary = node.isExternal;
+    writeByte(insideExternalLibrary ? 1 : 0);
+    writeStringReference(node.name ?? '');
+    writeStringReference('${node.importUri}');
+    // TODO(jensj): We save (almost) the same URI twice.
+    writeUriReference(node.fileUri ?? '');
+    writeNodeList(node.classes);
+    writeNodeList(node.fields);
+    writeNodeList(node.procedures);
+  }
+
+  void writeAnnotation(Expression annotation) {
+    _variableIndexer ??= new VariableIndexer();
+    writeNode(annotation);
+  }
+
+  void writeAnnotationList(List<Expression> annotations) {
+    writeList(annotations, writeAnnotation);
+  }
+
+  visitClass(Class node) {
+    int flags = node.isAbstract ? 1 : 0;
+    if (node.level == ClassLevel.Type) {
+      flags |= 0x2;
+    }
+    if (node.isMixinApplication) {
+      writeByte(Tag.MixinClass);
+      writeByte(flags);
+      writeStringReference(node.name ?? '');
+      writeUriReference(node.fileUri ?? '');
+      writeAnnotationList(node.annotations);
+      _typeParameterIndexer.enter(node.typeParameters);
+      writeNodeList(node.typeParameters);
+      writeNode(node.supertype);
+      writeNode(node.mixedInType);
+      writeNodeList(node.implementedTypes);
+      writeNodeList(node.constructors);
+      _typeParameterIndexer.exit(node.typeParameters);
+    } else {
+      writeByte(Tag.NormalClass);
+      writeByte(flags);
+      writeStringReference(node.name ?? '');
+      writeUriReference(node.fileUri ?? '');
+      writeAnnotationList(node.annotations);
+      _typeParameterIndexer.enter(node.typeParameters);
+      writeNodeList(node.typeParameters);
+      writeOptionalNode(node.supertype);
+      writeNodeList(node.implementedTypes);
+      writeNodeList(node.fields);
+      writeNodeList(node.constructors);
+      writeNodeList(node.procedures);
+      _typeParameterIndexer.exit(node.typeParameters);
+    }
+  }
+
+  static final Name _emptyName = new Name('');
+
+  visitConstructor(Constructor node) {
+    _variableIndexer = new VariableIndexer();
+    writeByte(Tag.Constructor);
+    writeByte(node.flags);
+    writeName(node.name ?? _emptyName);
+    writeAnnotationList(node.annotations);
+    assert(node.function.typeParameters.isEmpty);
+    writeNode(node.function);
+    // Parameters are in scope in the initializers.
+    _variableIndexer.restoreScope(node.function.positionalParameters.length +
+        node.function.namedParameters.length);
+    writeNodeList(node.initializers);
+    _variableIndexer = null;
+  }
+
+  visitProcedure(Procedure node) {
+    _variableIndexer = new VariableIndexer();
+    writeByte(Tag.Procedure);
+    writeByte(node.kind.index);
+    writeByte(node.flags);
+    writeName(node.name ?? '');
+    writeUriReference(node.fileUri ?? '');
+    writeAnnotationList(node.annotations);
+    writeOptionalNode(node.function);
+    _variableIndexer = null;
+  }
+
+  visitField(Field node) {
+    _variableIndexer = new VariableIndexer();
+    writeByte(Tag.Field);
+    writeOffset(node);
+    writeByte(node.flags);
+    writeName(node.name ?? '');
+    writeUriReference(node.fileUri ?? '');
+    writeAnnotationList(node.annotations);
+    writeNode(node.type);
+    writeOptionalInferredValue(node.inferredValue);
+    writeOptionalNode(node.initializer);
+    _variableIndexer = null;
+  }
+
+  visitInvalidInitializer(InvalidInitializer node) {
+    writeByte(Tag.InvalidInitializer);
+  }
+
+  visitFieldInitializer(FieldInitializer node) {
+    writeByte(Tag.FieldInitializer);
+    writeMemberReference(node.field);
+    writeNode(node.value);
+  }
+
+  visitSuperInitializer(SuperInitializer node) {
+    writeByte(Tag.SuperInitializer);
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitRedirectingInitializer(RedirectingInitializer node) {
+    writeByte(Tag.RedirectingInitializer);
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitLocalInitializer(LocalInitializer node) {
+    writeByte(Tag.LocalInitializer);
+    writeVariableDeclaration(node.variable);
+  }
+
+  visitFunctionNode(FunctionNode node) {
+    assert(_variableIndexer != null);
+    _variableIndexer.pushScope();
+    var oldLabels = _labelIndexer;
+    _labelIndexer = new LabelIndexer();
+    var oldCases = _switchCaseIndexer;
+    _switchCaseIndexer = new SwitchCaseIndexer();
+    // Note: FunctionNode has no tag.
+    _typeParameterIndexer.enter(node.typeParameters);
+    writeByte(node.asyncMarker.index);
+    writeNodeList(node.typeParameters);
+    writeUInt30(node.requiredParameterCount);
+    writeVariableDeclarationList(node.positionalParameters);
+    writeVariableDeclarationList(node.namedParameters);
+    writeNode(node.returnType);
+    writeOptionalInferredValue(node.inferredReturnValue);
+    writeOptionalNode(node.body);
+    _labelIndexer = oldLabels;
+    _switchCaseIndexer = oldCases;
+    _typeParameterIndexer.exit(node.typeParameters);
+    _variableIndexer.popScope();
+  }
+
+  visitInvalidExpression(InvalidExpression node) {
+    writeByte(Tag.InvalidExpression);
+  }
+
+  visitVariableGet(VariableGet node) {
+    assert(_variableIndexer != null);
+    int index = _variableIndexer[node.variable];
+    assert(index != null);
+    if (index & Tag.SpecializedPayloadMask == index &&
+        node.promotedType == null) {
+      writeByte(Tag.SpecializedVariableGet + index);
+    } else {
+      writeByte(Tag.VariableGet);
+      writeUInt30(_variableIndexer[node.variable]);
+      writeOptionalNode(node.promotedType);
+    }
+  }
+
+  visitVariableSet(VariableSet node) {
+    assert(_variableIndexer != null);
+    int index = _variableIndexer[node.variable];
+    if (index & Tag.SpecializedPayloadMask == index) {
+      writeByte(Tag.SpecializedVariableSet + index);
+      writeNode(node.value);
+    } else {
+      writeByte(Tag.VariableSet);
+      writeUInt30(_variableIndexer[node.variable]);
+      writeNode(node.value);
+    }
+  }
+
+  visitPropertyGet(PropertyGet node) {
+    writeByte(Tag.PropertyGet);
+    writeOffset(node);
+    writeNode(node.receiver);
+    writeName(node.name);
+    writeMemberReference(node.interfaceTarget, allowNull: true);
+  }
+
+  visitPropertySet(PropertySet node) {
+    writeByte(Tag.PropertySet);
+    writeOffset(node);
+    writeNode(node.receiver);
+    writeName(node.name);
+    writeNode(node.value);
+    writeMemberReference(node.interfaceTarget, allowNull: true);
+  }
+
+  visitSuperPropertyGet(SuperPropertyGet node) {
+    writeByte(Tag.SuperPropertyGet);
+    writeName(node.name);
+    writeMemberReference(node.interfaceTarget, allowNull: true);
+  }
+
+  visitSuperPropertySet(SuperPropertySet node) {
+    writeByte(Tag.SuperPropertySet);
+    writeName(node.name);
+    writeNode(node.value);
+    writeMemberReference(node.interfaceTarget, allowNull: true);
+  }
+
+  visitDirectPropertyGet(DirectPropertyGet node) {
+    writeByte(Tag.DirectPropertyGet);
+    writeNode(node.receiver);
+    writeMemberReference(node.target);
+  }
+
+  visitDirectPropertySet(DirectPropertySet node) {
+    writeByte(Tag.DirectPropertySet);
+    writeNode(node.receiver);
+    writeMemberReference(node.target);
+    writeNode(node.value);
+  }
+
+  visitStaticGet(StaticGet node) {
+    writeByte(Tag.StaticGet);
+    writeOffset(node);
+    writeMemberReference(node.target);
+  }
+
+  visitStaticSet(StaticSet node) {
+    writeByte(Tag.StaticSet);
+    writeMemberReference(node.target);
+    writeNode(node.value);
+  }
+
+  visitMethodInvocation(MethodInvocation node) {
+    writeByte(Tag.MethodInvocation);
+    writeOffset(node);
+    writeNode(node.receiver);
+    writeName(node.name);
+    writeNode(node.arguments);
+    writeMemberReference(node.interfaceTarget, allowNull: true);
+  }
+
+  visitSuperMethodInvocation(SuperMethodInvocation node) {
+    writeByte(Tag.SuperMethodInvocation);
+    writeOffset(node);
+    writeName(node.name);
+    writeNode(node.arguments);
+    writeMemberReference(node.interfaceTarget, allowNull: true);
+  }
+
+  visitDirectMethodInvocation(DirectMethodInvocation node) {
+    writeByte(Tag.DirectMethodInvocation);
+    writeNode(node.receiver);
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitStaticInvocation(StaticInvocation node) {
+    writeByte(node.isConst ? Tag.ConstStaticInvocation : Tag.StaticInvocation);
+    writeOffset(node);
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitConstructorInvocation(ConstructorInvocation node) {
+    writeByte(node.isConst
+        ? Tag.ConstConstructorInvocation
+        : Tag.ConstructorInvocation);
+    writeOffset(node);
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitArguments(Arguments node) {
+    writeNodeList(node.types);
+    writeNodeList(node.positional);
+    writeNodeList(node.named);
+  }
+
+  visitNamedExpression(NamedExpression node) {
+    writeStringReference(node.name);
+    writeNode(node.value);
+  }
+
+  visitNot(Not node) {
+    writeByte(Tag.Not);
+    writeNode(node.operand);
+  }
+
+  int logicalOperatorIndex(String operator) {
+    switch (operator) {
+      case '&&':
+        return 0;
+      case '||':
+        return 1;
+    }
+    throw 'Not a logical operator: $operator';
+  }
+
+  visitLogicalExpression(LogicalExpression node) {
+    writeByte(Tag.LogicalExpression);
+    writeNode(node.left);
+    writeByte(logicalOperatorIndex(node.operator));
+    writeNode(node.right);
+  }
+
+  visitConditionalExpression(ConditionalExpression node) {
+    writeByte(Tag.ConditionalExpression);
+    writeNode(node.condition);
+    writeNode(node.then);
+    writeNode(node.otherwise);
+    writeOptionalNode(node.staticType);
+  }
+
+  visitStringConcatenation(StringConcatenation node) {
+    writeByte(Tag.StringConcatenation);
+    writeNodeList(node.expressions);
+  }
+
+  visitIsExpression(IsExpression node) {
+    writeByte(Tag.IsExpression);
+    writeNode(node.operand);
+    writeNode(node.type);
+  }
+
+  visitAsExpression(AsExpression node) {
+    writeByte(Tag.AsExpression);
+    writeNode(node.operand);
+    writeNode(node.type);
+  }
+
+  visitStringLiteral(StringLiteral node) {
+    writeByte(Tag.StringLiteral);
+    writeStringReference(node.value);
+  }
+
+  visitIntLiteral(IntLiteral node) {
+    int value = node.value;
+    int biasedValue = value + Tag.SpecializedIntLiteralBias;
+    if (biasedValue >= 0 &&
+        biasedValue & Tag.SpecializedPayloadMask == biasedValue) {
+      writeByte(Tag.SpecializedIntLiteral + biasedValue);
+    } else if (value.abs() >> 30 == 0) {
+      if (value < 0) {
+        writeByte(Tag.NegativeIntLiteral);
+        writeUInt30(-value);
+      } else {
+        writeByte(Tag.PositiveIntLiteral);
+        writeUInt30(value);
+      }
+    } else {
+      // TODO: Pick a better format for big int literals.
+      writeByte(Tag.BigIntLiteral);
+      writeStringReference('${node.value}');
+    }
+  }
+
+  visitDoubleLiteral(DoubleLiteral node) {
+    // TODO: Pick a better format for double literals.
+    writeByte(Tag.DoubleLiteral);
+    writeStringReference('${node.value}');
+  }
+
+  visitBoolLiteral(BoolLiteral node) {
+    writeByte(node.value ? Tag.TrueLiteral : Tag.FalseLiteral);
+  }
+
+  visitNullLiteral(NullLiteral node) {
+    writeByte(Tag.NullLiteral);
+  }
+
+  visitSymbolLiteral(SymbolLiteral node) {
+    writeByte(Tag.SymbolLiteral);
+    writeStringReference(node.value);
+  }
+
+  visitTypeLiteral(TypeLiteral node) {
+    writeByte(Tag.TypeLiteral);
+    writeNode(node.type);
+  }
+
+  visitThisExpression(ThisExpression node) {
+    writeByte(Tag.ThisExpression);
+  }
+
+  visitRethrow(Rethrow node) {
+    writeByte(Tag.Rethrow);
+  }
+
+  visitThrow(Throw node) {
+    writeByte(Tag.Throw);
+    writeOffset(node);
+    writeNode(node.expression);
+  }
+
+  visitListLiteral(ListLiteral node) {
+    writeByte(node.isConst ? Tag.ConstListLiteral : Tag.ListLiteral);
+    writeNode(node.typeArgument);
+    writeNodeList(node.expressions);
+  }
+
+  visitMapLiteral(MapLiteral node) {
+    writeByte(node.isConst ? Tag.ConstMapLiteral : Tag.MapLiteral);
+    writeNode(node.keyType);
+    writeNode(node.valueType);
+    writeNodeList(node.entries);
+  }
+
+  visitMapEntry(MapEntry node) {
+    // Note: there is no tag on MapEntry
+    writeNode(node.key);
+    writeNode(node.value);
+  }
+
+  visitAwaitExpression(AwaitExpression node) {
+    writeByte(Tag.AwaitExpression);
+    writeNode(node.operand);
+  }
+
+  visitFunctionExpression(FunctionExpression node) {
+    writeByte(Tag.FunctionExpression);
+    writeNode(node.function);
+  }
+
+  visitLet(Let node) {
+    writeByte(Tag.Let);
+    writeVariableDeclaration(node.variable);
+    writeNode(node.body);
+    --_variableIndexer.stackHeight;
+  }
+
+  writeStatementOrEmpty(Statement node) {
+    if (node == null) {
+      writeByte(Tag.EmptyStatement);
+    } else {
+      writeNode(node);
+    }
+  }
+
+  visitInvalidStatement(InvalidStatement node) {
+    writeByte(Tag.InvalidStatement);
+  }
+
+  visitExpressionStatement(ExpressionStatement node) {
+    writeByte(Tag.ExpressionStatement);
+    writeNode(node.expression);
+  }
+
+  visitBlock(Block node) {
+    _variableIndexer.pushScope();
+    writeByte(Tag.Block);
+    writeNodeList(node.statements);
+    _variableIndexer.popScope();
+  }
+
+  visitEmptyStatement(EmptyStatement node) {
+    writeByte(Tag.EmptyStatement);
+  }
+
+  visitAssertStatement(AssertStatement node) {
+    writeByte(Tag.AssertStatement);
+    writeNode(node.condition);
+    writeOptionalNode(node.message);
+  }
+
+  visitLabeledStatement(LabeledStatement node) {
+    _labelIndexer.enter(node);
+    writeByte(Tag.LabeledStatement);
+    writeNode(node.body);
+    _labelIndexer.exit();
+  }
+
+  visitBreakStatement(BreakStatement node) {
+    writeByte(Tag.BreakStatement);
+    writeUInt30(_labelIndexer[node.target]);
+  }
+
+  visitWhileStatement(WhileStatement node) {
+    writeByte(Tag.WhileStatement);
+    writeNode(node.condition);
+    writeNode(node.body);
+  }
+
+  visitDoStatement(DoStatement node) {
+    writeByte(Tag.DoStatement);
+    writeNode(node.body);
+    writeNode(node.condition);
+  }
+
+  visitForStatement(ForStatement node) {
+    _variableIndexer.pushScope();
+    writeByte(Tag.ForStatement);
+    writeVariableDeclarationList(node.variables);
+    writeOptionalNode(node.condition);
+    writeNodeList(node.updates);
+    writeNode(node.body);
+    _variableIndexer.popScope();
+  }
+
+  visitForInStatement(ForInStatement node) {
+    _variableIndexer.pushScope();
+    writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement);
+    writeVariableDeclaration(node.variable);
+    writeNode(node.iterable);
+    writeNode(node.body);
+    _variableIndexer.popScope();
+  }
+
+  visitSwitchStatement(SwitchStatement node) {
+    _switchCaseIndexer.enter(node);
+    writeByte(Tag.SwitchStatement);
+    writeNode(node.expression);
+    writeNodeList(node.cases);
+    _switchCaseIndexer.exit(node);
+  }
+
+  visitSwitchCase(SwitchCase node) {
+    // Note: there is no tag on SwitchCase.
+    writeNodeList(node.expressions);
+    writeByte(node.isDefault ? 1 : 0);
+    writeNode(node.body);
+  }
+
+  visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    writeByte(Tag.ContinueSwitchStatement);
+    writeUInt30(_switchCaseIndexer[node.target]);
+  }
+
+  visitIfStatement(IfStatement node) {
+    writeByte(Tag.IfStatement);
+    writeNode(node.condition);
+    writeNode(node.then);
+    writeStatementOrEmpty(node.otherwise);
+  }
+
+  visitReturnStatement(ReturnStatement node) {
+    writeByte(Tag.ReturnStatement);
+    writeOptionalNode(node.expression);
+  }
+
+  visitTryCatch(TryCatch node) {
+    writeByte(Tag.TryCatch);
+    writeNode(node.body);
+    writeNodeList(node.catches);
+  }
+
+  visitCatch(Catch node) {
+    // Note: there is no tag on Catch.
+    _variableIndexer.pushScope();
+    writeNode(node.guard);
+    writeOptionalVariableDeclaration(node.exception);
+    writeOptionalVariableDeclaration(node.stackTrace);
+    writeNode(node.body);
+    _variableIndexer.popScope();
+  }
+
+  visitTryFinally(TryFinally node) {
+    writeByte(Tag.TryFinally);
+    writeNode(node.body);
+    writeNode(node.finalizer);
+  }
+
+  visitYieldStatement(YieldStatement node) {
+    writeByte(Tag.YieldStatement);
+    writeByte(node.flags);
+    writeNode(node.expression);
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    writeByte(Tag.VariableDeclaration);
+    writeVariableDeclaration(node);
+  }
+
+  void writeVariableDeclaration(VariableDeclaration node) {
+    writeByte(node.flags);
+    writeStringReference(node.name ?? '');
+    writeNode(node.type);
+    writeOptionalInferredValue(node.inferredValue);
+    writeOptionalNode(node.initializer);
+    // Declare the variable after its initializer. It is not in scope in its
+    // own initializer.
+    _variableIndexer.declare(node);
+  }
+
+  void writeVariableDeclarationList(List<VariableDeclaration> nodes) {
+    writeList(nodes, writeVariableDeclaration);
+  }
+
+  void writeOptionalVariableDeclaration(VariableDeclaration node) {
+    if (node == null) {
+      writeByte(Tag.Nothing);
+    } else {
+      writeByte(Tag.Something);
+      writeVariableDeclaration(node);
+    }
+  }
+
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    writeByte(Tag.FunctionDeclaration);
+    writeVariableDeclaration(node.variable);
+    writeNode(node.function);
+  }
+
+  visitBottomType(BottomType node) {
+    writeByte(Tag.BottomType);
+  }
+
+  visitInvalidType(InvalidType node) {
+    writeByte(Tag.InvalidType);
+  }
+
+  visitDynamicType(DynamicType node) {
+    writeByte(Tag.DynamicType);
+  }
+
+  visitVoidType(VoidType node) {
+    writeByte(Tag.VoidType);
+  }
+
+  visitInterfaceType(InterfaceType node) {
+    if (node.typeArguments.isEmpty) {
+      writeByte(Tag.SimpleInterfaceType);
+      writeClassReference(node.classNode);
+    } else {
+      writeByte(Tag.InterfaceType);
+      writeClassReference(node.classNode);
+      writeNodeList(node.typeArguments);
+    }
+  }
+
+  visitSupertype(Supertype node) {
+    if (node.typeArguments.isEmpty) {
+      writeByte(Tag.SimpleInterfaceType);
+      writeClassReference(node.classNode);
+    } else {
+      writeByte(Tag.InterfaceType);
+      writeClassReference(node.classNode);
+      writeNodeList(node.typeArguments);
+    }
+  }
+
+  visitFunctionType(FunctionType node) {
+    if (node.requiredParameterCount == node.positionalParameters.length &&
+        node.typeParameters.isEmpty &&
+        node.namedParameters.isEmpty) {
+      writeByte(Tag.SimpleFunctionType);
+      writeNodeList(node.positionalParameters);
+      writeNode(node.returnType);
+    } else {
+      writeByte(Tag.FunctionType);
+      _typeParameterIndexer.enter(node.typeParameters);
+      writeNodeList(node.typeParameters);
+      writeUInt30(node.requiredParameterCount);
+      writeNodeList(node.positionalParameters);
+      writeNodeList(node.namedParameters);
+      writeNode(node.returnType);
+      _typeParameterIndexer.exit(node.typeParameters);
+    }
+  }
+
+  visitNamedType(NamedType node) {
+    writeStringReference(node.name);
+    writeNode(node.type);
+  }
+
+  visitTypeParameterType(TypeParameterType node) {
+    writeByte(Tag.TypeParameterType);
+    writeUInt30(_typeParameterIndexer[node.parameter]);
+  }
+
+  visitTypeParameter(TypeParameter node) {
+    writeStringReference(node.name ?? '');
+    writeNode(node.bound);
+  }
+
+  defaultNode(Node node) {
+    throw 'Unsupported node: $node';
+  }
+}
+
+class VariableIndexer {
+  final Map<VariableDeclaration, int> index = <VariableDeclaration, int>{};
+  final List<int> scopes = <int>[];
+  int stackHeight = 0;
+
+  void declare(VariableDeclaration node) {
+    index[node] = stackHeight++;
+  }
+
+  void pushScope() {
+    scopes.add(stackHeight);
+  }
+
+  void popScope() {
+    stackHeight = scopes.removeLast();
+  }
+
+  void restoreScope(int numberOfVariables) {
+    stackHeight += numberOfVariables;
+  }
+
+  int operator [](VariableDeclaration node) {
+    return index[node];
+  }
+}
+
+class LabelIndexer {
+  final Map<LabeledStatement, int> index = <LabeledStatement, int>{};
+  int stackHeight = 0;
+
+  void enter(LabeledStatement node) {
+    index[node] = stackHeight++;
+  }
+
+  void exit() {
+    --stackHeight;
+  }
+
+  int operator [](LabeledStatement node) => index[node];
+}
+
+class SwitchCaseIndexer {
+  final Map<SwitchCase, int> index = <SwitchCase, int>{};
+  int stackHeight = 0;
+
+  void enter(SwitchStatement node) {
+    for (var caseNode in node.cases) {
+      index[caseNode] = stackHeight++;
+    }
+  }
+
+  void exit(SwitchStatement node) {
+    stackHeight -= node.cases.length;
+  }
+
+  int operator [](SwitchCase node) => index[node];
+}
+
+class TypeParameterIndexer {
+  final Map<TypeParameter, int> index = <TypeParameter, int>{};
+  int stackHeight = 0;
+
+  void enter(List<TypeParameter> typeParameters) {
+    for (var parameter in typeParameters) {
+      index[parameter] = stackHeight;
+      ++stackHeight;
+    }
+  }
+
+  void exit(List<TypeParameter> typeParameters) {
+    stackHeight -= typeParameters.length;
+  }
+
+  int operator [](TypeParameter parameter) => index[parameter];
+}
+
+class StringTableEntry implements Comparable<StringTableEntry> {
+  final String value;
+  int frequency = 0;
+
+  StringTableEntry(this.value);
+
+  int compareTo(StringTableEntry other) => other.frequency - frequency;
+}
+
+class StringIndexer extends RecursiveVisitor<Null> {
+  final List<StringTableEntry> entries = <StringTableEntry>[];
+  final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>();
+
+  StringIndexer() {
+    put('');
+  }
+
+  int get numberOfStrings => index.length;
+
+  void build(Node node) {
+    node.accept(this);
+    entries.sort();
+    for (int i = 0; i < entries.length; ++i) {
+      index[entries[i].value] = i;
+    }
+  }
+
+  void put(String string) {
+    int i = index.putIfAbsent(string, () {
+      entries.add(new StringTableEntry(string));
+      return index.length;
+    });
+    ++entries[i].frequency;
+  }
+
+  void putOptional(String string) {
+    if (string != null) {
+      put(string);
+    }
+  }
+
+  int operator [](String string) => index[string];
+
+  void addLibraryImports(LibraryImportTable imports) {
+    imports.importPaths.forEach(put);
+  }
+
+  visitName(Name node) {
+    put(node.name);
+  }
+
+  visitLibrary(Library node) {
+    putOptional(node.name);
+    put('${node.importUri}');
+    node.visitChildren(this);
+  }
+
+  visitClass(Class node) {
+    putOptional(node.name);
+    node.visitChildren(this);
+  }
+
+  visitNamedExpression(NamedExpression node) {
+    put(node.name);
+    node.visitChildren(this);
+  }
+
+  visitStringLiteral(StringLiteral node) {
+    put(node.value);
+  }
+
+  visitIntLiteral(IntLiteral node) {
+    if (node.value.abs() >> 30 != 0) {
+      put('${node.value}');
+    }
+  }
+
+  visitDoubleLiteral(DoubleLiteral node) {
+    put('${node.value}');
+  }
+
+  visitSymbolLiteral(SymbolLiteral node) {
+    put(node.value);
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    putOptional(node.name);
+    node.visitChildren(this);
+  }
+
+  visitNamedType(NamedType node) {
+    put(node.name);
+    node.visitChildren(this);
+  }
+
+  visitTypeParameter(TypeParameter node) {
+    putOptional(node.name);
+    node.visitChildren(this);
+  }
+}
+
+/// Computes and stores the index of a library, class, or member within its
+/// parent list.
+class GlobalIndexer extends TreeVisitor {
+  final Map<TreeNode, int> indices = <TreeNode, int>{};
+
+  void buildIndexForContainer(TreeNode libraryOrClass) {
+    libraryOrClass.accept(this);
+  }
+
+  void buildIndexForList(List<TreeNode> list) {
+    for (int i = 0; i < list.length; ++i) {
+      TreeNode child = list[i];
+      if (child != null) {
+        indices[child] = i;
+      }
+    }
+  }
+
+  visitProgram(Program node) {
+    buildIndexForList(node.libraries);
+  }
+
+  visitLibrary(Library node) {
+    buildIndexForList(node.classes);
+    buildIndexForList(node.fields);
+    buildIndexForList(node.procedures);
+  }
+
+  visitClass(Class node) {
+    buildIndexForList(node.fields);
+    buildIndexForList(node.constructors);
+    buildIndexForList(node.procedures);
+  }
+
+  int operator [](TreeNode memberOrLibraryOrClass) {
+    var node = memberOrLibraryOrClass;
+    assert(node is Member || node is Library || node is Class);
+    int index = indices[node];
+    if (index == null) {
+      buildIndexForContainer(node.parent);
+      return indices[node];
+    } else {
+      return index;
+    }
+  }
+}
+
+/// Puts a buffer in front of a [Sink<List<int>>].
+class BufferedSink {
+  static const int SIZE = 100000;
+  static const int SMALL = 10000;
+  final Sink<List<int>> _sink;
+  Uint8List _buffer = new Uint8List(SIZE);
+  int length = 0;
+
+  BufferedSink(this._sink);
+
+  void addByte(int byte) {
+    _buffer[length++] = byte;
+    if (length == SIZE) {
+      _sink.add(_buffer);
+      _buffer = new Uint8List(SIZE);
+      length = 0;
+    }
+  }
+
+  void addBytes(List<int> bytes) {
+    // Avoid copying a large buffer into the another large buffer. Also, if
+    // the bytes buffer is too large to fit in our own buffer, just emit both.
+    if (length + bytes.length < SIZE &&
+        (bytes.length < SMALL || length < SMALL)) {
+      if (length == 0) {
+        _sink.add(bytes);
+      } else {
+        _buffer.setRange(length, length + bytes.length, bytes);
+        length += bytes.length;
+      }
+    } else if (bytes.length < SMALL) {
+      // Flush as much as we can in the current buffer.
+      _buffer.setRange(length, SIZE, bytes);
+      _sink.add(_buffer);
+      // Copy over the remainder into a new buffer. It is guaranteed to fit
+      // because the input byte array is small.
+      int alreadyEmitted = SIZE - length;
+      int remainder = bytes.length - alreadyEmitted;
+      _buffer = new Uint8List(SIZE);
+      _buffer.setRange(0, remainder, bytes, alreadyEmitted);
+      length = remainder;
+    } else {
+      _sink.add(_buffer.sublist(0, length));
+      _sink.add(bytes);
+      _buffer = new Uint8List(SIZE);
+      length = 0;
+    }
+  }
+
+  void flush() {
+    _sink.add(_buffer.sublist(0, length));
+    _buffer = new Uint8List(SIZE);
+    length = 0;
+  }
+
+  void flushAndDestroy() {
+    _sink.add(_buffer.sublist(0, length));
+  }
+}
diff --git a/pkg/kernel/lib/binary/loader.dart b/pkg/kernel/lib/binary/loader.dart
new file mode 100644
index 0000000..8ee8fb5
--- /dev/null
+++ b/pkg/kernel/lib/binary/loader.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.binary.loader;
+
+import '../repository.dart';
+import '../ast.dart';
+import 'tag.dart';
+import 'dart:io';
+import 'ast_from_binary.dart';
+
+abstract class BinaryReferenceLoader {
+  Library getLibraryReference(Library from, String relativePath);
+  Class getClassReference(Library library, int tag, int index);
+  Member getMemberReference(TreeNode classOrLibrary, int tag, int index);
+  Member getLibraryMemberReference(Library library, int tag, int index);
+  Member getClassMemberReference(Class classNode, int tag, int index);
+}
+
+class BinaryLoader implements BinaryReferenceLoader {
+  final Repository repository;
+
+  BinaryLoader(this.repository);
+
+  Library getLibraryReference(Library from, String relativePath) {
+    var fullUri = from.importUri.resolve(relativePath);
+    return repository.getLibraryReference(fullUri);
+  }
+
+  static int _pow2roundup(int x) {
+    --x;
+    x |= x >> 1;
+    x |= x >> 2;
+    x |= x >> 4;
+    x |= x >> 8;
+    x |= x >> 16;
+    return x + 1;
+  }
+
+  TreeNode _extendList(
+      TreeNode parent, List<TreeNode> items, int index, TreeNode build()) {
+    if (items.length <= index) {
+      // Avoid excessive resizing by growing the list in steps.
+      items.length = _pow2roundup(index + 1);
+    }
+    return items[index] ??= build()..parent = parent;
+  }
+
+  Class getClassReference(Library library, int tag, int index) {
+    return _extendList(
+        library, library.classes, index, () => _buildClassReference(tag));
+  }
+
+  Class _buildClassReference(int tag) {
+    return new Class();
+  }
+
+  Field _buildFieldReference() {
+    return new Field(null);
+  }
+
+  Constructor _buildConstructorReference() {
+    return new Constructor(null);
+  }
+
+  Procedure _buildProcedureReference() {
+    return new Procedure(null, null, null);
+  }
+
+  Member getMemberReference(TreeNode classOrLibrary, int tag, int index) {
+    if (classOrLibrary is Class) {
+      return getClassMemberReference(classOrLibrary, tag, index);
+    } else {
+      return getLibraryMemberReference(classOrLibrary, tag, index);
+    }
+  }
+
+  Member getLibraryMemberReference(Library library, int tag, int index) {
+    switch (tag) {
+      case Tag.LibraryFieldReference:
+      case Tag.Field:
+        return _extendList(
+            library, library.fields, index, _buildFieldReference);
+      case Tag.LibraryProcedureReference:
+      case Tag.Procedure:
+        return _extendList(
+            library, library.procedures, index, _buildProcedureReference);
+      default:
+        throw 'Invalid library member reference tag: $tag';
+    }
+  }
+
+  Member getClassMemberReference(Class classNode, int tag, int index) {
+    switch (tag) {
+      case Tag.ClassFieldReference:
+      case Tag.Field:
+        return _extendList(
+            classNode, classNode.fields, index, _buildFieldReference);
+      case Tag.ClassConstructorReference:
+      case Tag.Constructor:
+        return _extendList(classNode, classNode.constructors, index,
+            _buildConstructorReference);
+      case Tag.ClassProcedureReference:
+      case Tag.Procedure:
+        return _extendList(
+            classNode, classNode.procedures, index, _buildProcedureReference);
+      default:
+        throw 'Invalid library member reference tag: $tag';
+    }
+  }
+
+  Program loadProgram(String filename) {
+    var bytes = new File(filename).readAsBytesSync();
+    return new BinaryBuilder(this, bytes, filename).readProgramFile();
+  }
+}
diff --git a/pkg/kernel/lib/binary/readme.md b/pkg/kernel/lib/binary/readme.md
new file mode 100644
index 0000000..8bd2346
--- /dev/null
+++ b/pkg/kernel/lib/binary/readme.md
@@ -0,0 +1,3 @@
+Conversion to and from a binary format.
+
+The binary format is described in [binary.md](../../binary.md).
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
new file mode 100644
index 0000000..226b190
--- /dev/null
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.binary.tag;
+
+class Tag {
+  static const int Nothing = 0;
+  static const int Something = 1;
+
+  static const int NormalClass = 2;
+  static const int MixinClass = 3;
+
+  static const int Field = 4;
+  static const int Constructor = 5;
+  static const int Procedure = 6;
+
+  static const int InvalidInitializer = 7;
+  static const int FieldInitializer = 8;
+  static const int SuperInitializer = 9;
+  static const int RedirectingInitializer = 10;
+  static const int LocalInitializer = 11;
+
+  static const int DirectPropertyGet = 15;
+  static const int DirectPropertySet = 16;
+  static const int DirectMethodInvocation = 17;
+  static const int ConstStaticInvocation = 18;
+  static const int InvalidExpression = 19;
+  static const int VariableGet = 20;
+  static const int VariableSet = 21;
+  static const int PropertyGet = 22;
+  static const int PropertySet = 23;
+  static const int SuperPropertyGet = 24;
+  static const int SuperPropertySet = 25;
+  static const int StaticGet = 26;
+  static const int StaticSet = 27;
+  static const int MethodInvocation = 28;
+  static const int SuperMethodInvocation = 29;
+  static const int StaticInvocation = 30;
+  static const int ConstructorInvocation = 31;
+  static const int ConstConstructorInvocation = 32;
+  static const int Not = 33;
+  static const int LogicalExpression = 34;
+  static const int ConditionalExpression = 35;
+  static const int StringConcatenation = 36;
+  static const int IsExpression = 37;
+  static const int AsExpression = 38;
+  static const int StringLiteral = 39;
+  static const int DoubleLiteral = 40;
+  static const int TrueLiteral = 41;
+  static const int FalseLiteral = 42;
+  static const int NullLiteral = 43;
+  static const int SymbolLiteral = 44;
+  static const int TypeLiteral = 45;
+  static const int ThisExpression = 46;
+  static const int Rethrow = 47;
+  static const int Throw = 48;
+  static const int ListLiteral = 49;
+  static const int MapLiteral = 50;
+  static const int AwaitExpression = 51;
+  static const int FunctionExpression = 52;
+  static const int Let = 53;
+  static const int PositiveIntLiteral = 55;
+  static const int NegativeIntLiteral = 56;
+  static const int BigIntLiteral = 57;
+  static const int ConstListLiteral = 58;
+  static const int ConstMapLiteral = 59;
+
+  static const int InvalidStatement = 60;
+  static const int ExpressionStatement = 61;
+  static const int Block = 62;
+  static const int EmptyStatement = 63;
+  static const int AssertStatement = 64;
+  static const int LabeledStatement = 65;
+  static const int BreakStatement = 66;
+  static const int WhileStatement = 67;
+  static const int DoStatement = 68;
+  static const int ForStatement = 69;
+  static const int ForInStatement = 70;
+  static const int SwitchStatement = 71;
+  static const int ContinueSwitchStatement = 72;
+  static const int IfStatement = 73;
+  static const int ReturnStatement = 74;
+  static const int TryCatch = 75;
+  static const int TryFinally = 76;
+  static const int YieldStatement = 77;
+  static const int VariableDeclaration = 78;
+  static const int FunctionDeclaration = 79;
+  static const int AsyncForInStatement = 80;
+
+  static const int BottomType = 89;
+  static const int InvalidType = 90;
+  static const int DynamicType = 91;
+  static const int VoidType = 92;
+  static const int InterfaceType = 93;
+  static const int FunctionType = 94;
+  static const int TypeParameterType = 95;
+  static const int SimpleInterfaceType = 96;
+  static const int SimpleFunctionType = 97;
+
+  static const int NullReference = 99;
+  static const int NormalClassReference = 100;
+  static const int MixinClassReference = 101;
+
+  static const int LibraryFieldReference = 102;
+  static const int ClassFieldReference = 103;
+  static const int ClassConstructorReference = 104;
+  static const int LibraryProcedureReference = 105;
+  static const int ClassProcedureReference = 106;
+
+  static const int SpecializedTagHighBit = 0x80; // 10000000
+  static const int SpecializedTagMask = 0xF8; // 11111000
+  static const int SpecializedPayloadMask = 0x7; // 00000111
+
+  static const int SpecializedVariableGet = 128;
+  static const int SpecializedVariableSet = 136;
+  static const int SpecializedIntLiteral = 144;
+
+  static const int SpecializedIntLiteralBias = 3;
+
+  static const int ProgramFile = 0x90ABCDEF;
+}
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
new file mode 100644
index 0000000..32bf6958
--- /dev/null
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -0,0 +1,852 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.class_hierarchy;
+
+import 'ast.dart';
+import 'dart:math';
+import 'dart:typed_data';
+import 'type_algebra.dart';
+
+/// Data structure for answering various subclassing queries.
+class ClassHierarchy {
+  /// All classes in the program.
+  ///
+  /// The list is ordered so that classes occur after their super classes.
+  final List<Class> classes;
+
+  final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
+
+  ClassHierarchy(Program program)
+      : this._internal(program, _countClasses(program));
+
+  Class get rootClass => classes[0];
+
+  /// Returns the index of [class_] in the [classes] list.
+  int getClassIndex(Class class_) => _infoFor[class_].topologicalIndex;
+
+  /// True if [subclass] inherits from [superclass] though zero or more
+  /// `extends` relationships.
+  bool isSubclassOf(Class subclass, Class superclass) {
+    if (identical(subclass, superclass)) return true;
+    return _infoFor[subclass].isSubclassOf(_infoFor[superclass]);
+  }
+
+  /// True if [submixture] inherits from [superclass] though zero or more
+  /// `extends` and `with` relationships.
+  bool isSubmixtureOf(Class submixture, Class superclass) {
+    if (identical(submixture, superclass)) return true;
+    return _infoFor[submixture].isSubmixtureOf(_infoFor[superclass]);
+  }
+
+  /// True if [subtype] inherits from [superclass] though zero or more
+  /// `extends`, `with`, and `implements` relationships.
+  bool isSubtypeOf(Class subtype, Class superclass) {
+    if (identical(subtype, superclass)) return true;
+    return _infoFor[subtype].isSubtypeOf(_infoFor[superclass]);
+  }
+
+  /// True if the given class is the direct super class of another class.
+  bool isUsedAsSuperClass(Class class_) {
+    return _infoFor[class_].directExtenders.isNotEmpty;
+  }
+
+  /// True if the given class is used as the right-hand operand to a
+  /// mixin application (i.e. [Class.mixedInType]).
+  bool isUsedAsMixin(Class class_) {
+    return _infoFor[class_].directMixers.isNotEmpty;
+  }
+
+  /// True if the given class is used in an `implements` clause.
+  bool isUsedAsSuperInterface(Class class_) {
+    return _infoFor[class_].directImplementers.isNotEmpty;
+  }
+
+  /// Returns the instantiation of [superclass] that is implemented by [class_],
+  /// or `null` if [class_] does not implement [superclass] at all.
+  Supertype getClassAsInstanceOf(Class class_, Class superclass) {
+    if (identical(class_, superclass)) return class_.asThisSupertype;
+    _ClassInfo info = _infoFor[class_];
+    _ClassInfo superInfo = _infoFor[superclass];
+    if (!info.isSubtypeOf(superInfo)) return null;
+    if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype;
+    return info.genericSuperTypes[superclass];
+  }
+
+  /// Returns the instantiation of [superclass] that is implemented by [type],
+  /// or `null` if [type] does not implement [superclass] at all.
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
+    Supertype castedType = getClassAsInstanceOf(type.classNode, superclass);
+    if (castedType == null) return null;
+    return Substitution
+        .fromInterfaceType(type)
+        .substituteType(castedType.asInterfaceType);
+  }
+
+  /// Returns the instance member that would respond to a dynamic dispatch of
+  /// [name] to an instance of [class_], or `null` if no such member exists.
+  ///
+  /// If [setter] is `false`, the name is dispatched as a getter or call,
+  /// and will return a field, getter, method, or operator (or null).
+  ///
+  /// If [setter] is `true`, the name is dispatched as a setter, roughly
+  /// corresponding to `name=` in the Dart specification, but note that the
+  /// returned member will not have a name ending with `=`.  In this case,
+  /// a non-final field or setter (or null) will be returned.
+  ///
+  /// If the class is abstract, abstract members are ignored and the dispatch
+  /// is resolved if the class was not abstract.
+  Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
+    _ClassInfo info = _infoFor[class_];
+    List<Member> list =
+        setter ? info.implementedSetters : info.implementedGettersAndCalls;
+    return _findMemberByName(list, name);
+  }
+
+  /// Returns the list of potential targets of dynamic dispatch to an instance
+  /// of [class_].
+  ///
+  /// If [setters] is `false`, only potential targets of a getter or call
+  /// dispatch are returned.  If [setters] is `true`, only potential targets
+  /// of a setter dispatch are returned.
+  ///
+  /// See [getDispatchTarget] for more details.
+  ///
+  /// The returned list should not be modified.
+  List<Member> getDispatchTargets(Class class_, {bool setters: false}) {
+    _ClassInfo info = _infoFor[class_];
+    return setters ? info.implementedSetters : info.implementedGettersAndCalls;
+  }
+
+  /// Returns the possibly abstract interface member of [class_] with the given
+  /// [name].
+  ///
+  /// If [setters] is `false`, only fields, methods, and getters with that name
+  /// will be found.  If [setters] is `true`, only non-final fields and setters
+  /// will be found.
+  ///
+  /// If multiple members with that name are inherited and not overidden, the
+  /// member from the first declared supertype is returned.
+  Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
+    List<Member> list = getInterfaceMembers(class_, setters: setter);
+    return _findMemberByName(list, name);
+  }
+
+  /// Returns the list of members denoting the interface for [class_], which
+  /// may include abstract members.
+  ///
+  /// The list may contain multiple members with a given name.  This happens
+  /// when members are inherited through different supertypes and not overridden
+  /// in the class.
+  ///
+  /// Also see [getInterfaceMember].
+  List<Member> getInterfaceMembers(Class class_, {bool setters: false}) {
+    return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters);
+  }
+
+  /// Invokes [callback] for every member declared in or inherited by [class_]
+  /// that overrides or implements a member in a supertype of [class_]
+  /// (or in rare cases, overrides a member declared in [class_]).
+  ///
+  /// We use the term "inheritable" for members that are candidates for
+  /// inheritance but may have been overridden.  The "declared" members of a
+  /// mixin application are those declared in the mixed-in type. The callback is
+  /// invoked in the following cases:
+  ///
+  /// 1. A member declared in the class overrides a member inheritable through
+  /// one of the supertypes of the class.
+  ///
+  /// 2. A non-abstract member is inherited from a superclass, and in the
+  /// context of this class, it overrides an abstract member inheritable through
+  /// one of its superinterfaces.
+  ///
+  /// 3. A non-abstract member is inherited from a superclass, and it overrides
+  /// an abstract member declared in this class.
+  ///
+  /// This method will not report that a member overrides itself. A given pair
+  /// may be reported multiple times when there are multiple inheritance paths
+  /// to the overridden member.
+  ///
+  /// It is possible for two methods to override one another in both directions.
+  ///
+  /// Getters and setters are overridden separately.  The [isSetter] callback
+  /// parameter determines which type of access is being overridden.
+  void forEachOverridePair(Class class_,
+      callback(Member declaredMember, Member interfaceMember, bool isSetter)) {
+    _ClassInfo info = _infoFor[class_];
+    for (var supertype in class_.supers) {
+      var superclass = supertype.classNode;
+      var superGetters = getInterfaceMembers(superclass);
+      var superSetters = getInterfaceMembers(superclass, setters: true);
+      _reportOverrides(info.implementedGettersAndCalls, superGetters, callback);
+      _reportOverrides(info.declaredGettersAndCalls, superGetters, callback,
+          onlyAbstract: true);
+      _reportOverrides(info.implementedSetters, superSetters, callback,
+          isSetter: true);
+      _reportOverrides(info.declaredSetters, superSetters, callback,
+          isSetter: true, onlyAbstract: true);
+    }
+    if (!class_.isAbstract) {
+      // If a non-abstract class declares an abstract method M whose
+      // implementation M' is inherited from the superclass, then the inherited
+      // method M' overrides the declared method M.
+      // This flies in the face of conventional override logic, but is necessary
+      // because an instance of the class will contain the method M' which can
+      // be invoked through the interface of M.
+      // Note that [_reportOverrides] does not report self-overrides, so in
+      // most cases these calls will just scan both lists and report nothing.
+      _reportOverrides(info.implementedGettersAndCalls,
+          info.declaredGettersAndCalls, callback);
+      _reportOverrides(info.implementedSetters, info.declaredSetters, callback,
+          isSetter: true);
+    }
+  }
+
+  static void _reportOverrides(
+      List<Member> declaredList,
+      List<Member> inheritedList,
+      callback(Member declaredMember, Member interfaceMember, bool isSetter),
+      {bool isSetter: false,
+      bool onlyAbstract: false}) {
+    int i = 0, j = 0;
+    while (i < declaredList.length && j < inheritedList.length) {
+      Member declared = declaredList[i];
+      if (onlyAbstract && !declared.isAbstract) {
+        ++i;
+        continue;
+      }
+      Member inherited = inheritedList[j];
+      int comparison = _compareMembers(declared, inherited);
+      if (comparison < 0) {
+        ++i;
+      } else if (comparison > 0) {
+        ++j;
+      } else {
+        if (!identical(declared, inherited)) {
+          callback(declared, inherited, isSetter);
+        }
+        // A given declared member may override multiple interface members,
+        // so only move past the interface member.
+        ++j;
+      }
+    }
+  }
+
+  ClassHierarchy._internal(Program program, int numberOfClasses)
+      : classes = new List<Class>(numberOfClasses) {
+    // Build the class ordering based on a topological sort.
+    for (var library in program.libraries) {
+      for (var classNode in library.classes) {
+        _topologicalSortVisit(classNode);
+      }
+    }
+
+    // Build index of direct children.  Do this after the topological sort so
+    // that super types always occur before subtypes.
+    for (int i = 0; i < classes.length; ++i) {
+      var class_ = classes[i];
+      var info = _infoFor[class_];
+      if (class_.supertype != null) {
+        _infoFor[class_.supertype.classNode].directExtenders.add(info);
+      }
+      if (class_.mixedInType != null) {
+        _infoFor[class_.mixedInType.classNode].directMixers.add(info);
+      }
+      for (var supertype in class_.implementedTypes) {
+        _infoFor[supertype.classNode].directImplementers.add(info);
+      }
+    }
+
+    // Run a downward traversal from the root, compute preorder numbers for
+    // each class, and build their subtype sets as interval lists.
+    _topDownSortVisit(_infoFor[rootClass]);
+
+    for (int i = 0; i < classes.length; ++i) {
+      var class_ = classes[i];
+      _buildInterfaceMembers(class_, _infoFor[class_], setters: true);
+      _buildInterfaceMembers(class_, _infoFor[class_], setters: false);
+    }
+  }
+
+  /// Upwards traversal of the class hierarchy that orders classes so super
+  /// types before their subtypes.
+  int _topSortIndex = 0;
+  void _topologicalSortVisit(Class classNode) {
+    var info = _infoFor[classNode];
+    if (info != null) {
+      if (info.isBeingVisited) {
+        throw 'Cyclic inheritance involving ${info.classNode.name}';
+      }
+      return; // Already built.
+    }
+    _infoFor[classNode] = info = new _ClassInfo(classNode);
+    info.isBeingVisited = true;
+    if (classNode.supertype != null) {
+      _topologicalSortVisit(classNode.supertype.classNode);
+      _recordSuperTypes(info, classNode.supertype);
+    }
+    if (classNode.mixedInType != null) {
+      _topologicalSortVisit(classNode.mixedInType.classNode);
+      _recordSuperTypes(info, classNode.mixedInType);
+    }
+    for (var supertype in classNode.implementedTypes) {
+      _topologicalSortVisit(supertype.classNode);
+      _recordSuperTypes(info, supertype);
+    }
+    _buildDeclaredMembers(classNode, info);
+    _buildImplementedMembers(classNode, info);
+    int id = _topSortIndex++;
+    info.topologicalIndex = id;
+    classes[id] = info.classNode;
+    info.isBeingVisited = false;
+  }
+
+  void _buildDeclaredMembers(Class classNode, _ClassInfo info) {
+    if (classNode.mixedInType != null) {
+      _ClassInfo mixedInfo = _infoFor[classNode.mixedInType.classNode];
+      info.declaredGettersAndCalls = mixedInfo.declaredGettersAndCalls;
+      info.declaredSetters = mixedInfo.declaredSetters;
+    } else {
+      var members = info.declaredGettersAndCalls = <Member>[];
+      var setters = info.declaredSetters = <Member>[];
+      for (Procedure procedure in classNode.procedures) {
+        if (procedure.isStatic) continue;
+        if (procedure.kind == ProcedureKind.Setter) {
+          setters.add(procedure);
+        } else {
+          members.add(procedure);
+        }
+      }
+      for (Field field in classNode.fields) {
+        if (field.isStatic) continue;
+        if (field.hasImplicitGetter) {
+          members.add(field);
+        }
+        if (field.hasImplicitSetter) {
+          setters.add(field);
+        }
+      }
+      members.sort(_compareMembers);
+      setters.sort(_compareMembers);
+    }
+  }
+
+  void _buildImplementedMembers(Class classNode, _ClassInfo info) {
+    List<Member> inheritedMembers;
+    List<Member> inheritedSetters;
+    if (classNode.supertype == null) {
+      inheritedMembers = inheritedSetters = const <Member>[];
+    } else {
+      _ClassInfo superInfo = _infoFor[classNode.supertype.classNode];
+      inheritedMembers = superInfo.implementedGettersAndCalls;
+      inheritedSetters = superInfo.implementedSetters;
+    }
+    info.implementedGettersAndCalls = _inheritMembers(
+        info.declaredGettersAndCalls, inheritedMembers,
+        skipAbstractMembers: true);
+    info.implementedSetters = _inheritMembers(
+        info.declaredSetters, inheritedSetters,
+        skipAbstractMembers: true);
+  }
+
+  List<Member> _buildInterfaceMembers(Class classNode, _ClassInfo info,
+      {bool setters}) {
+    List<Member> members =
+        setters ? info.interfaceSetters : info.interfaceGettersAndCalls;
+    if (members != null) return members;
+    List<Member> allInheritedMembers = <Member>[];
+    List<Member> declared =
+        setters ? info.declaredSetters : info.declaredGettersAndCalls;
+    void inheritFrom(Supertype type) {
+      if (type == null) return;
+      List<Member> inherited = _buildInterfaceMembers(
+          type.classNode, _infoFor[type.classNode],
+          setters: setters);
+      inherited = _getUnshadowedInheritedMembers(declared, inherited);
+      allInheritedMembers = _merge(allInheritedMembers, inherited);
+    }
+    inheritFrom(classNode.supertype);
+    inheritFrom(classNode.mixedInType);
+    classNode.implementedTypes.forEach(inheritFrom);
+    members = _inheritMembers(declared, allInheritedMembers);
+    if (setters) {
+      info.interfaceSetters = members;
+    } else {
+      info.interfaceGettersAndCalls = members;
+    }
+    return members;
+  }
+
+  /// Computes the list of implemented members, based on the declared instance
+  /// members and inherited instance members.
+  ///
+  /// Both lists must be sorted by name beforehand.
+  static List<Member> _inheritMembers(
+      List<Member> declared, List<Member> inherited,
+      {bool skipAbstractMembers: false}) {
+    List<Member> result = <Member>[]
+      ..length = declared.length + inherited.length;
+    // Since both lists are sorted, we can fuse them like in merge sort.
+    int storeIndex = 0;
+    int i = 0, j = 0;
+    while (i < declared.length && j < inherited.length) {
+      Member declaredMember = declared[i];
+      Member inheritedMember = inherited[j];
+      if (skipAbstractMembers && declaredMember.isAbstract) {
+        ++i;
+        continue;
+      }
+      if (skipAbstractMembers && inheritedMember.isAbstract) {
+        ++j;
+        continue;
+      }
+      int comparison = _compareMembers(declaredMember, inheritedMember);
+      if (comparison < 0) {
+        result[storeIndex++] = declaredMember;
+        ++i;
+      } else if (comparison > 0) {
+        result[storeIndex++] = inheritedMember;
+        ++j;
+      } else {
+        result[storeIndex++] = declaredMember;
+        ++i;
+        ++j; // Move past overridden member.
+      }
+    }
+    // One of the two lists is now exhausted, copy over the remains.
+    while (i < declared.length) {
+      result[storeIndex++] = declared[i++];
+    }
+    while (j < inherited.length) {
+      result[storeIndex++] = inherited[j++];
+    }
+    result.length = storeIndex;
+    return result;
+  }
+
+  /// Returns the subset of members in [inherited] for which a member with the
+  /// same name does not occur in [declared].
+  ///
+  /// The input lists must be sorted, and the returned list is sorted.
+  static List<Member> _getUnshadowedInheritedMembers(
+      List<Member> declared, List<Member> inherited) {
+    List<Member> result = <Member>[]..length = inherited.length;
+    int storeIndex = 0;
+    int i = 0, j = 0;
+    while (i < declared.length && j < inherited.length) {
+      Member declaredMember = declared[i];
+      Member inheritedMember = inherited[j];
+      int comparison = _compareMembers(declaredMember, inheritedMember);
+      if (comparison < 0) {
+        ++i;
+      } else if (comparison > 0) {
+        result[storeIndex++] = inheritedMember;
+        ++j;
+      } else {
+        // Move past the shadowed member, but retain the declared member, as
+        // it may shadow multiple members.
+        ++j;
+      }
+    }
+    // If the list of declared members is exhausted, copy over the remains of
+    // the inherited members.
+    while (j < inherited.length) {
+      result[storeIndex++] = inherited[j++];
+    }
+    result.length = storeIndex;
+    return result;
+  }
+
+  /// Merges two sorted lists.
+  ///
+  /// If a given member occurs in both lists, the merge will attempt to exclude
+  /// the duplicate member, but is not strictly guaranteed to do so.
+  static List<Member> _merge(List<Member> first, List<Member> second) {
+    if (first.isEmpty) return second;
+    if (second.isEmpty) return first;
+    List<Member> result = <Member>[]..length = first.length + second.length;
+    int storeIndex = 0;
+    int i = 0, j = 0;
+    while (i < first.length && j < second.length) {
+      Member firstMember = first[i];
+      Member secondMember = second[j];
+      int compare = _compareMembers(firstMember, secondMember);
+      if (compare <= 0) {
+        result[storeIndex++] = firstMember;
+        ++i;
+        // If the same member occurs in both lists, skip the duplicate.
+        if (identical(firstMember, secondMember)) {
+          ++j;
+        }
+      } else {
+        result[storeIndex++] = secondMember;
+        ++j;
+      }
+    }
+    while (i < first.length) {
+      result[storeIndex++] = first[i++];
+    }
+    while (j < second.length) {
+      result[storeIndex++] = second[j++];
+    }
+    result.length = storeIndex;
+    return result;
+  }
+
+  void _recordSuperTypes(_ClassInfo subInfo, Supertype supertype) {
+    _ClassInfo superInfo = _infoFor[supertype.classNode];
+    if (supertype.typeArguments.isEmpty) {
+      if (superInfo.genericSuperTypes == null) return;
+      // Since the immediate super type is not generic, all entries in its
+      // super type map are also valid entries for this class.
+      if (subInfo.genericSuperTypes == null &&
+          superInfo.ownsGenericSuperTypeMap) {
+        // Instead of copying the map, take ownership of the map object.
+        // This may result in more entries being added to the map later. Those
+        // are not valid for the super type, but it works out because all
+        // lookups in the map are guarded by a subtype check, so the super type
+        // will not be bothered by the extra entries.
+        subInfo.genericSuperTypes = superInfo.genericSuperTypes;
+        superInfo.ownsGenericSuperTypeMap = false;
+      } else {
+        // Copy over the super type entries.
+        subInfo.genericSuperTypes ??= <Class, Supertype>{};
+        subInfo.genericSuperTypes.addAll(superInfo.genericSuperTypes);
+      }
+    } else {
+      // Copy over all transitive generic super types, and substitute the
+      // free variables with those provided in [supertype].
+      Class superclass = supertype.classNode;
+      var substitution = Substitution.fromPairs(
+          superclass.typeParameters, supertype.typeArguments);
+      subInfo.genericSuperTypes ??= <Class, Supertype>{};
+      superInfo.genericSuperTypes?.forEach((Class key, Supertype type) {
+        subInfo.genericSuperTypes[key] = substitution.substituteSupertype(type);
+      });
+      subInfo.genericSuperTypes[superclass] = supertype;
+    }
+  }
+
+  /// Downwards traversal of the class hierarchy that orders classes so local
+  /// hierarchies have contiguous indices.
+  int _topDownSortIndex = 0;
+  void _topDownSortVisit(_ClassInfo info) {
+    if (info.topDownIndex != -1) return;
+    bool isMixedIn = info.directMixers.isNotEmpty;
+    int index = _topDownSortIndex++;
+    info.topDownIndex = index;
+    var subclassSetBuilder = new _IntervalListBuilder()..addSingleton(index);
+    var submixtureSetBuilder =
+        isMixedIn ? (new _IntervalListBuilder()..addSingleton(index)) : null;
+    var subtypeSetBuilder = new _IntervalListBuilder()..addSingleton(index);
+    for (var subtype in info.directExtenders) {
+      _topDownSortVisit(subtype);
+      subclassSetBuilder.addIntervalList(subtype.subclassIntervalList);
+      submixtureSetBuilder?.addIntervalList(subtype.submixtureIntervalList);
+      subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+    }
+    for (var subtype in info.directMixers) {
+      _topDownSortVisit(subtype);
+      submixtureSetBuilder.addIntervalList(subtype.submixtureIntervalList);
+      subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+    }
+    for (var subtype in info.directImplementers) {
+      _topDownSortVisit(subtype);
+      subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+    }
+    info.subclassIntervalList = subclassSetBuilder.buildIntervalList();
+    info.submixtureIntervalList = isMixedIn
+        ? submixtureSetBuilder.buildIntervalList()
+        : info.subclassIntervalList;
+    info.subtypeIntervalList = subtypeSetBuilder.buildIntervalList();
+  }
+
+  static int _countClasses(Program program) {
+    int count = 0;
+    for (var library in program.libraries) {
+      count += library.classes.length;
+    }
+    return count;
+  }
+
+  /// Creates a histogram such that index `N` contains the number of classes
+  /// that have `N` intervals in its subclass or subtype set (whichever is
+  /// larger).
+  ///
+  /// The more numbers are condensed near the beginning, the more efficient the
+  /// internal data structure is.
+  List<int> getExpenseHistogram() {
+    var result = <int>[];
+    for (Class class_ in classes) {
+      var info = _infoFor[class_];
+      int intervals = max(info.subclassIntervalList.length,
+              info.subtypeIntervalList.length) ~/
+          2;
+      if (intervals >= result.length) {
+        int oldLength = result.length;
+        result.length = intervals + 1;
+        result.fillRange(oldLength, result.length, 0);
+      }
+      result[intervals] += 1;
+    }
+    return result;
+  }
+
+  /// Returns the average number of intervals per subtype relation (less
+  /// is better, 1.0 is bad).
+  ///
+  /// This is an estimate of the memory use compared to a data structure that
+  /// enumerates all subclass/subtype pairs.
+  double getCompressionRatio() {
+    int intervals = 0;
+    int sizes = 0;
+    for (Class class_ in classes) {
+      var info = _infoFor[class_];
+      intervals += (info.subclassIntervalList.length +
+              info.subtypeIntervalList.length) ~/
+          2;
+      sizes += _intervalListSize(info.subclassIntervalList) +
+          _intervalListSize(info.subtypeIntervalList);
+    }
+    return sizes == 0 ? 1.0 : intervals / sizes;
+  }
+
+  /// Returns the number of entries in hash tables storing hierarchy data.
+  int getSuperTypeHashTableSize() {
+    int sum = 0;
+    for (Class class_ in classes) {
+      _ClassInfo info = _infoFor[class_];
+      if (info.ownsGenericSuperTypeMap) {
+        sum += _infoFor[class_].genericSuperTypes?.length ?? 0;
+      }
+    }
+    return sum;
+  }
+}
+
+class _IntervalListBuilder {
+  final List<int> events = <int>[];
+
+  void addInterval(int start, int end) {
+    // Add an event point for each interval end point, using the low bit to
+    // distinguish opening from closing end points. Closing end points should
+    // have the high bit to ensure they occur after an opening end point.
+    events.add(start << 1);
+    events.add((end << 1) + 1);
+  }
+
+  void addSingleton(int x) {
+    addInterval(x, x + 1);
+  }
+
+  void addIntervalList(Uint32List intervals) {
+    for (int i = 0; i < intervals.length; i += 2) {
+      addInterval(intervals[i], intervals[i + 1]);
+    }
+  }
+
+  List<int> buildIntervalList() {
+    // Sort the event points and sweep left to right while tracking how many
+    // intervals we are currently inside.  Record an interval end point when the
+    // number of intervals drop to zero or increase from zero to one.
+    // Event points are encoded so that an opening end point occur before a
+    // closing end point at the same value.
+    events.sort();
+    int insideCount = 0; // The number of intervals we are currently inside.
+    int storeIndex = 0;
+    for (int i = 0; i < events.length; ++i) {
+      int event = events[i];
+      if (event & 1 == 0) {
+        // Start point
+        ++insideCount;
+        if (insideCount == 1) {
+          // Store the results temporarily back in the event array.
+          events[storeIndex++] = event >> 1;
+        }
+      } else {
+        // End point
+        --insideCount;
+        if (insideCount == 0) {
+          events[storeIndex++] = event >> 1;
+        }
+      }
+    }
+    // Copy the results over to a typed array of the correct length.
+    var result = new Uint32List(storeIndex);
+    for (int i = 0; i < storeIndex; ++i) {
+      result[i] = events[i];
+    }
+    return result;
+  }
+}
+
+bool _intervalListContains(Uint32List intervalList, int x) {
+  int low = 0, high = intervalList.length - 1;
+  if (high == -1 || x < intervalList[0] || intervalList[high] <= x) {
+    return false;
+  }
+  // Find the lower bound of x in the list.
+  // If the lower bound is at an even index, the lower bound is an opening point
+  // of an interval that contains x, otherwise it is a closing point of an
+  // interval below x and there is no interval containing x.
+  while (low < high) {
+    int mid = high - ((high - low) >> 1); // Get middle, rounding up.
+    int pivot = intervalList[mid];
+    if (pivot <= x) {
+      low = mid;
+    } else {
+      high = mid - 1;
+    }
+  }
+  return low == high && (low & 1) == 0;
+}
+
+int _intervalListSize(Uint32List intervalList) {
+  int size = 0;
+  for (int i = 0; i < intervalList.length; i += 2) {
+    size += intervalList[i + 1] - intervalList[i];
+  }
+  return size;
+}
+
+/// Returns the member with the given name, or `null` if no member has the
+/// name.  In case the list contains multiple members with the given name,
+/// the one that occurs first in the list is returned.
+Member _findMemberByName(List<Member> members, Name name) {
+  int low = 0, high = members.length - 1;
+  while (low <= high) {
+    int mid = low + ((high - low) >> 1);
+    Member pivot = members[mid];
+    int comparison = _compareNames(name, pivot.name);
+    if (comparison < 0) {
+      high = mid - 1;
+    } else if (comparison > 0) {
+      low = mid + 1;
+    } else if (high != mid) {
+      // Ensure we find the first element of the given name.
+      high = mid;
+    } else {
+      return pivot;
+    }
+  }
+  return null;
+}
+
+/// Compares members by name.
+int _compareMembers(Member first, Member second) {
+  return _compareNames(first.name, second.name);
+}
+
+/// Compares names using an arbitrary as-fast-as-possible sorting criterion.
+int _compareNames(Name firstName, Name secondName) {
+  int firstHash = firstName.hashCode;
+  int secondHash = secondName.hashCode;
+  if (firstHash != secondHash) return firstHash - secondHash;
+  String firstString = firstName.name;
+  String secondString = secondName.name;
+  int firstLength = firstString.length;
+  int secondLength = secondString.length;
+  if (firstLength != secondLength) {
+    return firstLength - secondLength;
+  }
+  Library firstLibrary = firstName.library;
+  Library secondLibrary = secondName.library;
+  if (firstLibrary != secondLibrary) {
+    if (firstLibrary == null) return -1;
+    if (secondLibrary == null) return 1;
+    return firstLibrary.compareTo(secondLibrary);
+  }
+  for (int i = 0; i < firstLength; ++i) {
+    int firstUnit = firstString.codeUnitAt(i);
+    int secondUnit = secondString.codeUnitAt(i);
+    int delta = firstUnit - secondUnit;
+    if (delta != 0) return delta;
+  }
+  return 0;
+}
+
+class _ClassInfo {
+  final Class classNode;
+  int topologicalIndex = 0;
+  int topDownIndex = -1;
+  bool isBeingVisited = false;
+
+  // Super types must always occur before subtypes in these lists.
+  // For example:
+  //
+  //   class A extends Object
+  //   class B extends Object implements A
+  //
+  // Here `A` must occur before `B` in the list of direct extenders of Object,
+  // because `B` is a subtype of `A`.
+  final List<_ClassInfo> directExtenders = <_ClassInfo>[];
+  final List<_ClassInfo> directMixers = <_ClassInfo>[];
+  final List<_ClassInfo> directImplementers = <_ClassInfo>[];
+
+  /// Top-down indices of all subclasses of this class, represented as
+  /// interleaved begin/end interval end points.
+  Uint32List subclassIntervalList;
+  Uint32List submixtureIntervalList;
+  Uint32List subtypeIntervalList;
+
+  bool isSubclassOf(_ClassInfo other) {
+    return _intervalListContains(other.subclassIntervalList, topDownIndex);
+  }
+
+  bool isSubmixtureOf(_ClassInfo other) {
+    return _intervalListContains(other.submixtureIntervalList, topDownIndex);
+  }
+
+  bool isSubtypeOf(_ClassInfo other) {
+    return _intervalListContains(other.subtypeIntervalList, topDownIndex);
+  }
+
+  /// Maps generic supertype classes to the instantiation implemented by this
+  /// class.
+  ///
+  /// E.g. `List` maps to `List<String>` for a class that directly of indirectly
+  /// implements `List<String>`.
+  ///
+  /// However, the map may contain additional entries for classes that are not
+  /// supertypes of this class, so that a single map object can be shared
+  /// between different classes.  Lookups into the map should therefore be
+  /// guarded by a subtype check.
+  ///
+  /// For example:
+  ///
+  ///     class Q<T>
+  ///     class A<T>
+  ///
+  ///     class B extends A<String>
+  ///     class C extends B implements Q<int>
+  ///
+  /// In this case, a single map object `{A: A<String>, Q: Q<int>}` may be
+  /// shared by the classes `B` and `C`.
+  Map<Class, Supertype> genericSuperTypes;
+
+  /// If true, this is the current "owner" of [genericSuperTypes], meaning
+  /// we may add additional entries to the map or transfer ownership to another
+  /// class.
+  bool ownsGenericSuperTypeMap = true;
+
+  /// Instance fields, getters, methods, and operators declared in this class
+  /// or its mixed-in class, sorted according to [_compareMembers].
+  List<Member> declaredGettersAndCalls;
+
+  /// Non-final instance fields and setters declared in this class or its
+  /// mixed-in class, sorted according to [_compareMembers].
+  List<Member> declaredSetters;
+
+  /// Instance fields, getters, methods, and operators implemented by this class
+  /// (declared or inherited).
+  List<Member> implementedGettersAndCalls;
+
+  /// Non-final instance fields and setters implemented by this class
+  /// (declared or inherited).
+  List<Member> implementedSetters;
+
+  List<Member> interfaceGettersAndCalls;
+  List<Member> interfaceSetters;
+
+  _ClassInfo(this.classNode);
+}
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
new file mode 100644
index 0000000..ee315e6
--- /dev/null
+++ b/pkg/kernel/lib/clone.dart
@@ -0,0 +1,399 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.clone;
+
+import 'ast.dart';
+import 'type_algebra.dart';
+
+/// Visitor that return a clone of a tree, maintaining references to cloned
+/// objects.
+///
+/// It is safe to clone members, but cloning a class or library is not
+/// supported.
+class CloneVisitor extends TreeVisitor {
+  final Map<VariableDeclaration, VariableDeclaration> variables =
+      <VariableDeclaration, VariableDeclaration>{};
+  final Map<LabeledStatement, LabeledStatement> labels =
+      <LabeledStatement, LabeledStatement>{};
+  final Map<SwitchCase, SwitchCase> switchCases = <SwitchCase, SwitchCase>{};
+  final Map<TypeParameter, DartType> typeSubstitution;
+
+  CloneVisitor({Map<TypeParameter, DartType> typeSubstitution})
+      : this.typeSubstitution = ensureMutable(typeSubstitution);
+
+  static Map<TypeParameter, DartType> ensureMutable(
+      Map<TypeParameter, DartType> map) {
+    // We need to mutate this map, so make sure we don't use a constant map.
+    if (map == null || map.isEmpty) {
+      return <TypeParameter, DartType>{};
+    }
+    return map;
+  }
+
+  TreeNode visitLibrary(Library node) {
+    throw 'Cloning of libraries is not implemented';
+  }
+
+  TreeNode visitClass(Class node) {
+    throw 'Cloning of classes is not implemented';
+  }
+
+  TreeNode clone(TreeNode node) =>
+      node.accept(this)..fileOffset = node.fileOffset;
+
+  TreeNode cloneOptional(TreeNode node) {
+    TreeNode result = node?.accept(this);
+    if (result != null) result.fileOffset = node.fileOffset;
+    return result;
+  }
+
+  DartType visitType(DartType type) {
+    return substitute(type, typeSubstitution);
+  }
+
+  DartType visitOptionalType(DartType type) {
+    return type == null ? null : substitute(type, typeSubstitution);
+  }
+
+  visitInvalidExpression(InvalidExpression node) => new InvalidExpression();
+
+  visitVariableGet(VariableGet node) {
+    return new VariableGet(
+        variables[node.variable], visitOptionalType(node.promotedType));
+  }
+
+  visitVariableSet(VariableSet node) {
+    return new VariableSet(variables[node.variable], clone(node.value));
+  }
+
+  visitPropertyGet(PropertyGet node) {
+    return new PropertyGet(
+        clone(node.receiver), node.name, node.interfaceTarget);
+  }
+
+  visitPropertySet(PropertySet node) {
+    return new PropertySet(clone(node.receiver), node.name, clone(node.value),
+        node.interfaceTarget);
+  }
+
+  visitDirectPropertyGet(DirectPropertyGet node) {
+    return new DirectPropertyGet(clone(node.receiver), node.target);
+  }
+
+  visitDirectPropertySet(DirectPropertySet node) {
+    return new DirectPropertySet(
+        clone(node.receiver), node.target, clone(node.value));
+  }
+
+  visitSuperPropertyGet(SuperPropertyGet node) {
+    return new SuperPropertyGet(node.name, node.interfaceTarget);
+  }
+
+  visitSuperPropertySet(SuperPropertySet node) {
+    return new SuperPropertySet(
+        node.name, clone(node.value), node.interfaceTarget);
+  }
+
+  visitStaticGet(StaticGet node) {
+    return new StaticGet(node.target);
+  }
+
+  visitStaticSet(StaticSet node) {
+    return new StaticSet(node.target, clone(node.value));
+  }
+
+  visitMethodInvocation(MethodInvocation node) {
+    return new MethodInvocation(clone(node.receiver), node.name,
+        clone(node.arguments), node.interfaceTarget);
+  }
+
+  visitDirectMethodInvocation(DirectMethodInvocation node) {
+    return new DirectMethodInvocation(
+        clone(node.receiver), node.target, clone(node.arguments));
+  }
+
+  visitSuperMethodInvocation(SuperMethodInvocation node) {
+    return new SuperMethodInvocation(
+        node.name, clone(node.arguments), node.interfaceTarget);
+  }
+
+  visitStaticInvocation(StaticInvocation node) {
+    return new StaticInvocation(node.target, clone(node.arguments));
+  }
+
+  visitConstructorInvocation(ConstructorInvocation node) {
+    return new ConstructorInvocation(node.target, clone(node.arguments));
+  }
+
+  visitNot(Not node) {
+    return new Not(clone(node.operand));
+  }
+
+  visitLogicalExpression(LogicalExpression node) {
+    return new LogicalExpression(
+        clone(node.left), node.operator, clone(node.right));
+  }
+
+  visitConditionalExpression(ConditionalExpression node) {
+    return new ConditionalExpression(clone(node.condition), clone(node.then),
+        clone(node.otherwise), visitOptionalType(node.staticType));
+  }
+
+  visitStringConcatenation(StringConcatenation node) {
+    return new StringConcatenation(node.expressions.map(clone).toList());
+  }
+
+  visitIsExpression(IsExpression node) {
+    return new IsExpression(clone(node.operand), visitType(node.type));
+  }
+
+  visitAsExpression(AsExpression node) {
+    return new AsExpression(clone(node.operand), visitType(node.type));
+  }
+
+  visitSymbolLiteral(SymbolLiteral node) {
+    return new SymbolLiteral(node.value);
+  }
+
+  visitTypeLiteral(TypeLiteral node) {
+    return new TypeLiteral(visitType(node.type));
+  }
+
+  visitThisExpression(ThisExpression node) {
+    return new ThisExpression();
+  }
+
+  visitRethrow(Rethrow node) {
+    return new Rethrow();
+  }
+
+  visitThrow(Throw node) {
+    return new Throw(cloneOptional(node.expression));
+  }
+
+  visitListLiteral(ListLiteral node) {
+    return new ListLiteral(node.expressions.map(clone).toList(),
+        typeArgument: visitType(node.typeArgument), isConst: node.isConst);
+  }
+
+  visitMapLiteral(MapLiteral node) {
+    return new MapLiteral(node.entries.map(clone).toList(),
+        keyType: visitType(node.keyType),
+        valueType: visitType(node.valueType),
+        isConst: node.isConst);
+  }
+
+  visitMapEntry(MapEntry node) {
+    return new MapEntry(clone(node.key), clone(node.value));
+  }
+
+  visitAwaitExpression(AwaitExpression node) {
+    return new AwaitExpression(clone(node.operand));
+  }
+
+  visitFunctionExpression(FunctionExpression node) {
+    return new FunctionExpression(clone(node.function));
+  }
+
+  visitStringLiteral(StringLiteral node) {
+    return new StringLiteral(node.value);
+  }
+
+  visitIntLiteral(IntLiteral node) {
+    return new IntLiteral(node.value);
+  }
+
+  visitDoubleLiteral(DoubleLiteral node) {
+    return new DoubleLiteral(node.value);
+  }
+
+  visitBoolLiteral(BoolLiteral node) {
+    return new BoolLiteral(node.value);
+  }
+
+  visitNullLiteral(NullLiteral node) {
+    return new NullLiteral();
+  }
+
+  visitLet(Let node) {
+    var newVariable = clone(node.variable);
+    return new Let(newVariable, clone(node.body));
+  }
+
+  // Statements
+  visitInvalidStatement(InvalidStatement node) {
+    return new InvalidStatement();
+  }
+
+  visitExpressionStatement(ExpressionStatement node) {
+    return new ExpressionStatement(clone(node.expression));
+  }
+
+  visitBlock(Block node) {
+    return new Block(node.statements.map(clone).toList());
+  }
+
+  visitEmptyStatement(EmptyStatement node) {
+    return new EmptyStatement();
+  }
+
+  visitAssertStatement(AssertStatement node) {
+    return new AssertStatement(
+        clone(node.condition), cloneOptional(node.message));
+  }
+
+  visitLabeledStatement(LabeledStatement node) {
+    LabeledStatement newNode = new LabeledStatement(null);
+    labels[node] = newNode;
+    newNode.body = clone(node.body)..parent = newNode;
+    return newNode;
+  }
+
+  visitBreakStatement(BreakStatement node) {
+    return new BreakStatement(labels[node.target]);
+  }
+
+  visitWhileStatement(WhileStatement node) {
+    return new WhileStatement(clone(node.condition), clone(node.body));
+  }
+
+  visitDoStatement(DoStatement node) {
+    return new DoStatement(clone(node.body), clone(node.condition));
+  }
+
+  visitForStatement(ForStatement node) {
+    var variables = node.variables.map(clone).toList();
+    return new ForStatement(variables, cloneOptional(node.condition),
+        node.updates.map(clone).toList(), clone(node.body));
+  }
+
+  visitForInStatement(ForInStatement node) {
+    var newVariable = clone(node.variable);
+    return new ForInStatement(
+        newVariable, clone(node.iterable), clone(node.body));
+  }
+
+  visitSwitchStatement(SwitchStatement node) {
+    for (SwitchCase switchCase in node.cases) {
+      switchCases[switchCase] =
+          new SwitchCase(switchCase.expressions.map(clone).toList(), null);
+    }
+    return new SwitchStatement(
+        clone(node.expression), node.cases.map(clone).toList());
+  }
+
+  visitSwitchCase(SwitchCase node) {
+    var switchCase = switchCases[node];
+    switchCase.body = clone(node.body)..parent = switchCase;
+    return switchCase;
+  }
+
+  visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    return new ContinueSwitchStatement(switchCases[node.target]);
+  }
+
+  visitIfStatement(IfStatement node) {
+    return new IfStatement(
+        clone(node.condition), clone(node.then), cloneOptional(node.otherwise));
+  }
+
+  visitReturnStatement(ReturnStatement node) {
+    return new ReturnStatement(cloneOptional(node.expression));
+  }
+
+  visitTryCatch(TryCatch node) {
+    return new TryCatch(clone(node.body), node.catches.map(clone).toList());
+  }
+
+  visitCatch(Catch node) {
+    var newException = cloneOptional(node.exception);
+    var newStackTrace = cloneOptional(node.stackTrace);
+    return new Catch(newException, clone(node.body),
+        stackTrace: newStackTrace, guard: visitType(node.guard));
+  }
+
+  visitTryFinally(TryFinally node) {
+    return new TryFinally(clone(node.body), clone(node.finalizer));
+  }
+
+  visitYieldStatement(YieldStatement node) {
+    return new YieldStatement(clone(node.expression));
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    return variables[node] = new VariableDeclaration(node.name,
+        initializer: cloneOptional(node.initializer),
+        type: visitType(node.type),
+        isFinal: node.isFinal,
+        isConst: node.isConst);
+  }
+
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    var newVariable = clone(node.variable);
+    return new FunctionDeclaration(newVariable, clone(node.function));
+  }
+
+  // Members
+  visitConstructor(Constructor node) {
+    return new Constructor(clone(node.function),
+        name: node.name,
+        isConst: node.isConst,
+        isExternal: node.isExternal,
+        initializers: node.initializers.map(clone).toList(),
+        transformerFlags: node.transformerFlags);
+  }
+
+  visitProcedure(Procedure node) {
+    return new Procedure(node.name, node.kind, clone(node.function),
+        isAbstract: node.isAbstract,
+        isStatic: node.isStatic,
+        isExternal: node.isExternal,
+        isConst: node.isConst,
+        transformerFlags: node.transformerFlags,
+        fileUri: node.fileUri);
+  }
+
+  visitField(Field node) {
+    return new Field(node.name,
+        type: visitType(node.type),
+        initializer: cloneOptional(node.initializer),
+        isFinal: node.isFinal,
+        isConst: node.isConst,
+        isStatic: node.isStatic,
+        hasImplicitGetter: node.hasImplicitGetter,
+        hasImplicitSetter: node.hasImplicitSetter,
+        transformerFlags: node.transformerFlags,
+        fileUri: node.fileUri);
+  }
+
+  visitTypeParameter(TypeParameter node) {
+    var newNode = new TypeParameter(node.name);
+    typeSubstitution[node] = new TypeParameterType(newNode);
+    newNode.bound = visitType(node.bound);
+    return newNode;
+  }
+
+  visitFunctionNode(FunctionNode node) {
+    var typeParameters = node.typeParameters.map(clone).toList();
+    var positional = node.positionalParameters.map(clone).toList();
+    var named = node.namedParameters.map(clone).toList();
+    return new FunctionNode(cloneOptional(node.body),
+        typeParameters: typeParameters,
+        positionalParameters: positional,
+        namedParameters: named,
+        requiredParameterCount: node.requiredParameterCount,
+        returnType: visitType(node.returnType),
+        asyncMarker: node.asyncMarker);
+  }
+
+  visitArguments(Arguments node) {
+    return new Arguments(node.positional.map(clone).toList(),
+        types: node.types.map(visitType).toList(),
+        named: node.named.map(clone).toList());
+  }
+
+  visitNamedExpression(NamedExpression node) {
+    return new NamedExpression(node.name, clone(node.value));
+  }
+}
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
new file mode 100644
index 0000000..790b3fd
--- /dev/null
+++ b/pkg/kernel/lib/core_types.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.class_table;
+
+import 'ast.dart';
+
+/// Provides access to the classes and libraries in the core libraries.
+class CoreTypes {
+  final Map<String, _LibraryIndex> _dartLibraries = <String, _LibraryIndex>{};
+  Class objectClass;
+  Class nullClass;
+  Class boolClass;
+  Class intClass;
+  Class numClass;
+  Class doubleClass;
+  Class stringClass;
+  Class listClass;
+  Class mapClass;
+  Class iterableClass;
+  Class iteratorClass;
+  Class futureClass;
+  Class streamClass;
+  Class symbolClass;
+  Class internalSymbolClass;
+  Class typeClass;
+  Class functionClass;
+
+  Library getCoreLibrary(String uri) => _dartLibraries[uri].library;
+
+  Class getCoreClass(String libraryUri, String className) {
+    return _dartLibraries[libraryUri].require(className);
+  }
+
+  Procedure getCoreProcedure(String libraryUri, String topLevelMemberName) {
+    Library library = getCoreLibrary(libraryUri);
+    for (Procedure procedure in library.procedures) {
+      if (procedure.name.name == topLevelMemberName) return procedure;
+    }
+    throw 'Missing procedure ${topLevelMemberName} from $libraryUri';
+  }
+
+  CoreTypes(Program program) {
+    for (var library in program.libraries) {
+      if (library.importUri.scheme == 'dart') {
+        _dartLibraries['${library.importUri}'] = new _LibraryIndex(library);
+      }
+    }
+    _LibraryIndex dartCore = _dartLibraries['dart:core'];
+    _LibraryIndex dartAsync = _dartLibraries['dart:async'];
+    _LibraryIndex dartInternal = _dartLibraries['dart:_internal'];
+    objectClass = dartCore.require('Object');
+    nullClass = dartCore.require('Null');
+    boolClass = dartCore.require('bool');
+    intClass = dartCore.require('int');
+    numClass = dartCore.require('num');
+    doubleClass = dartCore.require('double');
+    stringClass = dartCore.require('String');
+    listClass = dartCore.require('List');
+    mapClass = dartCore.require('Map');
+    iterableClass = dartCore.require('Iterable');
+    iteratorClass = dartCore.require('Iterator');
+    symbolClass = dartCore.require('Symbol');
+    typeClass = dartCore.require('Type');
+    functionClass = dartCore.require('Function');
+    futureClass = dartAsync.require('Future');
+    streamClass = dartAsync.require('Stream');
+    internalSymbolClass = dartInternal.require('Symbol');
+  }
+}
+
+/// Provides by-name lookup of classes in a library.
+class _LibraryIndex {
+  final Library library;
+  final Map<String, Class> classes = <String, Class>{};
+
+  _LibraryIndex(this.library) {
+    for (Class classNode in library.classes) {
+      if (classNode.name != null) {
+        classes[classNode.name] = classNode;
+      }
+    }
+  }
+
+  Class require(String name) {
+    Class result = classes[name];
+    if (result == null) {
+      if (library.isExternal) {
+        throw 'Missing class $name from external library ${library.name}';
+      } else {
+        throw 'Missing class $name from ${library.name}';
+      }
+    }
+    return result;
+  }
+}
diff --git a/pkg/kernel/lib/frontend/accessors.dart b/pkg/kernel/lib/frontend/accessors.dart
new file mode 100644
index 0000000..5271f0b
--- /dev/null
+++ b/pkg/kernel/lib/frontend/accessors.dart
@@ -0,0 +1,423 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 library to help transform compounds and null-aware accessors into
+/// let expressions.
+library kernel.frontend.accessors;
+
+import '../ast.dart';
+
+abstract class Accessor {
+  // [builtBinary] and [builtGetter] capture the inner nodes. Used by
+  // dart2js+rasta for determining how subexpressions map to legacy dart2js Ast
+  // nodes. This will be removed once dart2js type analysis (aka inference) is
+  // reimplemented on kernel.
+  Expression builtBinary;
+  Expression builtGetter;
+
+  Expression buildSimpleRead() {
+    return _finish(_makeSimpleRead());
+  }
+
+  /// Returns an assignment to the accessor.
+  ///
+  /// The returned expression evaluates to the assigned value, unless
+  /// [voidContext] is true, in which case it may evaluate to anything.
+  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+    return _finish(_makeSimpleWrite(value, voidContext));
+  }
+
+  Expression buildNullAwareAssignment(Expression value, DartType type,
+      {bool voidContext: false}) {
+    if (voidContext) {
+      return _finish(new ConditionalExpression(buildIsNull(_makeRead()),
+          _makeWrite(value, voidContext), new NullLiteral(), type));
+    }
+    var tmp = new VariableDeclaration.forValue(_makeRead());
+    return _finish(makeLet(
+        tmp,
+        new ConditionalExpression(buildIsNull(new VariableGet(tmp)),
+            _makeWrite(value, voidContext), new VariableGet(tmp), type)));
+  }
+
+  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+      {bool voidContext: false, Procedure interfaceTarget}) {
+    return _finish(_makeWrite(
+        builtBinary =
+            makeBinary(_makeRead(), binaryOperator, interfaceTarget, value),
+        voidContext));
+  }
+
+  Expression buildPrefixIncrement(Name binaryOperator,
+      {bool voidContext: false, Procedure interfaceTarget}) {
+    return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
+        voidContext: voidContext, interfaceTarget: interfaceTarget);
+  }
+
+  Expression buildPostfixIncrement(Name binaryOperator,
+      {bool voidContext: false, Procedure interfaceTarget}) {
+    if (voidContext) {
+      return buildPrefixIncrement(binaryOperator,
+          voidContext: true, interfaceTarget: interfaceTarget);
+    }
+    var value = new VariableDeclaration.forValue(_makeRead());
+    valueAccess() => new VariableGet(value);
+    var dummy = new VariableDeclaration.forValue(_makeWrite(
+        builtBinary = makeBinary(
+            valueAccess(), binaryOperator, interfaceTarget, new IntLiteral(1)),
+        true));
+    return _finish(makeLet(value, makeLet(dummy, valueAccess())));
+  }
+
+  Expression _makeSimpleRead() => _makeRead();
+
+  Expression _makeSimpleWrite(Expression value, bool voidContext) {
+    return _makeWrite(value, voidContext);
+  }
+
+  Expression _makeRead();
+
+  Expression _makeWrite(Expression value, bool voidContext);
+
+  Expression _finish(Expression body) => body;
+
+  makeInvalidRead() => new InvalidExpression();
+
+  makeInvalidWrite(Expression value) => wrapInvalid(value);
+}
+
+class VariableAccessor extends Accessor {
+  VariableDeclaration variable;
+  DartType promotedType;
+
+  VariableAccessor(this.variable, [this.promotedType]);
+
+  _makeRead() => new VariableGet(variable, promotedType);
+
+  _makeWrite(Expression value, bool voidContext) {
+    return variable.isFinal || variable.isConst
+        ? makeInvalidWrite(value)
+        : new VariableSet(variable, value);
+  }
+}
+
+class PropertyAccessor extends Accessor {
+  VariableDeclaration _receiverVariable;
+  Expression receiver;
+  Name name;
+  Member getter, setter;
+
+  static Accessor make(
+      Expression receiver, Name name, Member getter, Member setter) {
+    if (receiver is ThisExpression) {
+      return new ThisPropertyAccessor(name, getter, setter);
+    } else {
+      return new PropertyAccessor._internal(receiver, name, getter, setter);
+    }
+  }
+
+  PropertyAccessor._internal(
+      this.receiver, this.name, this.getter, this.setter);
+
+  _makeSimpleRead() => new PropertyGet(receiver, name, getter);
+  _makeSimpleWrite(Expression value, bool voidContext) {
+    return new PropertySet(receiver, name, value, setter);
+  }
+
+  receiverAccess() {
+    _receiverVariable ??= new VariableDeclaration.forValue(receiver);
+    return new VariableGet(_receiverVariable);
+  }
+
+  _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter);
+
+  _makeWrite(Expression value, bool voidContext) {
+    return new PropertySet(receiverAccess(), name, value, setter);
+  }
+
+  _finish(Expression body) => makeLet(_receiverVariable, body);
+}
+
+/// Special case of [PropertyAccessor] to avoid creating an indirect access to
+/// 'this'.
+class ThisPropertyAccessor extends Accessor {
+  Name name;
+  Member getter, setter;
+
+  ThisPropertyAccessor(this.name, this.getter, this.setter);
+
+  _makeRead() =>
+      builtGetter = new PropertyGet(new ThisExpression(), name, getter);
+
+  _makeWrite(Expression value, bool voidContext) {
+    return new PropertySet(new ThisExpression(), name, value, setter);
+  }
+}
+
+class NullAwarePropertyAccessor extends Accessor {
+  VariableDeclaration receiver;
+  Name name;
+  Member getter, setter;
+  DartType type;
+
+  NullAwarePropertyAccessor(
+      Expression receiver, this.name, this.getter, this.setter, this.type)
+      : this.receiver = makeOrReuseVariable(receiver);
+
+  receiverAccess() => new VariableGet(receiver);
+
+  _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter);
+
+  _makeWrite(Expression value, bool voidContext) {
+    return new PropertySet(receiverAccess(), name, value, setter);
+  }
+
+  _finish(Expression body) => makeLet(
+      receiver,
+      new ConditionalExpression(
+          buildIsNull(receiverAccess()), new NullLiteral(), body, type));
+}
+
+class SuperPropertyAccessor extends Accessor {
+  Name name;
+  Member getter, setter;
+
+  SuperPropertyAccessor(this.name, this.getter, this.setter);
+
+  _makeRead() => new SuperPropertyGet(name, getter);
+
+  _makeWrite(Expression value, bool voidContext) {
+    return new SuperPropertySet(name, value, setter);
+  }
+}
+
+final Name _indexGet = new Name('[]');
+final Name _indexSet = new Name('[]=');
+
+class IndexAccessor extends Accessor {
+  Expression receiver;
+  Expression index;
+  VariableDeclaration receiverVariable;
+  VariableDeclaration indexVariable;
+  Procedure getter, setter;
+
+  static Accessor make(Expression receiver, Expression index, Procedure getter,
+      Procedure setter) {
+    if (receiver is ThisExpression) {
+      return new ThisIndexAccessor(index, getter, setter);
+    } else {
+      return new IndexAccessor._internal(receiver, index, getter, setter);
+    }
+  }
+
+  IndexAccessor._internal(this.receiver, this.index, this.getter, this.setter);
+
+  _makeSimpleRead() => new MethodInvocation(
+      receiver, _indexGet, new Arguments(<Expression>[index]), getter);
+
+  _makeSimpleWrite(Expression value, bool voidContext) {
+    if (!voidContext) return _makeWriteAndReturn(value);
+    return new MethodInvocation(
+        receiver, _indexSet, new Arguments(<Expression>[index, value]), setter);
+  }
+
+  receiverAccess() {
+    // We cannot reuse the receiver if it is a variable since it might be
+    // reassigned in the index expression.
+    receiverVariable ??= new VariableDeclaration.forValue(receiver);
+    return new VariableGet(receiverVariable);
+  }
+
+  indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  _makeRead() {
+    return new MethodInvocation(receiverAccess(), _indexGet,
+        new Arguments(<Expression>[indexAccess()]), getter);
+  }
+
+  _makeWrite(Expression value, bool voidContext) {
+    if (!voidContext) return _makeWriteAndReturn(value);
+    return new MethodInvocation(receiverAccess(), _indexSet,
+        new Arguments(<Expression>[indexAccess(), value]), setter);
+  }
+
+  _makeWriteAndReturn(Expression value) {
+    // The call to []= does not return the value like direct-style assignments
+    // do.  We need to bind the value in a let.
+    var valueVariable = new VariableDeclaration.forValue(value);
+    var dummy = new VariableDeclaration.forValue(new MethodInvocation(
+        receiverAccess(),
+        _indexSet,
+        new Arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
+        setter));
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  Expression _finish(Expression body) {
+    return makeLet(receiverVariable, makeLet(indexVariable, body));
+  }
+}
+
+/// Special case of [IndexAccessor] to avoid creating an indirect access to
+/// 'this'.
+class ThisIndexAccessor extends Accessor {
+  Expression index;
+  VariableDeclaration indexVariable;
+  Procedure getter, setter;
+
+  ThisIndexAccessor(this.index, this.getter, this.setter);
+
+  _makeSimpleRead() {
+    return new MethodInvocation(new ThisExpression(), _indexGet,
+        new Arguments(<Expression>[index]), getter);
+  }
+
+  _makeSimpleWrite(Expression value, bool voidContext) {
+    if (!voidContext) return _makeWriteAndReturn(value);
+    return new MethodInvocation(new ThisExpression(), _indexSet,
+        new Arguments(<Expression>[index, value]), setter);
+  }
+
+  indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  _makeRead() => new MethodInvocation(new ThisExpression(), _indexGet,
+      new Arguments(<Expression>[indexAccess()]), getter);
+
+  _makeWrite(Expression value, bool voidContext) {
+    if (!voidContext) return _makeWriteAndReturn(value);
+    return new MethodInvocation(new ThisExpression(), _indexSet,
+        new Arguments(<Expression>[indexAccess(), value]), setter);
+  }
+
+  _makeWriteAndReturn(Expression value) {
+    var valueVariable = new VariableDeclaration.forValue(value);
+    var dummy = new VariableDeclaration.forValue(new MethodInvocation(
+        new ThisExpression(),
+        _indexSet,
+        new Arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
+        setter));
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  Expression _finish(Expression body) => makeLet(indexVariable, body);
+}
+
+class SuperIndexAccessor extends Accessor {
+  Expression index;
+  VariableDeclaration indexVariable;
+  Member getter, setter;
+
+  SuperIndexAccessor(this.index, this.getter, this.setter);
+
+  indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  _makeSimpleRead() => new SuperMethodInvocation(
+      _indexGet, new Arguments(<Expression>[index]), getter);
+
+  _makeSimpleWrite(Expression value, bool voidContext) {
+    if (!voidContext) return _makeWriteAndReturn(value);
+    return new SuperMethodInvocation(
+        _indexSet, new Arguments(<Expression>[index, value]), setter);
+  }
+
+  _makeRead() {
+    return new SuperMethodInvocation(
+        _indexGet, new Arguments(<Expression>[indexAccess()]), getter);
+  }
+
+  _makeWrite(Expression value, bool voidContext) {
+    if (!voidContext) return _makeWriteAndReturn(value);
+    return new SuperMethodInvocation(
+        _indexSet, new Arguments(<Expression>[indexAccess(), value]), setter);
+  }
+
+  _makeWriteAndReturn(Expression value) {
+    var valueVariable = new VariableDeclaration.forValue(value);
+    var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation(
+        _indexSet,
+        new Arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
+        setter));
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  Expression _finish(Expression body) {
+    return makeLet(indexVariable, body);
+  }
+}
+
+class StaticAccessor extends Accessor {
+  Member readTarget;
+  Member writeTarget;
+
+  StaticAccessor(this.readTarget, this.writeTarget);
+
+  _makeRead() =>
+      readTarget == null ? makeInvalidRead() : new StaticGet(readTarget);
+
+  _makeWrite(Expression value, bool voidContext) {
+    return writeTarget == null
+        ? makeInvalidWrite(value)
+        : new StaticSet(writeTarget, value);
+  }
+}
+
+class ReadOnlyAccessor extends Accessor {
+  Expression expression;
+  VariableDeclaration value;
+
+  ReadOnlyAccessor(this.expression);
+
+  _makeSimpleRead() => expression;
+
+  _makeRead() {
+    value ??= new VariableDeclaration.forValue(expression);
+    return new VariableGet(value);
+  }
+
+  _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value);
+
+  Expression _finish(Expression body) => makeLet(value, body);
+}
+
+Expression makeLet(VariableDeclaration variable, Expression body) {
+  if (variable == null) return body;
+  return new Let(variable, body);
+}
+
+Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget,
+    Expression right) {
+  return new MethodInvocation(
+      left, operator, new Arguments(<Expression>[right]), interfaceTarget);
+}
+
+final Name _equalOperator = new Name('==');
+
+Expression buildIsNull(Expression value) {
+  return makeBinary(value, _equalOperator, null, new NullLiteral());
+}
+
+VariableDeclaration makeOrReuseVariable(Expression value) {
+  // TODO: Devise a way to remember if a variable declaration was reused
+  // or is fresh (hence needs a let binding).
+  return new VariableDeclaration.forValue(value);
+}
+
+Expression wrapInvalid(Expression e) {
+  return new Let(new VariableDeclaration.forValue(e), new InvalidExpression());
+}
diff --git a/pkg/kernel/lib/frontend/readme.md b/pkg/kernel/lib/frontend/readme.md
new file mode 100644
index 0000000..53037ab
--- /dev/null
+++ b/pkg/kernel/lib/frontend/readme.md
@@ -0,0 +1 @@
+Utility method to help the frontend generate kernel IR.
diff --git a/pkg/kernel/lib/frontend/super_initializers.dart b/pkg/kernel/lib/frontend/super_initializers.dart
new file mode 100644
index 0000000..4569274
--- /dev/null
+++ b/pkg/kernel/lib/frontend/super_initializers.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 library to help move super calls last in the initializer list.
+library kernel.frontend.super_calls;
+
+import '../ast.dart';
+
+/// Mutates the initializer list of [node] so that its super initializer occurs
+/// last, while its arguments are evaluated at the correct place.
+///
+/// Does nothing if there is no super initializer or if it is already last.
+void moveSuperInitializerLast(Constructor node) {
+  List<Initializer> initializers = node.initializers;
+  if (initializers.isEmpty) return;
+  if (initializers.last is SuperInitializer) return;
+  int superIndex = -1;
+  for (int i = initializers.length - 1; i >= 0; --i) {
+    Initializer initializer = initializers[i];
+    if (initializer is SuperInitializer) {
+      superIndex = i;
+      break;
+    }
+  }
+  if (superIndex == -1) return;
+  SuperInitializer superCall = initializers[superIndex];
+  Arguments arguments = superCall.arguments;
+  int argumentCount = arguments.positional.length + arguments.named.length;
+
+  // We move all initializers after the super call to the place where the super
+  // call was, but reserve [argumentCount] slots before that for
+  // [LocalInitializer]s.
+  initializers.length += argumentCount;
+  initializers.setRange(
+      superIndex + argumentCount,  // desination start (inclusive)
+      initializers.length - 1,     // desination end (exclusive)
+      initializers,                // source list
+      superIndex + 1);             // source start index
+  initializers[initializers.length - 1] = superCall;
+
+  // Fill in the [argumentCount] reserved slots with the evaluation expressions
+  // of the arguments to the super constructor call.
+  int storeIndex = superIndex;
+  for (int i = 0; i < arguments.positional.length; ++i) {
+    var variable = new VariableDeclaration.forValue(arguments.positional[i]);
+    arguments.positional[i] = new VariableGet(variable)..parent = arguments;
+    initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
+  }
+  for (int i = 0; i < arguments.named.length; ++i) {
+    NamedExpression argument = arguments.named[i];
+    var variable = new VariableDeclaration.forValue(argument.value);
+    arguments.named[i].value = new VariableGet(variable)..parent = argument;
+    initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
+  }
+}
diff --git a/pkg/kernel/lib/import_table.dart b/pkg/kernel/lib/import_table.dart
new file mode 100644
index 0000000..89c2998
--- /dev/null
+++ b/pkg/kernel/lib/import_table.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.import_table;
+
+import 'ast.dart';
+import 'package:path/path.dart' as path;
+
+abstract class ImportTable {
+  int getImportIndex(Library library);
+}
+
+class ProgramImportTable implements ImportTable {
+  final Map<Library, int> _libraryIndex = <Library, int>{};
+
+  ProgramImportTable(Program program) {
+    for (int i = 0; i < program.libraries.length; ++i) {
+      _libraryIndex[program.libraries[i]] = i;
+    }
+  }
+
+  int getImportIndex(Library library) => _libraryIndex[library] ?? -1;
+}
+
+class LibraryImportTable implements ImportTable {
+  final List<String> _importPaths = <String>[];
+  final List<Library> _importedLibraries = <Library>[];
+  final Map<Library, int> _libraryIndex = <Library, int>{};
+
+  factory LibraryImportTable(Library lib) {
+    return new _ImportTableBuilder(lib).build();
+  }
+
+  LibraryImportTable.empty();
+
+  /// The list of imports.
+  ///
+  /// Should not be modified directly, as the index map would go out of sync.
+  List<String> get importPaths => _importPaths;
+
+  List<Library> get importedLibraries => _importedLibraries;
+
+  int addImport(Library target, String importPath) {
+    int index = _libraryIndex[target];
+    if (index != null) return index;
+    index = _importPaths.length;
+    _importPaths.add(importPath);
+    _importedLibraries.add(target);
+    _libraryIndex[target] = index;
+    return index;
+  }
+
+  /// Returns the index of the given import, or -1 if not found.
+  int getImportIndex(Library library) {
+    return _libraryIndex[library] ?? -1;
+  }
+
+  String getImportPath(Library library) {
+    return _importPaths[getImportIndex(library)];
+  }
+}
+
+/// Builds the import table for a given library.
+class _ImportTableBuilder extends RecursiveVisitor {
+  final LibraryImportTable table = new LibraryImportTable.empty();
+  final Library referenceLibrary;
+
+  LibraryImportTable build() {
+    referenceLibrary.accept(this);
+    return table;
+  }
+
+  _ImportTableBuilder(this.referenceLibrary) {
+    table.addImport(referenceLibrary, '');
+  }
+
+  void addLibraryImport(Library target) {
+    if (target == referenceLibrary) return; // Self-reference is special.
+    var referenceUri = referenceLibrary.importUri;
+    var targetUri = target.importUri;
+    if (targetUri == null) {
+      throw '$referenceUri cannot refer to library without an import URI';
+    }
+    if (targetUri.scheme == 'file' && referenceUri.scheme == 'file') {
+      var targetDirectory = path.dirname(targetUri.path);
+      var currentDirectory = path.dirname(referenceUri.path);
+      var relativeDirectory =
+          path.relative(targetDirectory, from: currentDirectory);
+      var filename = path.basename(targetUri.path);
+      table.addImport(target, '$relativeDirectory/$filename');
+    } else if (targetUri.scheme == 'file') {
+      // Cannot import a file:URI from a dart:URI or package:URI.
+      // We may want to remove this restriction, but for now it's just a sanity
+      // check.
+      throw '$referenceUri cannot refer to application library $targetUri';
+    } else {
+      table.addImport(target, target.importUri.toString());
+    }
+  }
+
+  visitClassReference(Class node) {
+    addLibraryImport(node.enclosingLibrary);
+  }
+
+  defaultMemberReference(Member node) {
+    addLibraryImport(node.enclosingLibrary);
+  }
+
+  visitName(Name name) {
+    if (name.library != null) {
+      addLibraryImport(name.library);
+    }
+  }
+}
diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart
new file mode 100644
index 0000000..123f843
--- /dev/null
+++ b/pkg/kernel/lib/kernel.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Conventions for paths:
+///
+/// - Use the [Uri] class for paths that may have the `file`, `dart` or
+///   `package` scheme.  Never use [Uri] for relative paths.
+/// - Use [String]s for all filenames and paths that have no scheme prefix.
+/// - Never translate a `dart:` or `package:` URI into a `file:` URI, instead
+///   translate it to a [String] if the file system path is needed.
+/// - Only use [File] from dart:io at the last moment when it is needed.
+///
+library kernel;
+
+import 'ast.dart';
+import 'binary/ast_to_binary.dart';
+import 'binary/loader.dart';
+import 'dart:async';
+import 'dart:io';
+import 'repository.dart';
+import 'text/ast_to_text.dart';
+
+export 'ast.dart';
+export 'repository.dart';
+
+Program loadProgramFromBinary(String path, [Repository repository]) {
+  repository ??= new Repository();
+  return new BinaryLoader(repository).loadProgram(path);
+}
+
+Future writeProgramToBinary(Program program, String path) {
+  var sink = new File(path).openWrite();
+  var future;
+  try {
+    new BinaryPrinter(sink).writeProgramFile(program);
+  } finally {
+    future = sink.close();
+  }
+  return future;
+}
+
+void writeLibraryToText(Library library, {String path}) {
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer).writeLibraryFile(library);
+  if (path == null) {
+    print(buffer);
+  } else {
+    new File(path).writeAsStringSync('$buffer');
+  }
+}
+
+void writeProgramToText(Program program, {String path, bool showExternal: false}) {
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, showExternal: showExternal).writeProgramFile(program);
+  if (path == null) {
+    print(buffer);
+  } else {
+    new File(path).writeAsStringSync('$buffer');
+  }
+}
diff --git a/pkg/kernel/lib/log.dart b/pkg/kernel/lib/log.dart
new file mode 100644
index 0000000..9a6d6a2
--- /dev/null
+++ b/pkg/kernel/lib/log.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.log;
+
+import 'package:logging/logging.dart';
+export 'package:logging/logging.dart';
+
+final Logger log = new Logger("dart-kernel");
diff --git a/pkg/kernel/lib/repository.dart b/pkg/kernel/lib/repository.dart
new file mode 100644
index 0000000..7689d90
--- /dev/null
+++ b/pkg/kernel/lib/repository.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.repository;
+
+import 'dart:io';
+
+import 'package:path/path.dart' as pathlib;
+
+import 'ast.dart';
+
+/// Keeps track of which [Library] objects have been created for a given URI.
+///
+/// To load different files into the same IR, pass in the same repository
+/// object to the loaders.
+class Repository {
+  final String workingDirectory;
+  final Map<Uri, Library> _uriToLibrary = <Uri, Library>{};
+  final List<Library> libraries = <Library>[];
+
+  Repository({String workingDirectory})
+      : this.workingDirectory = workingDirectory ?? Directory.current.path;
+
+  /// Get the [Library] object for the library addresesd by [path]; possibly
+  /// as an external library.
+  ///
+  /// The [path] may be a relative or absolute file path, or a URI string with a
+  /// `dart:`, `package:` or `file:` scheme.
+  ///
+  /// Note that this method does not check if the library can be loaded at all.
+  Library getLibrary(String path) {
+    return getLibraryReference(normalizePath(path));
+  }
+
+  String normalizeFileExtension(String path) {
+    if (path.endsWith('.dill')) {
+      return path.substring(0, path.length - '.dill'.length) + '.dart';
+    } else {
+      return path;
+    }
+  }
+
+  /// Get the canonical URI for the library addressed by the given [path].
+  ///
+  /// The [path] may be a relative or absolute file path, or a URI string with a
+  /// `dart:`, `package:` or `file:` scheme.
+  Uri normalizePath(String path) {
+    var uri = Uri.parse(path);
+    if (!uri.hasScheme) {
+      if (!pathlib.isAbsolute(path)) {
+        path = pathlib.join(workingDirectory, path);
+      }
+      uri = new Uri(scheme: 'file', path: normalizeFileExtension(path));
+    } else if (uri.scheme == 'file') {
+      var path = normalizeFileExtension(uri.path);
+      if (!uri.hasAbsolutePath) {
+        uri = uri.replace(path: pathlib.join(workingDirectory, path));
+      } else {
+        uri = uri.replace(path: path);
+      }
+    }
+    return uri;
+  }
+
+  Library getLibraryReference(Uri uri) {
+    assert(uri.hasScheme);
+    assert(uri.scheme != 'file' || uri.hasAbsolutePath);
+    return _uriToLibrary.putIfAbsent(uri, () => _buildLibraryReference(uri));
+  }
+
+  Library _buildLibraryReference(Uri uri) {
+    var library = new Library(uri, isExternal: true);
+    libraries.add(library);
+    return library;
+  }
+}
diff --git a/pkg/kernel/lib/target/flutter.dart b/pkg/kernel/lib/target/flutter.dart
new file mode 100644
index 0000000..ea9e704
--- /dev/null
+++ b/pkg/kernel/lib/target/flutter.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.target.flutter;
+
+import '../ast.dart';
+import '../transformations/continuation.dart' as cont;
+import '../transformations/erasure.dart';
+import '../transformations/sanitize_for_vm.dart';
+import '../transformations/mixin_full_resolution.dart' as mix;
+import '../transformations/setup_builtin_library.dart' as setup_builtin_library;
+import 'targets.dart';
+
+class FlutterTarget extends Target {
+  final TargetFlags flags;
+
+  FlutterTarget(this.flags);
+
+  bool get strongMode => flags.strongMode;
+  
+  bool get strongModeSdk => false;
+
+  String get name => 'flutter';
+
+  // This is the order that bootstrap libraries are loaded according to
+  // `runtime/vm/object_store.h`.
+  List<String> get extraRequiredLibraries => const <String>[
+        'dart:async',
+        'dart:collection',
+        'dart:convert',
+        'dart:developer',
+        'dart:_internal',
+        'dart:isolate',
+        'dart:math',
+
+        // The library dart:mirrors may be ignored by the VM, e.g. when built in
+        // PRODUCT mode.
+        'dart:mirrors',
+
+        'dart:profiler',
+        'dart:typed_data',
+        'dart:_vmservice',
+        'dart:_builtin',
+        'dart:nativewrappers',
+        'dart:io',
+
+        // Required for flutter.
+        'dart:ui',
+        'dart:jni',
+        'dart:mojo.internal',
+        'dart:vmservice_sky',
+      ];
+
+  void transformProgram(Program program) {
+    new mix.MixinFullResolution().transform(program);
+    cont.transformProgram(program);
+
+    // Repair `_getMainClosure()` function in dart:{_builtin,ui} libraries.
+    setup_builtin_library.transformProgram(program);
+    setup_builtin_library.transformProgram(program, libraryUri: 'dart:ui');
+
+    if (strongMode) {
+      new Erasure().transform(program);
+    }
+
+    new SanitizeForVM().transform(program);
+  }
+}
diff --git a/pkg/kernel/lib/target/readme.md b/pkg/kernel/lib/target/readme.md
new file mode 100644
index 0000000..d614241
--- /dev/null
+++ b/pkg/kernel/lib/target/readme.md
@@ -0,0 +1,3 @@
+Target configurations.
+
+A target can tailor the kernel IR for a specific backend.
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
new file mode 100644
index 0000000..1dcae03
--- /dev/null
+++ b/pkg/kernel/lib/target/targets.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.target.targets;
+
+import '../ast.dart';
+
+import 'vm.dart';
+import 'flutter.dart';
+
+final List<String> targetNames = targets.keys.toList();
+
+class TargetFlags {
+  bool strongMode;
+  TargetFlags({this.strongMode: false});
+}
+
+typedef Target _TargetBuilder(TargetFlags flags);
+
+final Map<String, _TargetBuilder> targets = <String, _TargetBuilder>{
+  'none': (TargetFlags flags) => new NoneTarget(flags),
+  'vm': (TargetFlags flags) => new VmTarget(flags),
+  'flutter': (TargetFlags flags) => new FlutterTarget(flags),
+};
+
+Target getTarget(String name, TargetFlags flags) {
+  var builder = targets[name];
+  if (builder == null) return null;
+  return builder(flags);
+}
+
+/// A target provides backend-specific options for generating kernel IR.
+abstract class Target {
+  String get name;
+
+  /// A list of URIs of required libraries, not including dart:core.
+  ///
+  /// Libraries will be loaded in order.
+  List<String> get extraRequiredLibraries => <String>[];
+
+  /// Additional declared variables implied by this target.
+  ///
+  /// These can also be passed on the command-line of form `-D<name>=<value>`,
+  /// and those provided on the command-line take precedence over those defined
+  /// by the target.
+  Map<String, String> get extraDeclaredVariables => const <String, String>{};
+
+  bool get strongMode;
+
+  /// If true, the SDK should be loaded in strong mode.
+  bool get strongModeSdk => strongMode;
+
+  void transformProgram(Program program);
+
+  String toString() => 'Target($name)';
+}
+
+class NoneTarget extends Target {
+  final TargetFlags flags;
+
+  NoneTarget(this.flags);
+
+  bool get strongMode => flags.strongMode;
+  String get name => 'none';
+  List<String> get extraRequiredLibraries => <String>[];
+  void transformProgram(Program program) {}
+}
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
new file mode 100644
index 0000000..e6c5d94
--- /dev/null
+++ b/pkg/kernel/lib/target/vm.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.target.vm;
+
+import '../ast.dart';
+import '../transformations/continuation.dart' as cont;
+import '../transformations/erasure.dart';
+import '../transformations/mixin_full_resolution.dart' as mix;
+import '../transformations/sanitize_for_vm.dart';
+import '../transformations/setup_builtin_library.dart' as setup_builtin_library;
+import 'targets.dart';
+
+/// Specializes the kernel IR to the Dart VM.
+class VmTarget extends Target {
+  final TargetFlags flags;
+
+  VmTarget(this.flags);
+
+  bool get strongMode => flags.strongMode;
+
+  /// The VM patch files are not strong mode clean, so we adopt a hybrid mode
+  /// where the SDK is internally unchecked, but trusted to satisfy the types
+  /// declared on its interface.
+  bool get strongModeSdk => false;
+
+  String get name => 'vm';
+
+  // This is the order that bootstrap libraries are loaded according to
+  // `runtime/vm/object_store.h`.
+  List<String> get extraRequiredLibraries => const <String>[
+        'dart:async',
+        'dart:collection',
+        'dart:convert',
+        'dart:developer',
+        'dart:_internal',
+        'dart:isolate',
+        'dart:math',
+
+        // The library dart:mirrors may be ignored by the VM, e.g. when built in
+        // PRODUCT mode.
+        'dart:mirrors',
+
+        'dart:profiler',
+        'dart:typed_data',
+        'dart:vmservice_io',
+        'dart:_vmservice',
+        'dart:_builtin',
+        'dart:nativewrappers',
+        'dart:io',
+      ];
+
+  void transformProgram(Program program) {
+    new mix.MixinFullResolution().transform(program);
+    cont.transformProgram(program);
+
+    // Repair `_getMainClosure()` function in dart:_builtin.
+    setup_builtin_library.transformProgram(program);
+
+    if (strongMode) {
+      new Erasure().transform(program);
+    }
+
+    new SanitizeForVM().transform(program);
+  }
+}
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
new file mode 100644
index 0000000..18be9de
--- /dev/null
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -0,0 +1,1544 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.ast_to_text;
+
+import '../ast.dart';
+import '../import_table.dart';
+import '../type_propagation/type_propagation.dart';
+
+class Namer<T> {
+  int index = 0;
+  final String prefix;
+  final Map<T, String> map = <T, String>{};
+
+  Namer(this.prefix);
+
+  String getName(T key) => map.putIfAbsent(key, () => '$prefix${++index}');
+}
+
+class Disambiguator<T> {
+  final Map<T, String> names = <T, String>{};
+  final Set<String> usedNames = new Set<String>();
+
+  String disambiguate(T key, String proposeName()) {
+    return names.putIfAbsent(key, () {
+      var proposedName = proposeName();
+      if (usedNames.add(proposedName)) return proposedName;
+      int i = 2;
+      while (!usedNames.add('$proposedName$i')) {
+        ++i;
+      }
+      return '$proposedName$i';
+    });
+  }
+}
+
+NameSystem globalDebuggingNames = new NameSystem();
+
+String debugLibraryName(Library node) {
+  return node.name ?? globalDebuggingNames.nameLibrary(node);
+}
+
+String debugClassName(Class node) {
+  return node.name ?? globalDebuggingNames.nameClass(node);
+}
+
+String debugQualifiedClassName(Class node) {
+  return debugLibraryName(node.enclosingLibrary) + '::' + debugClassName(node);
+}
+
+String debugMemberName(Member node) {
+  return node.name?.name ?? globalDebuggingNames.nameMember(node);
+}
+
+String debugQualifiedMemberName(Member node) {
+  if (node.enclosingClass != null) {
+    return debugQualifiedClassName(node.enclosingClass) +
+        '::' +
+        debugMemberName(node);
+  } else {
+    return debugLibraryName(node.enclosingLibrary) +
+        '::' +
+        debugMemberName(node);
+  }
+}
+
+String debugTypeParameterName(TypeParameter node) {
+  return node.name ?? globalDebuggingNames.nameTypeParameter(node);
+}
+
+String debugQualifiedTypeParameterName(TypeParameter node) {
+  if (node.parent is Class) {
+    return debugQualifiedClassName(node.parent) +
+        '::' +
+        debugTypeParameterName(node);
+  }
+  if (node.parent is Member) {
+    return debugQualifiedMemberName(node.parent) +
+        '::' +
+        debugTypeParameterName(node);
+  }
+  return debugTypeParameterName(node);
+}
+
+String debugVariableDeclarationName(VariableDeclaration node) {
+  return node.name ?? globalDebuggingNames.nameVariable(node);
+}
+
+String debugNodeToString(Node node) {
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: globalDebuggingNames).writeNode(node);
+  return '$buffer';
+}
+
+String programToString(Program node) {
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: new NameSystem()).writeProgramFile(node);
+  return '$buffer';
+}
+
+class NameSystem {
+  final Namer<VariableDeclaration> variables =
+      new Namer<VariableDeclaration>('#t');
+  final Namer<Member> members = new Namer<Member>('#m');
+  final Namer<Class> classes = new Namer<Class>('#class');
+  final Namer<Library> libraries = new Namer<Library>('#lib');
+  final Namer<TypeParameter> typeParameters = new Namer<TypeParameter>('#T');
+  final Namer<TreeNode> labels = new Namer<TreeNode>('#L');
+  final Disambiguator<Library> prefixes = new Disambiguator<Library>();
+
+  nameVariable(VariableDeclaration node) => variables.getName(node);
+  nameMember(Member node) => members.getName(node);
+  nameClass(Class node) => classes.getName(node);
+  nameLibrary(Library node) => libraries.getName(node);
+  nameTypeParameter(TypeParameter node) => typeParameters.getName(node);
+  nameSwitchCase(SwitchCase node) => labels.getName(node);
+  nameLabeledStatement(LabeledStatement node) => labels.getName(node);
+
+  nameLibraryPrefix(Library node, {String proposedName}) {
+    return prefixes.disambiguate(node, () {
+      if (proposedName != null) return proposedName;
+      if (node.name != null) return abbreviateName(node.name);
+      if (node.importUri != null) {
+        var path = node.importUri.hasEmptyPath
+            ? '${node.importUri}'
+            : node.importUri.pathSegments.last;
+        if (path.endsWith('.dart')) {
+          path = path.substring(0, path.length - '.dart'.length);
+        }
+        return abbreviateName(path);
+      }
+      return 'L';
+    });
+  }
+
+  final RegExp punctuation = new RegExp('[.:]');
+
+  String abbreviateName(String name) {
+    int dot = name.lastIndexOf(punctuation);
+    if (dot != -1) {
+      name = name.substring(dot + 1);
+    }
+    if (name.length > 4) {
+      return name.substring(0, 3);
+    }
+    return name;
+  }
+}
+
+abstract class Annotator {
+  String annotateVariable(Printer printer, VariableDeclaration node);
+  String annotateReturn(Printer printer, FunctionNode node);
+  String annotateField(Printer printer, Field node);
+}
+
+class InferredValueAnnotator implements Annotator {
+  const InferredValueAnnotator();
+
+  String annotateVariable(Printer printer, VariableDeclaration node) {
+    if (node.inferredValue == null) return null;
+    return printer.getInferredValueString(node.inferredValue);
+  }
+
+  String annotateReturn(Printer printer, FunctionNode node) {
+    if (node.inferredReturnValue == null) return null;
+    return printer.getInferredValueString(node.inferredReturnValue);
+  }
+
+  String annotateField(Printer printer, Field node) {
+    if (node.inferredValue == null) return null;
+    return printer.getInferredValueString(node.inferredValue);
+  }
+}
+
+/// A quick and dirty ambiguous text printer.
+class Printer extends Visitor<Null> {
+  final NameSystem syntheticNames;
+  final StringSink sink;
+  final Annotator annotator;
+  ImportTable importTable;
+  int indentation = 0;
+  int column = 0;
+  bool showExternal;
+
+  static int SPACE = 0;
+  static int WORD = 1;
+  static int SYMBOL = 2;
+  int state = SPACE;
+
+  Printer(this.sink,
+      {NameSystem syntheticNames,
+      this.showExternal,
+      this.importTable,
+      this.annotator: const InferredValueAnnotator()})
+      : this.syntheticNames = syntheticNames ?? new NameSystem();
+
+  Printer._inner(Printer parent, this.importTable)
+      : sink = parent.sink,
+        syntheticNames = parent.syntheticNames,
+        annotator = parent.annotator,
+        showExternal = parent.showExternal;
+
+  String getLibraryName(Library node) {
+    return node.name ?? syntheticNames.nameLibrary(node);
+  }
+
+  String getLibraryReference(Library node) {
+    if (node == null) return '<No Library>';
+    if (importTable != null && importTable.getImportIndex(node) != -1) {
+      return syntheticNames.nameLibraryPrefix(node);
+    }
+    return getLibraryName(node);
+  }
+
+  String getClassName(Class node) {
+    return node.name ?? syntheticNames.nameClass(node);
+  }
+
+  String getClassReference(Class node) {
+    if (node == null) return '<No Class>';
+    String name = getClassName(node);
+    String library = getLibraryReference(node.enclosingLibrary);
+    return '$library::$name';
+  }
+
+  String getInferredValueString(InferredValue value) {
+    if (value.isNothing) return 'Nothing';
+    if (value.isAlwaysNull) return 'Null';
+    assert(value.baseClass != null);
+    String baseName = getClassReference(value.baseClass);
+    String baseSuffix = value.isSubclass ? '+' : value.isSubtype ? '*' : '!';
+    String bitSuffix = ValueBit.format(value.valueBits);
+    return '$baseName$baseSuffix $bitSuffix';
+  }
+
+  static final String emptyNameString = '•';
+  static final Name emptyName = new Name(emptyNameString);
+
+  Name getMemberName(Member node) {
+    if (node.name?.name == '') return emptyName;
+    if (node.name != null) return node.name;
+    return new Name(syntheticNames.nameMember(node));
+  }
+
+  String getMemberReference(Member node) {
+    if (node == null) return '<No Member>';
+    String name = getMemberName(node).name;
+    if (node.parent is Class) {
+      String className = getClassReference(node.parent);
+      return '$className::$name';
+    } else {
+      String library = getLibraryReference(node.enclosingLibrary);
+      return '$library::$name';
+    }
+  }
+
+  String getVariableName(VariableDeclaration node) {
+    return node.name ?? syntheticNames.nameVariable(node);
+  }
+
+  String getVariableReference(VariableDeclaration node) {
+    if (node == null) return '<No VariableDeclaration>';
+    return getVariableName(node);
+  }
+
+  String getTypeParameterName(TypeParameter node) {
+    return node.name ?? syntheticNames.nameTypeParameter(node);
+  }
+
+  String getTypeParameterReference(TypeParameter node) {
+    if (node == null) return '<No TypeParameter>';
+    String name = getTypeParameterName(node);
+    if (node.parent is FunctionNode && node.parent.parent is Member) {
+      String member = getMemberReference(node.parent.parent);
+      return '$member::$name';
+    } else if (node.parent is Class) {
+      String className = getClassReference(node.parent);
+      return '$className::$name';
+    } else {
+      return name; // Bound inside a function type.
+    }
+  }
+
+  void writeLibraryFile(Library library) {
+    writeWord('library');
+    if (library.name != null) {
+      writeWord(library.name);
+    }
+    endLine(';');
+    var imports = new LibraryImportTable(library);
+    for (var library in imports.importedLibraries) {
+      var importPath = imports.getImportPath(library);
+      if (importPath == "") {
+        var prefix =
+            syntheticNames.nameLibraryPrefix(library, proposedName: 'self');
+        endLine('import self as $prefix;');
+      } else {
+        var prefix = syntheticNames.nameLibraryPrefix(library);
+        endLine('import "$importPath" as $prefix;');
+      }
+    }
+    endLine();
+    var inner = new Printer._inner(this, imports);
+    library.classes.forEach(inner.writeNode);
+    library.fields.forEach(inner.writeNode);
+    library.procedures.forEach(inner.writeNode);
+  }
+
+  void writeProgramFile(Program program) {
+    ImportTable imports = new ProgramImportTable(program);
+    var inner = new Printer._inner(this, imports);
+    writeWord('main');
+    writeSpaced('=');
+    inner.writeMemberReference(program.mainMethod);
+    endLine(';');
+    for (var library in program.libraries) {
+      if (library.isExternal) {
+        if (!showExternal) {
+          continue;
+        }
+        writeWord('external');
+      }
+      writeWord('library');
+      if (library.name != null) {
+        writeWord(library.name);
+      }
+      if (library.importUri != null) {
+        writeSpaced('from');
+        writeWord('"${library.importUri}"');
+      }
+      var prefix = syntheticNames.nameLibraryPrefix(library);
+      writeSpaced('as');
+      writeWord(prefix);
+      endLine(' {');
+      ++inner.indentation;
+      library.classes.forEach(inner.writeNode);
+      library.fields.forEach(inner.writeNode);
+      library.procedures.forEach(inner.writeNode);
+      --inner.indentation;
+      endLine('}');
+    }
+  }
+
+  int getPrecedence(TreeNode node) {
+    return Precedence.of(node);
+  }
+
+  void write(String string) {
+    sink.write(string);
+    column += string.length;
+  }
+
+  void writeSpace([String string = ' ']) {
+    write(string);
+    state = SPACE;
+  }
+
+  void ensureSpace() {
+    if (state != SPACE) writeSpace();
+  }
+
+  void writeSymbol(String string) {
+    write(string);
+    state = SYMBOL;
+  }
+
+  void writeSpaced(String string) {
+    ensureSpace();
+    write(string);
+    writeSpace();
+  }
+
+  void writeComma([String string = ',']) {
+    write(string);
+    writeSpace();
+  }
+
+  void writeWord(String string) {
+    if (string.isEmpty) return;
+    ensureWordBoundary();
+    write(string);
+    state = WORD;
+  }
+
+  void ensureWordBoundary() {
+    if (state == WORD) {
+      writeSpace();
+    }
+  }
+
+  void writeIndentation() {
+    writeSpace('  ' * indentation);
+  }
+
+  void writeNode(Node node) {
+    node.accept(this);
+  }
+
+  void writeOptionalNode(Node node) {
+    if (node != null) {
+      node.accept(this);
+    }
+  }
+
+  void writeAnnotatedType(DartType type, String annotation) {
+    writeType(type);
+    if (annotation != null) {
+      write('/');
+      write(annotation);
+      state = WORD;
+    }
+  }
+
+  void writeType(DartType type) {
+    if (type == null) {
+      print('<No DartType>');
+    } else {
+      type.accept(this);
+    }
+  }
+
+  void writeOptionalType(DartType type) {
+    if (type != null) {
+      type.accept(this);
+    }
+  }
+
+  visitSupertype(Supertype type) {
+    if (type == null) {
+      print('<No Supertype>');
+    } else {
+      writeClassReference(type.classNode);
+      if (type.typeArguments.isNotEmpty) {
+        writeSymbol('<');
+        writeList(type.typeArguments, writeType);
+        writeSymbol('>');
+      }
+    }
+  }
+
+  void writeModifier(bool isThere, String name) {
+    if (isThere) {
+      writeWord(name);
+    }
+  }
+
+  void writeName(Name name) {
+    if (name?.name == '') {
+      writeWord(emptyNameString);
+    } else {
+      writeWord(name?.name ?? '<anon>'); // TODO: write library name
+    }
+  }
+
+  void endLine([String string]) {
+    if (string != null) {
+      write(string);
+    }
+    write('\n');
+    state = SPACE;
+    column = 0;
+  }
+
+  void writeFunction(FunctionNode function,
+      {name, List<Initializer> initializers, bool terminateLine: true}) {
+    if (name is String) {
+      writeWord(name);
+    } else if (name is Name) {
+      writeName(name);
+    } else {
+      assert(name == null);
+    }
+    writeTypeParameterList(function.typeParameters);
+    writeParameterList(function.positionalParameters, function.namedParameters,
+        function.requiredParameterCount);
+    writeReturnType(
+        function.returnType, annotator?.annotateReturn(this, function));
+    if (initializers != null && initializers.isNotEmpty) {
+      endLine();
+      ++indentation;
+      writeIndentation();
+      writeComma(':');
+      writeList(initializers, writeNode);
+      --indentation;
+    }
+    if (function.asyncMarker != AsyncMarker.Sync) {
+      writeSpaced(getAsyncMarkerKeyword(function.asyncMarker));
+    }
+    if (function.body != null) {
+      writeFunctionBody(function.body, terminateLine: terminateLine);
+    } else if (terminateLine) {
+      endLine(';');
+    }
+  }
+
+  String getAsyncMarkerKeyword(AsyncMarker marker) {
+    switch (marker) {
+      case AsyncMarker.Sync:
+        return 'sync';
+      case AsyncMarker.SyncStar:
+        return 'sync*';
+      case AsyncMarker.Async:
+        return 'async';
+      case AsyncMarker.AsyncStar:
+        return 'async*';
+      case AsyncMarker.SyncYielding:
+        return 'yielding';
+      default:
+        return '<Invalid async marker: $marker>';
+    }
+  }
+
+  void writeFunctionBody(Statement body, {bool terminateLine: true}) {
+    if (body is Block && body.statements.isEmpty) {
+      ensureSpace();
+      writeSymbol('{}');
+      state = WORD;
+      if (terminateLine) {
+        endLine();
+      }
+    } else if (body is Block) {
+      ensureSpace();
+      endLine('{');
+      ++indentation;
+      body.statements.forEach(writeNode);
+      --indentation;
+      writeIndentation();
+      writeSymbol('}');
+      state = WORD;
+      if (terminateLine) {
+        endLine();
+      }
+    } else if (body is ReturnStatement && !terminateLine) {
+      writeSpaced('=>');
+      writeExpression(body.expression);
+    } else {
+      writeBody(body);
+    }
+  }
+
+  void writeBody(Statement body) {
+    if (body is Block) {
+      endLine(' {');
+      ++indentation;
+      body.statements.forEach(writeNode);
+      --indentation;
+      writeIndentation();
+      endLine('}');
+    } else {
+      endLine();
+      ++indentation;
+      writeNode(body);
+      --indentation;
+    }
+  }
+
+  void writeReturnType(DartType type, String annotation) {
+    if (type == null) return;
+    writeSpaced('→');
+    writeAnnotatedType(type, annotation);
+  }
+
+  void writeTypeParameterList(List<TypeParameter> typeParameters) {
+    if (typeParameters.isEmpty) return;
+    writeSymbol('<');
+    writeList(typeParameters, writeNode);
+    writeSymbol('>');
+    state = WORD; // Ensure space if not followed by another symbol.
+  }
+
+  void writeParameterList(List<VariableDeclaration> positional,
+      List<VariableDeclaration> named, int requiredParameterCount) {
+    writeSymbol('(');
+    writeList(
+        positional.take(requiredParameterCount), writeVariableDeclaration);
+    if (requiredParameterCount < positional.length) {
+      if (requiredParameterCount > 0) {
+        writeComma();
+      }
+      writeSymbol('[');
+      writeList(
+          positional.skip(requiredParameterCount), writeVariableDeclaration);
+      writeSymbol(']');
+    }
+    if (named.isNotEmpty) {
+      if (positional.isNotEmpty) {
+        writeComma();
+      }
+      writeSymbol('{');
+      writeList(named, writeVariableDeclaration);
+      writeSymbol('}');
+    }
+    writeSymbol(')');
+  }
+
+  void writeList(Iterable nodes, callback(x), {String separator: ','}) {
+    bool first = true;
+    for (var node in nodes) {
+      if (first) {
+        first = false;
+      } else {
+        writeComma(separator);
+      }
+      callback(node);
+    }
+  }
+
+  void writeMemberReference(Member member) {
+    writeWord(getMemberReference(member));
+  }
+
+  void writeClassReference(Class classNode) {
+    writeWord(getClassReference(classNode));
+  }
+
+  void writeLibraryReference(Library library) {
+    writeWord(getLibraryReference(library));
+  }
+
+  void writeVariableReference(VariableDeclaration variable) {
+    writeWord(getVariableReference(variable));
+  }
+
+  void writeTypeParameterReference(TypeParameter node) {
+    writeWord(getTypeParameterReference(node));
+  }
+
+  void writeExpression(Expression node, [int minimumPrecedence]) {
+    bool needsParenteses = false;
+    if (minimumPrecedence != null && getPrecedence(node) < minimumPrecedence) {
+      needsParenteses = true;
+      writeSymbol('(');
+    }
+    writeNode(node);
+    if (needsParenteses) {
+      writeSymbol(')');
+    }
+  }
+
+  void writeAnnotation(Expression node) {
+    writeSymbol('@');
+    if (node is ConstructorInvocation) {
+      writeMemberReference(node.target);
+      visitArguments(node.arguments);
+    } else {
+      writeExpression(node);
+    }
+  }
+
+  void writeAnnotationList(List<Expression> nodes) {
+    for (Expression node in nodes) {
+      writeIndentation();
+      writeAnnotation(node);
+      endLine();
+    }
+  }
+
+  visitLibrary(Library node) {}
+
+  visitField(Field node) {
+    writeAnnotationList(node.annotations);
+    writeIndentation();
+    writeModifier(node.isStatic, 'static');
+    writeModifier(node.isFinal, 'final');
+    writeModifier(node.isConst, 'const');
+    // Only show implicit getter/setter modifiers in cases where they are
+    // out of the ordinary.
+    if (node.isStatic) {
+      writeModifier(node.hasImplicitGetter, '[getter]');
+      writeModifier(node.hasImplicitSetter, '[setter]');
+    } else {
+      writeModifier(!node.hasImplicitGetter, '[no-getter]');
+      if (node.isFinal) {
+        writeModifier(node.hasImplicitSetter, '[setter]');
+      } else {
+        writeModifier(!node.hasImplicitSetter, '[no-setter]');
+      }
+    }
+    writeWord('field');
+    writeSpace();
+    writeAnnotatedType(node.type, annotator?.annotateField(this, node));
+    writeName(getMemberName(node));
+    if (node.initializer != null) {
+      writeSpaced('=');
+      writeExpression(node.initializer);
+    }
+    if ((node.enclosingClass == null &&
+            node.enclosingLibrary.fileUri != node.fileUri) ||
+        (node.enclosingClass != null &&
+            node.enclosingClass.fileUri != node.fileUri)) {
+      writeWord("/* from ${node.fileUri} */");
+    }
+    endLine(';');
+  }
+
+  visitProcedure(Procedure node) {
+    writeAnnotationList(node.annotations);
+    writeIndentation();
+    writeModifier(node.isExternal, 'external');
+    writeModifier(node.isStatic, 'static');
+    writeModifier(node.isAbstract, 'abstract');
+    writeWord(procedureKindToString(node.kind));
+    if ((node.enclosingClass == null &&
+            node.enclosingLibrary.fileUri != node.fileUri) ||
+        (node.enclosingClass != null &&
+            node.enclosingClass.fileUri != node.fileUri)) {
+      writeWord("/* from ${node.fileUri} */");
+    }
+    writeFunction(node.function, name: getMemberName(node));
+  }
+
+  visitConstructor(Constructor node) {
+    writeAnnotationList(node.annotations);
+    writeIndentation();
+    writeModifier(node.isExternal, 'external');
+    writeModifier(node.isConst, 'const');
+    writeWord('constructor');
+    writeFunction(node.function,
+        name: node.name, initializers: node.initializers);
+  }
+
+  visitClass(Class node) {
+    writeAnnotationList(node.annotations);
+    writeIndentation();
+    writeModifier(node.isAbstract, 'abstract');
+    writeWord('class');
+    writeWord(getClassName(node));
+    writeTypeParameterList(node.typeParameters);
+    if (node.isMixinApplication) {
+      writeSpaced('=');
+      visitSupertype(node.supertype);
+      writeSpaced('with');
+      visitSupertype(node.mixedInType);
+    } else if (node.supertype != null) {
+      writeSpaced('extends');
+      visitSupertype(node.supertype);
+    }
+    if (node.implementedTypes.isNotEmpty) {
+      writeSpaced('implements');
+      writeList(node.implementedTypes, visitSupertype);
+    }
+    var endLineString = ' {';
+    if (node.enclosingLibrary.fileUri != node.fileUri) {
+      endLineString += ' // from ${node.fileUri}';
+    }
+    endLine(endLineString);
+    ++indentation;
+    node.fields.forEach(writeNode);
+    node.constructors.forEach(writeNode);
+    node.procedures.forEach(writeNode);
+    --indentation;
+    writeIndentation();
+    endLine('}');
+  }
+
+  visitInvalidExpression(InvalidExpression node) {
+    writeWord('invalid-expression');
+  }
+
+  visitMethodInvocation(MethodInvocation node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTarget);
+    writeNode(node.arguments);
+  }
+
+  visitDirectMethodInvocation(DirectMethodInvocation node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.{=');
+    writeMemberReference(node.target);
+    writeSymbol('}');
+    writeNode(node.arguments);
+  }
+
+  visitSuperMethodInvocation(SuperMethodInvocation node) {
+    writeWord('super');
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTarget);
+    writeNode(node.arguments);
+  }
+
+  visitStaticInvocation(StaticInvocation node) {
+    writeModifier(node.isConst, 'const');
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitConstructorInvocation(ConstructorInvocation node) {
+    writeWord(node.isConst ? 'const' : 'new');
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitNot(Not node) {
+    writeSymbol('!');
+    writeExpression(node.operand, Precedence.PREFIX);
+  }
+
+  visitLogicalExpression(LogicalExpression node) {
+    int precedence = Precedence.binaryPrecedence[node.operator];
+    writeExpression(node.left, precedence);
+    writeSpaced(node.operator);
+    writeExpression(node.right, precedence + 1);
+  }
+
+  visitConditionalExpression(ConditionalExpression node) {
+    writeExpression(node.condition, Precedence.LOGICAL_OR);
+    writeSpaced('?');
+    writeExpression(node.then);
+    writeSpaced(':');
+    writeExpression(node.otherwise);
+  }
+
+  String getEscapedCharacter(int codeUnit) {
+    switch (codeUnit) {
+      case 9:
+        return r'\t';
+      case 10:
+        return r'\n';
+      case 11:
+        return r'\v';
+      case 12:
+        return r'\f';
+      case 13:
+        return r'\r';
+      case 34:
+        return r'\"';
+      case 36:
+        return r'\$';
+      case 92:
+        return r'\\';
+      default:
+        if (codeUnit < 32 || codeUnit > 126) {
+          return r'\u' + '$codeUnit'.padLeft(4, '0');
+        } else {
+          return null;
+        }
+    }
+  }
+
+  String escapeString(String string) {
+    StringBuffer buffer;
+    for (int i = 0; i < string.length; ++i) {
+      String character = getEscapedCharacter(string.codeUnitAt(i));
+      if (character != null) {
+        buffer ??= new StringBuffer(string.substring(0, i));
+        buffer.write(character);
+      } else {
+        buffer?.write(string[i]);
+      }
+    }
+    return buffer == null ? string : buffer.toString();
+  }
+
+  visitStringConcatenation(StringConcatenation node) {
+    if (state == WORD) {
+      writeSpace();
+    }
+    write('"');
+    for (var part in node.expressions) {
+      if (part is StringLiteral) {
+        writeSymbol(escapeString(part.value));
+      } else {
+        writeSymbol(r'${');
+        writeExpression(part);
+        writeSymbol('}');
+      }
+    }
+    write('"');
+    state = WORD;
+  }
+
+  visitIsExpression(IsExpression node) {
+    writeExpression(node.operand, Precedence.BITWISE_OR);
+    writeSpaced('is');
+    writeType(node.type);
+  }
+
+  visitAsExpression(AsExpression node) {
+    writeExpression(node.operand, Precedence.BITWISE_OR);
+    writeSpaced('as');
+    writeType(node.type);
+  }
+
+  visitSymbolLiteral(SymbolLiteral node) {
+    writeSymbol('#');
+    writeWord(node.value);
+  }
+
+  visitTypeLiteral(TypeLiteral node) {
+    writeType(node.type);
+  }
+
+  visitThisExpression(ThisExpression node) {
+    writeWord('this');
+  }
+
+  visitRethrow(Rethrow node) {
+    writeWord('rethrow');
+  }
+
+  visitThrow(Throw node) {
+    writeWord('throw');
+    writeSpace();
+    writeExpression(node.expression);
+  }
+
+  visitListLiteral(ListLiteral node) {
+    if (node.isConst) {
+      writeWord('const');
+      writeSpace();
+    }
+    if (node.typeArgument != null) {
+      writeSymbol('<');
+      writeType(node.typeArgument);
+      writeSymbol('>');
+    }
+    writeSymbol('[');
+    writeList(node.expressions, writeNode);
+    writeSymbol(']');
+  }
+
+  visitMapLiteral(MapLiteral node) {
+    if (node.isConst) {
+      writeWord('const');
+      writeSpace();
+    }
+    if (node.keyType != null) {
+      writeSymbol('<');
+      writeList([node.keyType, node.valueType], writeType);
+      writeSymbol('>');
+    }
+    writeSymbol('{');
+    writeList(node.entries, writeNode);
+    writeSymbol('}');
+  }
+
+  visitMapEntry(MapEntry node) {
+    writeExpression(node.key);
+    writeComma(':');
+    writeExpression(node.value);
+  }
+
+  visitAwaitExpression(AwaitExpression node) {
+    writeWord('await');
+    writeExpression(node.operand);
+  }
+
+  visitFunctionExpression(FunctionExpression node) {
+    writeFunction(node.function, terminateLine: false);
+  }
+
+  visitStringLiteral(StringLiteral node) {
+    writeWord('"${escapeString(node.value)}"');
+  }
+
+  visitIntLiteral(IntLiteral node) {
+    writeWord('${node.value}');
+  }
+
+  visitDoubleLiteral(DoubleLiteral node) {
+    writeWord('${node.value}');
+  }
+
+  visitBoolLiteral(BoolLiteral node) {
+    writeWord('${node.value}');
+  }
+
+  visitNullLiteral(NullLiteral node) {
+    writeWord('null');
+  }
+
+  visitLet(Let node) {
+    writeWord('let');
+    writeVariableDeclaration(node.variable);
+    writeSpaced('in');
+    writeExpression(node.body);
+  }
+
+  defaultExpression(Expression node) {
+    writeWord('${node.runtimeType}');
+  }
+
+  visitVariableGet(VariableGet node) {
+    writeVariableReference(node.variable);
+  }
+
+  visitVariableSet(VariableSet node) {
+    writeVariableReference(node.variable);
+    writeSpaced('=');
+    writeExpression(node.value);
+  }
+
+  void writeInterfaceTarget(Name name, Member target) {
+    if (target != null) {
+      writeSymbol('{');
+      writeMemberReference(target);
+      writeSymbol('}');
+    } else {
+      writeName(name);
+    }
+  }
+
+  visitPropertyGet(PropertyGet node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTarget);
+  }
+
+  visitPropertySet(PropertySet node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTarget);
+    writeSpaced('=');
+    writeExpression(node.value);
+  }
+
+  visitSuperPropertyGet(SuperPropertyGet node) {
+    writeWord('super');
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTarget);
+  }
+
+  visitSuperPropertySet(SuperPropertySet node) {
+    writeWord('super');
+    writeSymbol('.');
+    writeInterfaceTarget(node.name, node.interfaceTarget);
+    writeSpaced('=');
+    writeExpression(node.value);
+  }
+
+  visitDirectPropertyGet(DirectPropertyGet node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.{=');
+    writeMemberReference(node.target);
+    writeSymbol('}');
+  }
+
+  visitDirectPropertySet(DirectPropertySet node) {
+    writeExpression(node.receiver, Precedence.PRIMARY);
+    writeSymbol('.{=');
+    writeMemberReference(node.target);
+    writeSymbol('}');
+    writeSpaced('=');
+    writeExpression(node.value);
+  }
+
+  visitStaticGet(StaticGet node) {
+    writeMemberReference(node.target);
+  }
+
+  visitStaticSet(StaticSet node) {
+    writeMemberReference(node.target);
+    writeSpaced('=');
+    writeExpression(node.value);
+  }
+
+  visitInvalidStatement(InvalidStatement node) {
+    writeIndentation();
+    endLine('invalid-statement;');
+  }
+
+  visitExpressionStatement(ExpressionStatement node) {
+    writeIndentation();
+    writeExpression(node.expression);
+    endLine(';');
+  }
+
+  visitBlock(Block node) {
+    writeIndentation();
+    if (node.statements.isEmpty) {
+      endLine('{}');
+      return null;
+    }
+    endLine('{');
+    ++indentation;
+    node.statements.forEach(writeNode);
+    --indentation;
+    writeIndentation();
+    endLine('}');
+  }
+
+  visitEmptyStatement(EmptyStatement node) {
+    writeIndentation();
+    endLine(';');
+  }
+
+  visitAssertStatement(AssertStatement node) {
+    writeIndentation();
+    writeWord('assert');
+    writeSymbol('(');
+    writeExpression(node.condition);
+    if (node.message != null) {
+      writeComma();
+      writeExpression(node.message);
+    }
+    endLine(');');
+  }
+
+  visitLabeledStatement(LabeledStatement node) {
+    writeIndentation();
+    writeWord(syntheticNames.nameLabeledStatement(node));
+    endLine(':');
+    writeNode(node.body);
+  }
+
+  visitBreakStatement(BreakStatement node) {
+    writeIndentation();
+    writeWord('break');
+    writeWord(syntheticNames.nameLabeledStatement(node.target));
+    endLine(';');
+  }
+
+  visitWhileStatement(WhileStatement node) {
+    writeIndentation();
+    writeSpaced('while');
+    writeSymbol('(');
+    writeExpression(node.condition);
+    writeSymbol(')');
+    writeBody(node.body);
+  }
+
+  visitDoStatement(DoStatement node) {
+    writeIndentation();
+    writeWord('do');
+    writeBody(node.body);
+    writeIndentation();
+    writeSpaced('while');
+    writeSymbol('(');
+    writeExpression(node.condition);
+    endLine(')');
+  }
+
+  visitForStatement(ForStatement node) {
+    writeIndentation();
+    writeSpaced('for');
+    writeSymbol('(');
+    writeList(node.variables, writeVariableDeclaration);
+    writeComma(';');
+    if (node.condition != null) {
+      writeExpression(node.condition);
+    }
+    writeComma(';');
+    writeList(node.updates, writeExpression);
+    writeSymbol(')');
+    writeBody(node.body);
+  }
+
+  visitForInStatement(ForInStatement node) {
+    writeIndentation();
+    writeSpaced('for');
+    writeSymbol('(');
+    writeVariableDeclaration(node.variable, useVarKeyword: true);
+    writeSpaced('in');
+    writeExpression(node.iterable);
+    writeSymbol(')');
+    writeBody(node.body);
+  }
+
+  visitSwitchStatement(SwitchStatement node) {
+    writeIndentation();
+    writeWord('switch');
+    writeSymbol('(');
+    writeExpression(node.expression);
+    endLine(') {');
+    ++indentation;
+    node.cases.forEach(writeNode);
+    --indentation;
+    writeIndentation();
+    endLine('}');
+  }
+
+  visitSwitchCase(SwitchCase node) {
+    String label = syntheticNames.nameSwitchCase(node);
+    writeIndentation();
+    writeWord(label);
+    endLine(':');
+    for (var expression in node.expressions) {
+      writeIndentation();
+      writeWord('case');
+      writeExpression(expression);
+      endLine(':');
+    }
+    if (node.isDefault) {
+      writeIndentation();
+      writeWord('default');
+      endLine(':');
+    }
+    ++indentation;
+    writeNode(node.body);
+    --indentation;
+  }
+
+  visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    writeIndentation();
+    writeWord('continue');
+    writeWord(syntheticNames.nameSwitchCase(node.target));
+    endLine(';');
+  }
+
+  visitIfStatement(IfStatement node) {
+    writeIndentation();
+    writeWord('if');
+    writeSymbol('(');
+    writeExpression(node.condition);
+    writeSymbol(')');
+    writeBody(node.then);
+    if (node.otherwise != null) {
+      writeIndentation();
+      writeWord('else');
+      writeBody(node.otherwise);
+    }
+  }
+
+  visitReturnStatement(ReturnStatement node) {
+    writeIndentation();
+    writeWord('return');
+    if (node.expression != null) {
+      writeSpace();
+      writeExpression(node.expression);
+    }
+    endLine(';');
+  }
+
+  visitTryCatch(TryCatch node) {
+    writeIndentation();
+    writeWord('try');
+    writeBody(node.body);
+    node.catches.forEach(writeNode);
+  }
+
+  visitCatch(Catch node) {
+    writeIndentation();
+    if (node.guard != null) {
+      writeWord('on');
+      writeType(node.guard);
+      writeSpace();
+    }
+    writeWord('catch');
+    writeSymbol('(');
+    if (node.exception != null) {
+      writeVariableDeclaration(node.exception);
+    } else {
+      writeWord('no-exception-var');
+    }
+    if (node.stackTrace != null) {
+      writeComma();
+      writeVariableDeclaration(node.stackTrace);
+    }
+    writeSymbol(')');
+    writeBody(node.body);
+  }
+
+  visitTryFinally(TryFinally node) {
+    writeIndentation();
+    writeWord('try');
+    writeBody(node.body);
+    writeIndentation();
+    writeWord('finally');
+    writeBody(node.finalizer);
+  }
+
+  visitYieldStatement(YieldStatement node) {
+    writeIndentation();
+    if (node.isYieldStar) {
+      writeWord('yield*');
+    } else if (node.isNative) {
+      writeWord('[yield]');
+    } else {
+      writeWord('yield');
+    }
+    writeExpression(node.expression);
+    endLine(';');
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    writeIndentation();
+    writeVariableDeclaration(node, useVarKeyword: true);
+    endLine(';');
+  }
+
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    writeIndentation();
+    writeWord('function');
+    writeFunction(node.function, name: getVariableName(node.variable));
+  }
+
+  void writeVariableDeclaration(VariableDeclaration node,
+      {bool useVarKeyword: false}) {
+    writeModifier(node.isFinal, 'final');
+    writeModifier(node.isConst, 'const');
+    if (node.type != null) {
+      writeAnnotatedType(node.type, annotator?.annotateVariable(this, node));
+    }
+    if (useVarKeyword && !node.isFinal && !node.isConst && node.type == null) {
+      writeWord('var');
+    }
+    writeWord(getVariableName(node));
+    if (node.initializer != null) {
+      writeSpaced('=');
+      writeExpression(node.initializer);
+    }
+  }
+
+  visitArguments(Arguments node) {
+    if (node.types.isNotEmpty) {
+      writeSymbol('<');
+      writeList(node.types, writeType);
+      writeSymbol('>');
+    }
+    writeSymbol('(');
+    var allArgs =
+        <List<TreeNode>>[node.positional, node.named].expand((x) => x);
+    writeList(allArgs, writeNode);
+    writeSymbol(')');
+  }
+
+  visitNamedExpression(NamedExpression node) {
+    writeWord(node.name);
+    writeComma(':');
+    writeExpression(node.value);
+  }
+
+  defaultStatement(Statement node) {
+    writeIndentation();
+    endLine('${node.runtimeType}');
+  }
+
+  visitInvalidInitializer(InvalidInitializer node) {
+    writeWord('invalid-initializer');
+  }
+
+  visitFieldInitializer(FieldInitializer node) {
+    writeMemberReference(node.field);
+    writeSpaced('=');
+    writeExpression(node.value);
+  }
+
+  visitSuperInitializer(SuperInitializer node) {
+    writeWord('super');
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitRedirectingInitializer(RedirectingInitializer node) {
+    writeWord('this');
+    writeMemberReference(node.target);
+    writeNode(node.arguments);
+  }
+
+  visitLocalInitializer(LocalInitializer node) {
+    writeVariableDeclaration(node.variable);
+  }
+
+  defaultInitializer(Initializer node) {
+    writeIndentation();
+    endLine(': ${node.runtimeType}');
+  }
+
+  visitInvalidType(InvalidType node) {
+    writeWord('invalid-type');
+  }
+
+  visitDynamicType(DynamicType node) {
+    writeWord('dynamic');
+  }
+
+  visitVoidType(VoidType node) {
+    writeWord('void');
+  }
+
+  visitInterfaceType(InterfaceType node) {
+    writeClassReference(node.classNode);
+    if (node.typeArguments.isNotEmpty) {
+      writeSymbol('<');
+      writeList(node.typeArguments, writeType);
+      writeSymbol('>');
+      state = WORD; // Disallow a word immediately after the '>'.
+    }
+  }
+
+  visitFunctionType(FunctionType node) {
+    writeTypeParameterList(node.typeParameters);
+    writeSymbol('(');
+    var positional = node.positionalParameters;
+    writeList(positional.take(node.requiredParameterCount), writeType);
+    if (node.requiredParameterCount < positional.length) {
+      if (node.requiredParameterCount > 0) {
+        writeComma();
+      }
+      writeSymbol('[');
+      writeList(positional.skip(node.requiredParameterCount), writeType);
+      writeSymbol(']');
+    }
+    if (node.namedParameters.isNotEmpty) {
+      if (node.positionalParameters.isNotEmpty) {
+        writeComma();
+      }
+      writeSymbol('{');
+      writeList(node.namedParameters, visitNamedType);
+      writeSymbol('}');
+    }
+    writeSymbol(')');
+    writeSpaced('→');
+    writeType(node.returnType);
+  }
+
+  visitNamedType(NamedType node) {
+    writeWord(node.name);
+    writeSymbol(':');
+    writeSpace();
+    writeType(node.type);
+  }
+
+  visitTypeParameterType(TypeParameterType node) {
+    writeTypeParameterReference(node.parameter);
+  }
+
+  visitTypeParameter(TypeParameter node) {
+    writeWord(getTypeParameterName(node));
+    writeSpaced('extends');
+    writeType(node.bound);
+  }
+
+  defaultNode(Node node) {
+    write('<${node.runtimeType}>');
+  }
+}
+
+class Precedence extends ExpressionVisitor<int> {
+  static final Precedence instance = new Precedence();
+
+  static int of(Expression node) => node.accept(instance);
+
+  static const int EXPRESSION = 1;
+  static const int CONDITIONAL = 2;
+  static const int LOGICAL_NULL_AWARE = 3;
+  static const int LOGICAL_OR = 4;
+  static const int LOGICAL_AND = 5;
+  static const int EQUALITY = 6;
+  static const int RELATIONAL = 7;
+  static const int BITWISE_OR = 8;
+  static const int BITWISE_XOR = 9;
+  static const int BITWISE_AND = 10;
+  static const int SHIFT = 11;
+  static const int ADDITIVE = 12;
+  static const int MULTIPLICATIVE = 13;
+  static const int PREFIX = 14;
+  static const int POSTFIX = 15;
+  static const int TYPE_LITERAL = 19;
+  static const int PRIMARY = 20;
+  static const int CALLEE = 21;
+
+  static const Map<String, int> binaryPrecedence = const {
+    '&&': LOGICAL_AND,
+    '||': LOGICAL_OR,
+    '??': LOGICAL_NULL_AWARE,
+    '==': EQUALITY,
+    '!=': EQUALITY,
+    '>': RELATIONAL,
+    '>=': RELATIONAL,
+    '<': RELATIONAL,
+    '<=': RELATIONAL,
+    '|': BITWISE_OR,
+    '^': BITWISE_XOR,
+    '&': BITWISE_AND,
+    '>>': SHIFT,
+    '<<': SHIFT,
+    '+': ADDITIVE,
+    '-': ADDITIVE,
+    '*': MULTIPLICATIVE,
+    '%': MULTIPLICATIVE,
+    '/': MULTIPLICATIVE,
+    '~/': MULTIPLICATIVE,
+    null: EXPRESSION,
+  };
+
+  static bool isAssociativeBinaryOperator(int precedence) {
+    return precedence != EQUALITY && precedence != RELATIONAL;
+  }
+
+  int defaultExpression(Expression node) => EXPRESSION;
+  int visitInvalidExpression(InvalidExpression node) => CALLEE;
+  int visitMethodInvocation(MethodInvocation node) => CALLEE;
+  int visitSuperMethodInvocation(SuperMethodInvocation node) => CALLEE;
+  int visitDirectMethodInvocation(DirectMethodInvocation node) => CALLEE;
+  int visitStaticInvocation(StaticInvocation node) => CALLEE;
+  int visitConstructorInvocation(ConstructorInvocation node) => CALLEE;
+  int visitNot(Not node) => PREFIX;
+  int visitLogicalExpression(LogicalExpression node) =>
+      binaryPrecedence[node.operator];
+  int visitConditionalExpression(ConditionalExpression node) => CONDITIONAL;
+  int visitStringConcatenation(StringConcatenation node) => PRIMARY;
+  int visitIsExpression(IsExpression node) => RELATIONAL;
+  int visitAsExpression(AsExpression node) => RELATIONAL;
+  int visitSymbolLiteral(SymbolLiteral node) => PRIMARY;
+  int visitTypeLiteral(TypeLiteral node) => PRIMARY;
+  int visitThisExpression(ThisExpression node) => CALLEE;
+  int visitRethrow(Rethrow node) => PRIMARY;
+  int visitThrow(Throw node) => EXPRESSION;
+  int visitListLiteral(ListLiteral node) => PRIMARY;
+  int visitMapLiteral(MapLiteral node) => PRIMARY;
+  int visitAwaitExpression(AwaitExpression node) => PREFIX;
+  int visitFunctionExpression(FunctionExpression node) => PRIMARY;
+  int visitStringLiteral(StringLiteral node) => CALLEE;
+  int visitIntLiteral(IntLiteral node) => CALLEE;
+  int visitDoubleLiteral(DoubleLiteral node) => CALLEE;
+  int visitBoolLiteral(BoolLiteral node) => CALLEE;
+  int visitNullLiteral(NullLiteral node) => CALLEE;
+  int visitVariableGet(VariableGet node) => PRIMARY;
+  int visitVariableSet(VariableSet node) => EXPRESSION;
+  int visitPropertyGet(PropertyGet node) => PRIMARY;
+  int visitPropertySet(PropertySet node) => EXPRESSION;
+  int visitSuperPropertyGet(SuperPropertyGet node) => PRIMARY;
+  int visitSuperPropertySet(SuperPropertySet node) => EXPRESSION;
+  int visitDirectPropertyGet(DirectPropertyGet node) => PRIMARY;
+  int visitDirectPropertySet(DirectPropertySet node) => EXPRESSION;
+  int visitStaticGet(StaticGet node) => PRIMARY;
+  int visitStaticSet(StaticSet node) => EXPRESSION;
+  int visitLet(Let node) => EXPRESSION;
+}
+
+String procedureKindToString(ProcedureKind kind) {
+  switch (kind) {
+    case ProcedureKind.Method:
+      return 'method';
+    case ProcedureKind.Getter:
+      return 'get';
+    case ProcedureKind.Setter:
+      return 'set';
+    case ProcedureKind.Operator:
+      return 'operator';
+    case ProcedureKind.Factory:
+      return 'factory';
+  }
+  throw 'illegal ProcedureKind: $kind';
+}
+
+class ExpressionPrinter {
+  final Printer writeer;
+  final int minimumPrecedence;
+
+  ExpressionPrinter(this.writeer, this.minimumPrecedence);
+}
diff --git a/pkg/kernel/lib/text/readme.md b/pkg/kernel/lib/text/readme.md
new file mode 100644
index 0000000..0d3f224
--- /dev/null
+++ b/pkg/kernel/lib/text/readme.md
@@ -0,0 +1,4 @@
+Conversion to a textual format.
+
+The text format is currently very ad-hoc and there is no conversion back, but
+it's a pleasant way to view the IR.
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
new file mode 100644
index 0000000..fb3483d
--- /dev/null
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -0,0 +1,489 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.async;
+
+import '../kernel.dart';
+import 'continuation.dart';
+
+/// A transformer that introduces temporary variables for all subexpressions
+/// that are alive across yield points (AwaitExpression).
+///
+/// The transformer is invoked by passing [rewrite] a top-level expression.
+///
+/// All intermediate values that are possible live across an await are named in
+/// local variables.
+///
+/// Await expressions are translated into a call to a helper function and a
+/// native yield.
+class ExpressionLifter extends Transformer {
+  final AsyncRewriterBase continuationRewriter;
+
+  /// Have we seen an await to the right in the expression tree.
+  ///
+  /// Subexpressions are visited right-to-left in the reverse of evaluation
+  /// order.
+  ///
+  /// On entry to an expression's visit method, [seenAwait] indicates whether a
+  /// sibling to the right contains an await.  If so the expression will be
+  /// named in a temporary variable because it is potentially live across an
+  /// await.
+  ///
+  /// On exit from an expression's visit method, [seenAwait] indicates whether
+  /// the expression itself or a sibling to the right contains an await.
+  bool seenAwait = false;
+
+  /// The (reverse order) sequence of statements that have been emitted.
+  ///
+  /// Transformation of an expression produces a transformed expression and a
+  /// sequence of statements which are assignments to local variables, calls to
+  /// helper functions, and yield points.  Only the yield points need to be a
+  /// statements, and they are statements so an implementation does not have to
+  /// handle unnamed expression intermediate live across yield points.
+  ///
+  /// The visit methods return the transformed expression and build a sequence
+  /// of statements by emitting statements into this list.  This list is built
+  /// in reverse because children are visited right-to-left.
+  ///
+  /// If an expression should be named it is named before visiting its children
+  /// so the naming assignment appears in the list before all statements
+  /// implementating the translation of the children.
+  ///
+  /// Children that are conditionally evaluated, such as some parts of logical
+  /// and conditional expressions, must be delimited so that they do not emit
+  /// unguarded statements into [statements].  This is implemented by setting
+  /// [statements] to a fresh empty list before transforming those children.
+  List<Statement> statements = <Statement>[];
+
+
+  /// The number of currently live named intermediate values.
+  ///
+  /// This index is used to allocate names to temporary values.  Because
+  /// children are visited right-to-left, names are assigned in reverse order of
+  /// index.
+  ///
+  /// When an assignment is emitted into [statements] to name an expression
+  /// before visiting its children, the index is not immediately reserved
+  /// because a child can freely use the same name as its parent.  In practice,
+  /// this will be the rightmost named child.
+  ///
+  /// After visiting the children of a named expression, [nameIndex] is set to
+  /// indicate one more live value (the value of the expression) than before
+  /// visiting the expression.
+  ///
+  /// After visiting the children of an expression that is not named,
+  /// [nameIndex] may still account for names of subexpressions.
+  int nameIndex = 0;
+
+  final VariableDeclaration asyncResult =
+      new VariableDeclaration(':result');
+  final List<VariableDeclaration> variables = <VariableDeclaration>[];
+
+  ExpressionLifter(this.continuationRewriter);
+
+  Block blockOf(List<Statement> stmts) => new Block(stmts.reversed.toList());
+
+  /// Rewrite a toplevel expression (toplevel wrt. a statement).
+  ///
+  /// Rewriting an expression produces a sequence of statements and an
+  /// expression.  The sequence of statements are added to the given list.  Pass
+  /// an empty list if the rewritten expression should be delimited from the
+  /// surrounding context.
+  Expression rewrite(Expression expression, List<Statement> outer) {
+    assert(statements.isEmpty);
+    assert(nameIndex == 0);
+    seenAwait = false;
+    Expression result = expression.accept(this);
+    outer.addAll(statements.reversed);
+    statements.clear();
+    nameIndex = 0;
+    return result;
+  }
+
+  // Perform an action with a given list of statements so that it cannot emit
+  // statements into the 'outer' list.
+  Expression delimit(Expression action(), List<Statement> inner) {
+    var index = nameIndex;
+    var outer = statements;
+    statements = inner;
+    Expression result = action();
+    nameIndex = index;
+    statements = outer;
+    return result;
+  }
+
+  // Name an expression by emitting an assignment to a temporary variable.
+  VariableGet name(Expression expr) {
+    VariableDeclaration temp = allocateTemporary(nameIndex);
+    statements.add(new ExpressionStatement(new VariableSet(temp, expr)));
+    return new VariableGet(temp);
+  }
+
+  VariableDeclaration allocateTemporary(int index) {
+    for (var i = variables.length; i <= index; i++) {
+      variables.add(new VariableDeclaration(":async_temporary_${i}"));
+    }
+    return variables[index];
+  }
+
+  // Simple literals.  These are pure expressions so they can be evaluated after
+  // an await to their right.
+  TreeNode visitSymbolLiteral(SymbolLiteral expr) => expr;
+  TreeNode visitTypeLiteral(TypeLiteral expr) => expr;
+  TreeNode visitThisExpression(ThisExpression expr) => expr;
+  TreeNode visitStringLiteral(StringLiteral expr) => expr;
+  TreeNode visitIntLiteral(IntLiteral expr) => expr;
+  TreeNode visitDoubleLiteral(DoubleLiteral expr) => expr;
+  TreeNode visitBoolLiteral(BoolLiteral expr) => expr;
+  TreeNode visitNullLiteral(NullLiteral expr) => expr;
+
+  // Nullary expressions with effects.
+  Expression nullary(Expression expr) {
+    if (seenAwait) {
+      expr = name(expr);
+      ++nameIndex;
+    }
+    return expr;
+  }
+
+  TreeNode visitInvalidExpression(InvalidExpression expr) => nullary(expr);
+  TreeNode visitSuperPropertyGet(SuperPropertyGet expr) => nullary(expr);
+  TreeNode visitStaticGet(StaticGet expr) => nullary(expr);
+  TreeNode visitRethrow(Rethrow expr) => nullary(expr);
+
+  // Getting a final or const variable is not an effect so it can be evaluated
+  // after an await to its right.
+  TreeNode visitVariableGet(VariableGet expr) {
+    if (seenAwait && !expr.variable.isFinal && !expr.variable.isConst) {
+      expr = name(expr);
+      ++nameIndex;
+    }
+    return expr;
+  }
+
+  // Transform an expression given an action to transform the children.  For
+  // this purposes of the await transformer the children should generally be
+  // translated from right to left, in the reverse of evaluation order.
+  Expression transform(Expression expr, void action()) {
+    var shouldName = seenAwait;
+
+    // 1. If there is an await in a sibling to the right, emit an assignment to
+    // a temporary variable before transforming the children.
+    var result = shouldName ? name(expr) : expr;
+
+    // 2. Remember the number of live temporaries before transforming the
+    // children.
+    var index = nameIndex;
+
+
+    // 3. Transform the children.  Initially they do not have an await in a
+    // sibling to their right.
+    seenAwait = false;
+    action();
+
+
+    // 4. If the expression was named then the variables used for children are
+    // no longer live but the variable used for the expression is.
+    if (shouldName) {
+      nameIndex = index + 1;
+      seenAwait = true;
+    }
+    return result;
+  }
+
+  // Unary expressions.
+  Expression unary(Expression expr) {
+    return transform(expr, () { expr.transformChildren(this); });
+  }
+
+  TreeNode visitVariableSet(VariableSet expr) => unary(expr);
+  TreeNode visitPropertyGet(PropertyGet expr) => unary(expr);
+  TreeNode visitDirectPropertyGet(DirectPropertyGet expr) => unary(expr);
+  TreeNode visitSuperPropertySet(SuperPropertySet expr) => unary(expr);
+  TreeNode visitStaticSet(StaticSet expr) => unary(expr);
+  TreeNode visitNot(Not expr) => unary(expr);
+  TreeNode visitIsExpression(IsExpression expr) => unary(expr);
+  TreeNode visitAsExpression(AsExpression expr) => unary(expr);
+  TreeNode visitThrow(Throw expr) => unary(expr);
+
+  TreeNode visitPropertySet(PropertySet expr) {
+    return transform(expr, () {
+      expr.value = expr.value.accept(this)..parent = expr;
+      expr.receiver = expr.receiver.accept(this)..parent = expr;
+    });
+  }
+
+  TreeNode visitDirectPropertySet(DirectPropertySet expr) {
+    return transform(expr, () {
+      expr.value = expr.value.accept(this)..parent = expr;
+      expr.receiver = expr.receiver.accept(this)..parent = expr;
+    });
+  }
+
+  TreeNode visitArguments(Arguments args) {
+    for (var named in args.named.reversed) {
+      named.value = named.value.accept(this)..parent = named;
+    }
+    var positional = args.positional;
+    for (var i = positional.length - 1; i >= 0; --i) {
+      positional[i] = positional[i].accept(this)..parent = args;
+    }
+    // Returns the arguments, which is assumed at the call sites because they do
+    // not replace the arguments or set parent pointers.
+    return args;
+  }
+
+  TreeNode visitMethodInvocation(MethodInvocation expr) {
+    return transform(expr, () {
+      visitArguments(expr.arguments);
+      expr.receiver = expr.receiver.accept(this)..parent = expr;
+    });
+  }
+
+  TreeNode visitDirectMethodInvocation(DirectMethodInvocation expr) {
+    return transform(expr, () {
+      visitArguments(expr.arguments);
+      expr.receiver = expr.receiver.accept(this)..parent = expr;
+    });
+  }
+
+  TreeNode visitSuperMethodInvocation(SuperMethodInvocation expr) {
+    return transform(expr, () { visitArguments(expr.arguments); });
+  }
+
+  TreeNode visitStaticInvocation(StaticInvocation expr) {
+    return transform(expr, () { visitArguments(expr.arguments); });
+  }
+
+  TreeNode visitConstructorInvocation(ConstructorInvocation expr) {
+    return transform(expr, () { visitArguments(expr.arguments); });
+  }
+
+  TreeNode visitStringConcatenation(StringConcatenation expr) {
+    return transform(expr, () {
+      var expressions = expr.expressions;
+      for (var i = expressions.length - 1; i >= 0; --i) {
+        expressions[i] = expressions[i].accept(this)..parent = expr;
+      }
+    });
+  }
+
+  TreeNode visitListLiteral(ListLiteral expr) {
+    return transform(expr, () {
+      var expressions = expr.expressions;
+      for (var i = expressions.length - 1; i >= 0; --i) {
+        expressions[i] = expr.expressions[i].accept(this)..parent = expr;
+      }
+    });
+  }
+
+  TreeNode visitMapLiteral(MapLiteral expr) {
+    return transform(expr, () {
+      for (var entry in expr.entries.reversed) {
+        entry.value = entry.value.accept(this)..parent = entry;
+        entry.key = entry.key.accept(this)..parent = entry;
+      }
+    });
+  }
+
+  // Control flow.
+  TreeNode visitLogicalExpression(LogicalExpression expr) {
+    var shouldName = seenAwait;
+
+    // Right is delimited because it is conditionally evaluated.
+    var rightStatements = <Statement>[];
+    seenAwait = false;
+    expr.right = delimit(() => expr.right.accept(this), rightStatements)
+        ..parent = expr;
+    var rightAwait = seenAwait;
+
+    if (rightStatements.isEmpty) {
+      // Easy case: right did not emit any statements.
+      seenAwait = shouldName;
+      return transform(expr, () {
+        expr.left = expr.left.accept(this)..parent = expr;
+        seenAwait = seenAwait || rightAwait;
+      });
+    }
+
+    // If right has emitted statements we will produce a temporary t and emit
+    // for && (there is an analogous case for ||):
+    //
+    // t = [left] == true;
+    // if (t) {
+    //   t = [right] == true;
+    // }
+
+    // Recall that statements are emitted in reverse order, so first emit the if
+    // statement, then the assignment of [left] == true, and then translate left
+    // so any statements it emits occur after in the accumulated list (that is,
+    // so they occur before in the corresponding block).
+    var rightBody = blockOf(rightStatements);
+    var result = allocateTemporary(nameIndex);
+    rightBody.addStatement(new ExpressionStatement(
+        new VariableSet(
+            result,
+            new MethodInvocation(
+                expr.right,
+                new Name('=='),
+                new Arguments(<Expression>[new BoolLiteral(true)])))));
+    var then, otherwise;
+    if (expr.operator == '&&') {
+      then = rightBody;
+      otherwise = null;
+    } else {
+      then = new EmptyStatement();
+      otherwise = rightBody;
+    }
+    statements.add(new IfStatement(new VariableGet(result), then, otherwise));
+
+    var test =
+        new MethodInvocation(
+            expr.left,
+            new Name('=='),
+            new Arguments(<Expression>[new BoolLiteral(true)]));
+    statements.add(
+        new ExpressionStatement(new VariableSet(result, test)));
+
+    seenAwait = false;
+    test.receiver = test.receiver.accept(this)..parent = test;
+
+    ++nameIndex;
+    seenAwait = seenAwait || rightAwait;
+    return new VariableGet(result);
+  }
+
+  TreeNode visitConditionalExpression(ConditionalExpression expr) {
+    // Then and otherwise are delimited because they are conditionally
+    // evaluated.
+    var shouldName = seenAwait;
+
+    var thenStatements = <Statement>[];
+    seenAwait = false;
+    expr.then = delimit(() => expr.then.accept(this), thenStatements)
+        ..parent = expr;
+    var thenAwait = seenAwait;
+
+    var otherwiseStatements = <Statement>[];
+    seenAwait = false;
+    expr.otherwise = delimit(() => expr.otherwise.accept(this),
+        otherwiseStatements)..parent = expr;
+    var otherwiseAwait = seenAwait;
+
+    if (thenStatements.isEmpty && otherwiseStatements.isEmpty) {
+      // Easy case: neither then nor otherwise emitted any statements.
+      seenAwait = shouldName;
+      return transform(expr, () {
+        expr.condition = expr.condition.accept(this)..parent = expr;
+        seenAwait = seenAwait || thenAwait || otherwiseAwait;
+      });
+    }
+
+    // If then or otherwise has emitted statements we will produce a temporary t
+    // and emit:
+    //
+    // if ([condition]) {
+    //   t = [left];
+    // } else {
+    //   t = [right];
+    // }
+    var result = allocateTemporary(nameIndex);
+    var thenBody = blockOf(thenStatements);
+    var otherwiseBody = blockOf(otherwiseStatements);
+    thenBody.addStatement(
+        new ExpressionStatement(new VariableSet(result, expr.then)));
+    otherwiseBody.addStatement(
+        new ExpressionStatement(new VariableSet(result, expr.otherwise)));
+    var branch = new IfStatement(expr.condition, thenBody, otherwiseBody);
+    statements.add(branch);
+
+    seenAwait = false;
+    branch.condition = branch.condition.accept(this)..parent = branch;
+
+    ++nameIndex;
+    seenAwait = seenAwait || thenAwait || otherwiseAwait;
+    return new VariableGet(result);
+  }
+
+  // Others.
+  TreeNode visitAwaitExpression(AwaitExpression expr) {
+    final R = continuationRewriter;
+    var shouldName = seenAwait;
+    var result = new VariableGet(asyncResult);
+    // The statements are in reverse order, so name the result first if
+    // necessary and then add the two other statements in reverse.
+    if (shouldName) result = name(result);
+    statements.add(R.createContinuationPoint());
+    Arguments arguments = new Arguments(<Expression>[
+        expr.operand,
+        new VariableGet(R.thenContinuationVariable),
+        new VariableGet(R.catchErrorContinuationVariable)]);
+    statements.add(new ExpressionStatement(
+        new StaticInvocation(R.helper.awaitHelper, arguments)));
+
+    seenAwait = false;
+    var index = nameIndex;
+    arguments.positional[0] = expr.operand.accept(this)..parent = arguments;
+
+    if (shouldName) nameIndex = index + 1;
+    seenAwait = true;
+    return result;
+  }
+
+  TreeNode visitFunctionExpression(FunctionExpression expr) {
+    expr.transformChildren(this);
+    return expr;
+  }
+
+  TreeNode visitLet(Let expr) {
+    var shouldName = seenAwait;
+
+    seenAwait = false;
+    var body = expr.body.accept(this);
+
+    VariableDeclaration variable = expr.variable;
+    if (seenAwait) {
+      // The body in `let var x = initializer in body` contained an await.  We
+      // will produce the sequence of statements:
+      //
+      // <initializer's statements>
+      // var x = <initializer's value>
+      // <body's statements>
+      //
+      // and return the body's value.
+      //
+      // So x is in scope for all the body's statements and the body's value.
+      // This has the unpleasant consequence that all let-bound variables with
+      // await in the let's body will end up hoisted out the the expression and
+      // allocated to the context in the VM, even if they have no uses
+      // (`let _ = e0 in e1` can be used for sequencing of `e0` and `e1`).
+      statements.add(variable);
+      var index = nameIndex;
+      seenAwait = false;
+      variable.initializer =
+          variable.initializer.accept(this)..parent = variable;
+      // Temporaries used in the initializer or the body are not live but the
+      // temporary used for the body is.
+      nameIndex = index + 1;
+      seenAwait = true;
+      return body;
+    } else {
+      // The body in `let x = initializer in body` did not contain an await.  We
+      // can leave a let expression.
+      seenAwait = shouldName;
+      return transform(expr, () {
+        // The body has already been translated.
+        expr.body = body..parent = expr;
+        variable.initializer =
+            variable.initializer.accept(this)..parent = variable;
+      });
+    }
+  }
+
+  visitFunctionNode(FunctionNode node) {
+    var nestedRewriter = new RecursiveContinuationRewriter(
+        continuationRewriter.helper);
+    return node.accept(nestedRewriter);
+  }
+}
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
new file mode 100644
index 0000000..fd6e1d2
--- /dev/null
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -0,0 +1,902 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.continuation;
+
+import 'dart:math' as math;
+
+import '../ast.dart';
+import '../visitor.dart';
+
+import 'async.dart';
+
+Program transformProgram(Program program) {
+  var helper = new HelperNodes.fromProgram(program);
+  var rewriter = new RecursiveContinuationRewriter(helper);
+  return rewriter.rewriteProgram(program);
+}
+
+class RecursiveContinuationRewriter extends Transformer {
+  final HelperNodes helper;
+  final VariableDeclaration asyncJumpVariable = new VariableDeclaration(
+      ":await_jump_var",
+      initializer: new IntLiteral(0));
+  final VariableDeclaration asyncContextVariable =
+      new VariableDeclaration(":await_ctx_var");
+
+  RecursiveContinuationRewriter(this.helper);
+
+  Program rewriteProgram(Program node) {
+    return node.accept(this);
+  }
+
+  visitFunctionNode(FunctionNode node) {
+    switch (node.asyncMarker) {
+      case AsyncMarker.Sync:
+      case AsyncMarker.SyncYielding:
+        node.transformChildren(new RecursiveContinuationRewriter(helper));
+        return node;
+      case AsyncMarker.SyncStar:
+        return new SyncStarFunctionRewriter(helper, node).rewrite();
+      case AsyncMarker.Async:
+        return new AsyncFunctionRewriter(helper, node).rewrite();
+      case AsyncMarker.AsyncStar:
+        return new AsyncStarFunctionRewriter(helper, node).rewrite();
+    }
+  }
+}
+
+abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter {
+  final FunctionNode enclosingFunction;
+
+  int currentTryDepth; // Nesting depth for try-blocks.
+  int currentCatchDepth = 0; // Nesting depth for catch-blocks.
+  int capturedTryDepth = 0; // Deepest yield point within a try-block.
+  int capturedCatchDepth = 0; // Deepest yield point within a catch-block.
+
+  ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction,
+      {this.currentTryDepth: 0})
+      : super(helper);
+
+  Statement createContinuationPoint([Expression value]) {
+    if (value == null) value = new NullLiteral();
+    capturedTryDepth = math.max(capturedTryDepth, currentTryDepth);
+    capturedCatchDepth = math.max(capturedCatchDepth, currentCatchDepth);
+    return new YieldStatement(value, isNative: true);
+  }
+
+  TreeNode visitTryCatch(TryCatch node) {
+    if (node.body != null) {
+      currentTryDepth++;
+      node.body = node.body.accept(this);
+      node.body?.parent = node;
+      currentTryDepth--;
+    }
+
+    currentCatchDepth++;
+    transformList(node.catches, this, node);
+    currentCatchDepth--;
+    return node;
+  }
+
+  TreeNode visitTryFinally(TryFinally node) {
+    if (node.body != null) {
+      currentTryDepth++;
+      node.body = node.body.accept(this);
+      node.body?.parent = node;
+      currentTryDepth--;
+    }
+    if (node.finalizer != null) {
+      node.finalizer = node.finalizer.accept(this);
+      node.finalizer?.parent = node;
+    }
+    return node;
+  }
+
+  Iterable<VariableDeclaration> createCapturedTryVariables() =>
+      new Iterable.generate(capturedTryDepth,
+          (depth) => new VariableDeclaration(":saved_try_context_var${depth}"));
+
+  Iterable<VariableDeclaration> createCapturedCatchVariables() =>
+      new Iterable.generate(capturedCatchDepth).expand((depth) => [
+            new VariableDeclaration(":exception${depth}"),
+            new VariableDeclaration(":stack_trace${depth}"),
+          ]);
+
+  List<VariableDeclaration> variableDeclarations() =>
+      [asyncJumpVariable, asyncContextVariable]
+        ..addAll(createCapturedTryVariables())
+        ..addAll(createCapturedCatchVariables());
+}
+
+class SyncStarFunctionRewriter extends ContinuationRewriterBase {
+  final VariableDeclaration iteratorVariable =
+      new VariableDeclaration(":iterator");
+
+  SyncStarFunctionRewriter(helper, enclosingFunction)
+      : super(helper, enclosingFunction);
+
+  FunctionNode rewrite() {
+    // :sync_body(:iterator) {
+    //     modified <node.body>;
+    // }
+    final nestedClosureVariable = new VariableDeclaration(":sync_op");
+    final function = new FunctionNode(buildClosureBody(),
+        positionalParameters: [iteratorVariable],
+        requiredParameterCount: 1,
+        asyncMarker: AsyncMarker.SyncYielding);
+    final closureFunction =
+        new FunctionDeclaration(nestedClosureVariable, function);
+
+    // return new _SyncIterable(:sync_body);
+    final arguments = new Arguments([new VariableGet(nestedClosureVariable)]);
+    final returnStatement = new ReturnStatement(
+        new ConstructorInvocation(helper.syncIterableConstructor, arguments));
+
+    enclosingFunction.body = new Block([]
+      ..addAll(variableDeclarations())
+      ..addAll([closureFunction, returnStatement]));
+    enclosingFunction.body.parent = enclosingFunction;
+    enclosingFunction.asyncMarker = AsyncMarker.Sync;
+    return enclosingFunction;
+  }
+
+  Statement buildClosureBody() {
+    // The body will insert calls to
+    //    :iterator.current_=
+    //    :iterator.isYieldEach=
+    // and return `true` as long as it did something and `false` when it's done.
+    return enclosingFunction.body.accept(this);
+  }
+
+  visitYieldStatement(YieldStatement node) {
+    var transformedExpression = node.expression.accept(this);
+
+    var statements = <Statement>[];
+    if (node.isYieldStar) {
+      var markYieldEach = new ExpressionStatement(new PropertySet(
+          new VariableGet(iteratorVariable),
+          new Name("isYieldEach", helper.coreLibrary),
+          new BoolLiteral(true)));
+      statements.add(markYieldEach);
+    }
+
+    var setCurrentIteratorValue = new ExpressionStatement(new PropertySet(
+        new VariableGet(iteratorVariable),
+        new Name("_current", helper.coreLibrary),
+        transformedExpression));
+
+    statements.add(setCurrentIteratorValue);
+    statements.add(createContinuationPoint(new BoolLiteral(true)));
+    return new Block(statements);
+  }
+}
+
+abstract class AsyncRewriterBase extends ContinuationRewriterBase {
+  final VariableDeclaration nestedClosureVariable =
+      new VariableDeclaration(":async_op");
+  final VariableDeclaration thenContinuationVariable =
+      new VariableDeclaration(":async_op_then");
+  final VariableDeclaration catchErrorContinuationVariable =
+      new VariableDeclaration(":async_op_error");
+
+  LabeledStatement labeledBody;
+
+  ExpressionLifter expressionRewriter;
+
+  AsyncRewriterBase(helper, enclosingFunction)
+      // Body is wrapped in the try-catch so initial currentTryDepth is 1.
+      : super(helper, enclosingFunction, currentTryDepth: 1) {}
+
+  void setupAsyncContinuations(List<Statement> statements) {
+    expressionRewriter = new ExpressionLifter(this);
+
+    // var :async_op_then;
+    statements.add(thenContinuationVariable);
+
+    // var :async_op_error;
+    statements.add(catchErrorContinuationVariable);
+
+    // :async_op([:result, :exception, :stack_trace]) {
+    //     modified <node.body>;
+    // }
+    final parameters = <VariableDeclaration>[
+      expressionRewriter.asyncResult,
+      new VariableDeclaration(':exception'),
+      new VariableDeclaration(':stack_trace'),
+    ];
+    final function = new FunctionNode(buildWrappedBody(),
+        positionalParameters: parameters,
+        requiredParameterCount: 0,
+        asyncMarker: AsyncMarker.SyncYielding);
+
+    // The await expression lifter might have created a number of
+    // [VariableDeclarations].
+    // TODO(kustermann): If we didn't need any variables we should not emit
+    // these.
+    statements.addAll(variableDeclarations());
+    statements.addAll(expressionRewriter.variables);
+
+    // Now add the closure function itself.
+    final closureFunction =
+        new FunctionDeclaration(nestedClosureVariable, function);
+    statements.add(closureFunction);
+
+    // :async_op_then = _asyncThenWrapperHelper(asyncBody);
+    final boundThenClosure = new StaticInvocation(helper.asyncThenWrapper,
+        new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]));
+    final thenClosureVariableAssign = new ExpressionStatement(
+        new VariableSet(thenContinuationVariable, boundThenClosure));
+    statements.add(thenClosureVariableAssign);
+
+    // :async_op_error = _asyncErrorWrapperHelper(asyncBody);
+    final boundCatchErrorClosure = new StaticInvocation(
+        helper.asyncErrorWrapper,
+        new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]));
+    final catchErrorClosureVariableAssign = new ExpressionStatement(
+        new VariableSet(
+            catchErrorContinuationVariable, boundCatchErrorClosure));
+    statements.add(catchErrorClosureVariableAssign);
+  }
+
+  Statement buildWrappedBody() {
+    labeledBody = new LabeledStatement(null);
+    labeledBody.body = visitDelimited(enclosingFunction.body)
+      ..parent = labeledBody;
+
+    var exceptionVariable = new VariableDeclaration(":exception");
+    var stackTraceVariable = new VariableDeclaration(":stack_trace");
+
+    return new TryCatch(buildReturn(labeledBody), <Catch>[
+      new Catch(
+          exceptionVariable,
+          new Block(<Statement>[
+            buildCatchBody(exceptionVariable, stackTraceVariable)
+          ]),
+          stackTrace: stackTraceVariable)
+    ]);
+  }
+
+  Statement buildCatchBody(
+      Statement exceptionVariable, Statement stackTraceVariable);
+
+  Statement buildReturn(Statement body);
+
+  List<Statement> statements = <Statement>[];
+
+  TreeNode visitInvalidStatement(InvalidStatement stmt) {
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitExpressionStatement(ExpressionStatement stmt) {
+    stmt.expression = expressionRewriter.rewrite(stmt.expression, statements)
+      ..parent = stmt;
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitBlock(Block stmt) {
+    var saved = statements;
+    statements = <Statement>[];
+    for (var statement in stmt.statements) {
+      statement.accept(this);
+    }
+    saved.add(new Block(statements));
+    statements = saved;
+    return null;
+  }
+
+  TreeNode visitEmptyStatement(EmptyStatement stmt) {
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitAssertStatement(AssertStatement stmt) {
+    // TODO!
+    return null;
+  }
+
+  Statement visitDelimited(Statement stmt) {
+    var saved = statements;
+    statements = <Statement>[];
+    stmt.accept(this);
+    Statement result =
+        statements.length == 1 ? statements.first : new Block(statements);
+    statements = saved;
+    return result;
+  }
+
+  Statement visitLabeledStatement(LabeledStatement stmt) {
+    stmt.body = visitDelimited(stmt.body)..parent = stmt;
+    statements.add(stmt);
+    return null;
+  }
+
+  Statement visitBreakStatement(BreakStatement stmt) {
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitWhileStatement(WhileStatement stmt) {
+    Statement body = visitDelimited(stmt.body);
+    List<Statement> effects = <Statement>[];
+    Expression cond = expressionRewriter.rewrite(stmt.condition, effects);
+    if (effects.isEmpty) {
+      stmt.condition = cond..parent = stmt;
+      stmt.body = body..parent = stmt;
+      statements.add(stmt);
+    } else {
+      // The condition rewrote to a non-empty sequence of statements S* and
+      // value V.  Rewrite the loop to:
+      //
+      // L: while (true) {
+      //   S*
+      //   if (V) {
+      //     [body]
+      //   else {
+      //     break L;
+      //   }
+      // }
+      LabeledStatement labeled = new LabeledStatement(stmt);
+      stmt.condition = new BoolLiteral(true)..parent = stmt;
+      effects.add(new IfStatement(cond, body, new BreakStatement(labeled)));
+      stmt.body = new Block(effects)..parent = stmt;
+      statements.add(labeled);
+    }
+    return null;
+  }
+
+  TreeNode visitDoStatement(DoStatement stmt) {
+    Statement body = visitDelimited(stmt.body);
+    List<Statement> effects = <Statement>[];
+    stmt.condition = expressionRewriter.rewrite(stmt.condition, effects)
+      ..parent = stmt;
+    if (effects.isNotEmpty) {
+      // The condition rewrote to a non-empty sequence of statements S* and
+      // value V.  Add the statements to the end of the loop body.
+      Block block = body is Block ? body : body = new Block(<Statement>[body]);
+      for (var effect in effects) {
+        block.statements.add(effect);
+        effect.parent = body;
+      }
+    }
+    stmt.body = body..parent = stmt;
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitForStatement(ForStatement stmt) {
+    // Because of for-loop scoping and variable capture, it is tricky to deal
+    // with await in the loop's variable initializers or update expressions.
+    bool isSimple = true;
+    int length = stmt.variables.length;
+    List<List<Statement>> initEffects = new List<List<Statement>>(length);
+    for (int i = 0; i < length; ++i) {
+      VariableDeclaration decl = stmt.variables[i];
+      initEffects[i] = <Statement>[];
+      if (decl.initializer != null) {
+        decl.initializer = expressionRewriter.rewrite(
+            decl.initializer, initEffects[i])..parent = decl;
+      }
+      isSimple = isSimple && initEffects[i].isEmpty;
+    }
+
+    length = stmt.updates.length;
+    List<List<Statement>> updateEffects = new List<List<Statement>>(length);
+    for (int i = 0; i < length; ++i) {
+      updateEffects[i] = <Statement>[];
+      stmt.updates[i] = expressionRewriter.rewrite(
+          stmt.updates[i], updateEffects[i])..parent = stmt;
+      isSimple = isSimple && updateEffects[i].isEmpty;
+    }
+
+    Statement body = visitDelimited(stmt.body);
+    Expression cond = stmt.condition;
+    List<Statement> condEffects;
+    if (cond != null) {
+      condEffects = <Statement>[];
+      cond = expressionRewriter.rewrite(stmt.condition, condEffects);
+    }
+
+    if (isSimple) {
+      // If the condition contains await, we use a translation like the one for
+      // while loops, but leaving the variable declarations and the update
+      // expressions in place.
+      if (condEffects == null || condEffects.isEmpty) {
+        if (cond != null) stmt.condition = cond..parent = stmt;
+        stmt.body = body..parent = stmt;
+        statements.add(stmt);
+      } else {
+        LabeledStatement labeled = new LabeledStatement(stmt);
+        // No condition in a for loop is the same as true.
+        stmt.condition = null;
+        condEffects
+            .add(new IfStatement(cond, body, new BreakStatement(labeled)));
+        stmt.body = new Block(condEffects)..parent = stmt;
+        statements.add(labeled);
+      }
+      return null;
+    }
+
+    // If the rewrite of the initializer or update expressions produces a
+    // non-empty sequence of statements then the loop is desugared.  If the loop
+    // has the form:
+    //
+    // label: for (Type x = init; cond; update) body
+    //
+    // it is translated as if it were:
+    //
+    // {
+    //   bool first = true;
+    //   Type temp;
+    //   label: while (true) {
+    //     Type x;
+    //     if (first) {
+    //       first = false;
+    //       x = init;
+    //     } else {
+    //       x = temp;
+    //       update;
+    //     }
+    //     if (cond) {
+    //       body;
+    //       temp = x;
+    //     } else {
+    //       break;
+    //     }
+    //   }
+    // }
+
+    // Place the loop variable declarations at the beginning of the body
+    // statements and move their initializers to a guarded list of statements.
+    // Add assignments to the loop variables from the previous iteration's temp
+    // variables before the updates.
+    //
+    // temps.first is the flag 'first'.
+    // TODO(kmillikin) bool type for first.
+    List<VariableDeclaration> temps = <VariableDeclaration>[
+      new VariableDeclaration.forValue(new BoolLiteral(true), isFinal: false)
+    ];
+    List<Statement> loopBody = <Statement>[];
+    List<Statement> initializers = <Statement>[
+      new ExpressionStatement(
+          new VariableSet(temps.first, new BoolLiteral(false)))
+    ];
+    List<Statement> updates = <Statement>[];
+    List<Statement> newBody = <Statement>[body];
+    for (int i = 0; i < stmt.variables.length; ++i) {
+      VariableDeclaration decl = stmt.variables[i];
+      temps.add(new VariableDeclaration(null, type: decl.type));
+      loopBody.add(decl);
+      if (decl.initializer != null) {
+        initializers.addAll(initEffects[i]);
+        initializers.add(
+            new ExpressionStatement(new VariableSet(decl, decl.initializer)));
+        decl.initializer = null;
+      }
+      updates.add(new ExpressionStatement(
+          new VariableSet(decl, new VariableGet(temps.last))));
+      newBody.add(new ExpressionStatement(
+          new VariableSet(temps.last, new VariableGet(decl))));
+    }
+    // Add the updates to their guarded list of statements.
+    for (int i = 0; i < stmt.updates.length; ++i) {
+      updates.addAll(updateEffects[i]);
+      updates.add(new ExpressionStatement(stmt.updates[i]));
+    }
+    // Initializers or updates could be empty.
+    loopBody.add(new IfStatement(new VariableGet(temps.first),
+        new Block(initializers), new Block(updates)));
+
+    LabeledStatement labeled = new LabeledStatement(null);
+    if (cond != null) {
+      loopBody.addAll(condEffects);
+    } else {
+      cond = new BoolLiteral(true);
+    }
+    loopBody.add(
+        new IfStatement(cond, new Block(newBody), new BreakStatement(labeled)));
+    labeled.body = new WhileStatement(
+        new BoolLiteral(true), new Block(loopBody))..parent = labeled;
+    statements.add(new Block(<Statement>[]
+      ..addAll(temps)
+      ..add(labeled)));
+    return null;
+  }
+
+  TreeNode visitForInStatement(ForInStatement stmt) {
+    if (stmt.isAsync) {
+      // Transform
+      //
+      //   await for (var variable in <stream-expression>) { ... }
+      //
+      // To:
+      //
+      //   {
+      //     var :for-iterator = new StreamIterator(<stream-expression>);
+      //     try {
+      //       while (await :for-iterator.moveNext()) {
+      //         var <variable> = :for-iterator.current;
+      //         ...
+      //       }
+      //     } finally {
+      //       :for-iterator.cancel();
+      //     }
+      //   }
+      var iteratorVariable = new VariableDeclaration(':for-iterator',
+          initializer: new ConstructorInvocation(
+              helper.streamIteratorConstructor,
+              new Arguments(<Expression>[stmt.iterable])));
+
+      // await iterator.moveNext()
+      var condition = new AwaitExpression(new MethodInvocation(
+          new VariableGet(iteratorVariable),
+          new Name('moveNext'),
+          new Arguments(<Expression>[])));
+
+      // var <variable> = iterator.current;
+      var valueVariable = stmt.variable;
+      valueVariable.initializer = new PropertyGet(
+          new VariableGet(iteratorVariable), new Name('current'));
+      valueVariable.initializer.parent = valueVariable;
+
+      var whileBody = new Block(<Statement>[valueVariable, stmt.body]);
+      var tryBody = new WhileStatement(condition, whileBody);
+
+      // iterator.cancel();
+      var tryFinalizer = new ExpressionStatement(new MethodInvocation(
+          new VariableGet(iteratorVariable),
+          new Name('cancel'),
+          new Arguments(<Expression>[])));
+
+      var tryFinally = new TryFinally(tryBody, tryFinalizer);
+
+      var block = new Block(<Statement>[iteratorVariable, tryFinally]);
+      block.accept(this);
+    } else {
+      stmt.iterable = expressionRewriter.rewrite(stmt.iterable, statements)
+        ..parent = stmt;
+      stmt.body = visitDelimited(stmt.body)..parent = stmt;
+      statements.add(stmt);
+    }
+    return null;
+  }
+
+  TreeNode visitSwitchStatement(SwitchStatement stmt) {
+    stmt.expression = expressionRewriter.rewrite(stmt.expression, statements)
+      ..parent = stmt;
+    for (var switchCase in stmt.cases) {
+      // Expressions in switch cases cannot contain await so they do not need to
+      // be translated.
+      switchCase.body = visitDelimited(switchCase.body)..parent = switchCase;
+    }
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitContinueSwitchStatement(ContinueSwitchStatement stmt) {
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitIfStatement(IfStatement stmt) {
+    stmt.condition = expressionRewriter.rewrite(stmt.condition, statements)
+      ..parent = stmt;
+    stmt.then = visitDelimited(stmt.then)..parent = stmt;
+    if (stmt.otherwise != null) {
+      stmt.otherwise = visitDelimited(stmt.otherwise)..parent = stmt;
+    }
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitTryCatch(TryCatch stmt) {
+    ++currentTryDepth;
+    stmt.body = visitDelimited(stmt.body)..parent = stmt;
+    --currentTryDepth;
+
+    ++currentCatchDepth;
+    for (var clause in stmt.catches) {
+      clause.body = visitDelimited(clause.body)..parent = clause;
+    }
+    --currentCatchDepth;
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitTryFinally(TryFinally stmt) {
+    ++currentTryDepth;
+    stmt.body = visitDelimited(stmt.body)..parent = stmt;
+    --currentTryDepth;
+    stmt.finalizer = visitDelimited(stmt.finalizer)..parent = stmt;
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitYieldStatement(YieldStatement stmt) {
+    stmt.expression = expressionRewriter.rewrite(stmt.expression, statements)
+      ..parent = stmt;
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitVariableDeclaration(VariableDeclaration stmt) {
+    if (stmt.initializer != null) {
+      stmt.initializer = expressionRewriter.rewrite(
+          stmt.initializer, statements)..parent = stmt;
+    }
+    statements.add(stmt);
+    return null;
+  }
+
+  TreeNode visitFunctionDeclaration(FunctionDeclaration stmt) {
+    stmt.function = stmt.function.accept(this)..parent = stmt;
+    statements.add(stmt);
+    return null;
+  }
+
+  defaultExpression(TreeNode node) => throw 'unreachable';
+}
+
+class AsyncStarFunctionRewriter extends AsyncRewriterBase {
+  VariableDeclaration controllerVariable;
+
+  AsyncStarFunctionRewriter(helper, enclosingFunction)
+      : super(helper, enclosingFunction);
+
+  FunctionNode rewrite() {
+    var statements = <Statement>[];
+
+    // var :controller;
+    controllerVariable = new VariableDeclaration(":controller");
+    statements.add(controllerVariable);
+
+    setupAsyncContinuations(statements);
+
+    // :controller = new _AsyncController(:async_op);
+    var arguments =
+        new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]);
+    var buildController = new ConstructorInvocation(
+        helper.streamControllerConstructor, arguments);
+    var setController = new ExpressionStatement(
+        new VariableSet(controllerVariable, buildController));
+    statements.add(setController);
+
+    // return :controller.stream;
+    var completerGet = new VariableGet(controllerVariable);
+    var returnStatement = new ReturnStatement(
+        new PropertyGet(completerGet, new Name('stream', helper.asyncLibrary)));
+    statements.add(returnStatement);
+
+    enclosingFunction.body = new Block(statements);
+    enclosingFunction.body.parent = enclosingFunction;
+    enclosingFunction.asyncMarker = AsyncMarker.Sync;
+    return enclosingFunction;
+  }
+
+  Statement buildCatchBody(exceptionVariable, stackTraceVariable) {
+    return new ExpressionStatement(new MethodInvocation(
+        new VariableGet(controllerVariable),
+        new Name("completeError", helper.asyncLibrary),
+        new Arguments(<Expression>[
+          new VariableGet(exceptionVariable),
+          new VariableGet(stackTraceVariable)
+        ])));
+  }
+
+  Statement buildReturn(Statement body) {
+    // Async* functions cannot return a value.  The returns from the function
+    // have been translated into breaks from the labeled body.
+    return new Block(<Statement>[
+      body,
+      new ExpressionStatement(new MethodInvocation(
+          new VariableGet(controllerVariable),
+          new Name("close", helper.asyncLibrary),
+          new Arguments(<Expression>[]))),
+      new ReturnStatement()
+    ]);
+  }
+
+  TreeNode visitYieldStatement(YieldStatement stmt) {
+    Expression expr = expressionRewriter.rewrite(stmt.expression, statements);
+
+    var addExpression = new MethodInvocation(
+        new VariableGet(controllerVariable),
+        new Name(stmt.isYieldStar ? 'addStream' : 'add', helper.asyncLibrary),
+        new Arguments(<Expression>[expr]));
+
+    statements.add(new IfStatement(addExpression,
+        new ReturnStatement(new NullLiteral()), createContinuationPoint()));
+    return null;
+  }
+
+  TreeNode visitReturnStatement(ReturnStatement node) {
+    // Async* functions cannot return a value.
+    assert(node.expression == null || node.expression is NullLiteral);
+    statements
+        .add(new BreakStatement(labeledBody)..fileOffset = node.fileOffset);
+    return null;
+  }
+}
+
+class AsyncFunctionRewriter extends AsyncRewriterBase {
+  VariableDeclaration completerVariable;
+  VariableDeclaration returnVariable;
+
+  AsyncFunctionRewriter(helper, enclosingFunction)
+      : super(helper, enclosingFunction);
+
+  FunctionNode rewrite() {
+    var statements = <Statement>[];
+
+    // var :completer = new Completer.sync();
+    completerVariable = new VariableDeclaration(":completer",
+        initializer: new StaticInvocation(
+            helper.completerConstructor, new Arguments([])),
+        isFinal: true);
+    statements.add(completerVariable);
+
+    returnVariable = new VariableDeclaration(":return_value");
+    statements.add(returnVariable);
+
+    setupAsyncContinuations(statements);
+
+    // new Future.microtask(:async_op);
+    var newMicrotaskStatement = new ExpressionStatement(new StaticInvocation(
+        helper.futureMicrotaskConstructor,
+        new Arguments([new VariableGet(nestedClosureVariable)])));
+    statements.add(newMicrotaskStatement);
+
+    // return :completer.future;
+    var completerGet = new VariableGet(completerVariable);
+    var returnStatement = new ReturnStatement(
+        new PropertyGet(completerGet, new Name('future', helper.asyncLibrary)));
+    statements.add(returnStatement);
+
+    enclosingFunction.body = new Block(statements);
+    enclosingFunction.body.parent = enclosingFunction;
+    enclosingFunction.asyncMarker = AsyncMarker.Sync;
+    return enclosingFunction;
+  }
+
+  Statement buildCatchBody(exceptionVariable, stackTraceVariable) {
+    return new ExpressionStatement(new MethodInvocation(
+        new VariableGet(completerVariable),
+        new Name("completeError", helper.asyncLibrary),
+        new Arguments([
+          new VariableGet(exceptionVariable),
+          new VariableGet(stackTraceVariable)
+        ])));
+  }
+
+  Statement buildReturn(Statement body) {
+    // Returns from the body have all been translated into assignments to the
+    // return value variable followed by a break from the labeled body.
+    return new Block(<Statement>[
+      body,
+      new ExpressionStatement(new MethodInvocation(
+          new VariableGet(completerVariable),
+          new Name("complete", helper.asyncLibrary),
+          new Arguments([new VariableGet(returnVariable)]))),
+      new ReturnStatement()
+    ]);
+  }
+
+  visitReturnStatement(ReturnStatement node) {
+    var expr = node.expression == null
+        ? new NullLiteral()
+        : expressionRewriter.rewrite(node.expression, statements);
+    statements
+        .add(new ExpressionStatement(new VariableSet(returnVariable, expr)));
+    statements
+        .add(new BreakStatement(labeledBody)..fileOffset = node.fileOffset);
+    return null;
+  }
+}
+
+class HelperNodes {
+  final Library asyncLibrary;
+  final Library coreLibrary;
+  final Procedure printProcedure;
+  final Procedure completerConstructor;
+  final Procedure futureMicrotaskConstructor;
+  final Constructor streamControllerConstructor;
+  final Constructor syncIterableConstructor;
+  final Constructor streamIteratorConstructor;
+  final Procedure asyncThenWrapper;
+  final Procedure asyncErrorWrapper;
+  final Procedure awaitHelper;
+
+  HelperNodes(
+      this.asyncLibrary,
+      this.coreLibrary,
+      this.printProcedure,
+      this.completerConstructor,
+      this.syncIterableConstructor,
+      this.streamIteratorConstructor,
+      this.futureMicrotaskConstructor,
+      this.streamControllerConstructor,
+      this.asyncThenWrapper,
+      this.asyncErrorWrapper,
+      this.awaitHelper);
+
+  factory HelperNodes.fromProgram(Program program) {
+    Library findLibrary(String name) {
+      Uri uri = Uri.parse(name);
+      for (var library in program.libraries) {
+        if (library.importUri == uri) return library;
+      }
+      throw 'Library "$name" not found';
+    }
+
+    Class findClass(Library library, String name) {
+      for (var klass in library.classes) {
+        if (klass.name == name) return klass;
+      }
+      throw 'Class "$name" not found';
+    }
+
+    Procedure findFactoryConstructor(Class klass, String name) {
+      for (var procedure in klass.procedures) {
+        if (procedure.isStatic && procedure.name.name == name) return procedure;
+      }
+      throw 'Factory constructor "$klass.$name" not found';
+    }
+
+    Constructor findConstructor(Class klass, String name) {
+      for (var constructor in klass.constructors) {
+        if (constructor.name.name == name) return constructor;
+      }
+      throw 'Constructor "$klass.$name" not found';
+    }
+
+    Procedure findProcedure(Library library, String name) {
+      for (var procedure in library.procedures) {
+        if (procedure.name.name == name ||
+            procedure.name.name == '${library.name}::${name}') {
+          return procedure;
+        }
+      }
+      throw 'Procedure "$name" not found';
+    }
+
+    var asyncLibrary = findLibrary('dart:async');
+    var coreLibrary = findLibrary('dart:core');
+
+    var completerClass = findClass(asyncLibrary, 'Completer');
+    var futureClass = findClass(asyncLibrary, 'Future');
+
+    // The VM's dart:async implementation has renamed _StreamIteratorImpl to
+    // _StreamIterator.  To support both old and new library implementations we
+    // look for the old name first and then the new name.
+    var streamIteratorClass;
+    try {
+      streamIteratorClass = findClass(asyncLibrary, '_StreamIteratorImpl');
+    } catch (e) {
+      if (e == 'Class "_StreamIteratorImpl" not found') {
+        streamIteratorClass = findClass(asyncLibrary, '_StreamIterator');
+      } else {
+        rethrow;
+      }
+    }
+
+    var syncIterableClass = findClass(coreLibrary, '_SyncIterable');
+    var streamControllerClass =
+        findClass(asyncLibrary, '_AsyncStarStreamController');
+
+    return new HelperNodes(
+        asyncLibrary,
+        coreLibrary,
+        findProcedure(coreLibrary, 'print'),
+        findFactoryConstructor(completerClass, 'sync'),
+        findConstructor(syncIterableClass, ''),
+        findConstructor(streamIteratorClass, ''),
+        findFactoryConstructor(futureClass, 'microtask'),
+        findConstructor(streamControllerClass, ''),
+        findProcedure(asyncLibrary, '_asyncThenWrapperHelper'),
+        findProcedure(asyncLibrary, '_asyncErrorWrapperHelper'),
+        findProcedure(asyncLibrary, '_awaitHelper'));
+  }
+}
diff --git a/pkg/kernel/lib/transformations/erasure.dart b/pkg/kernel/lib/transformations/erasure.dart
new file mode 100644
index 0000000..d2cb413
--- /dev/null
+++ b/pkg/kernel/lib/transformations/erasure.dart
@@ -0,0 +1,147 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.erasure;
+
+import '../ast.dart';
+import '../type_algebra.dart';
+
+/// This pass is a temporary measure to run strong mode code in the VM, which
+/// does not yet have the necessary runtime support.
+///
+/// Function type parameter lists are cleared and all uses of a function type
+/// parameter are replaced by its upper bound.
+///
+/// All uses of type parameters in constants are replaced by 'dynamic'.
+///
+/// This does not preserve dynamic type safety.
+class Erasure extends Transformer {
+  final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
+  final Map<TypeParameter, DartType> constantSubstitution =
+      <TypeParameter, DartType>{};
+
+  int constantContexts = 0;
+
+  void transform(Program program) {
+    program.accept(this);
+  }
+
+  void pushConstantContext() {
+    ++constantContexts;
+  }
+
+  void popConstantContext() {
+    --constantContexts;
+  }
+
+  bool get isInConstantContext => constantContexts > 0;
+
+  @override
+  visitDartType(DartType type) {
+    type = substitute(type, substitution);
+    if (isInConstantContext) {
+      type = substitute(type, constantSubstitution);
+    }
+    return type;
+  }
+
+  @override
+  visitClass(Class node) {
+    for (var parameter in node.typeParameters) {
+      constantSubstitution[parameter] = const DynamicType();
+    }
+    node.transformChildren(this);
+    constantSubstitution.clear();
+    return node;
+  }
+
+  @override
+  visitProcedure(Procedure node) {
+    if (node.kind == ProcedureKind.Factory) {
+      assert(node.enclosingClass != null);
+      assert(node.enclosingClass.typeParameters.length ==
+          node.function.typeParameters.length);
+      // Factories can have function type parameters as long as they correspond
+      // exactly to those on the enclosing class. However, these type parameters
+      // may still not be in a constant.
+      for (var parameter in node.function.typeParameters) {
+        constantSubstitution[parameter] = const DynamicType();
+      }
+      // Skip the visitFunctionNode but traverse body.
+      node.function.transformChildren(this);
+      node.function.typeParameters.forEach(constantSubstitution.remove);
+    } else {
+      node.transformChildren(this);
+    }
+    return node;
+  }
+
+  bool isObject(DartType type) {
+    return type is InterfaceType && type.classNode.supertype == null;
+  }
+
+  @override
+  visitFunctionNode(FunctionNode node) {
+    for (var parameter in node.typeParameters) {
+      substitution[parameter] = const DynamicType();
+    }
+    for (var parameter in node.typeParameters) {
+      if (!isObject(parameter.bound)) {
+        substitution[parameter] = substitute(parameter.bound, substitution);
+      }
+    }
+    node.transformChildren(this);
+    node.typeParameters.forEach(substitution.remove);
+    node.typeParameters.clear();
+    return node;
+  }
+
+  @override
+  visitStaticInvocation(StaticInvocation node) {
+    if (node.target.kind != ProcedureKind.Factory) {
+      node.arguments.types.clear();
+    }
+    if (node.isConst) pushConstantContext();
+    node.transformChildren(this);
+    if (node.isConst) popConstantContext();
+    return node;
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    node.arguments.types.clear();
+    node.transformChildren(this);
+    return node;
+  }
+
+  @override
+  visitDirectMethodInvocation(DirectMethodInvocation node) {
+    node.arguments.types.clear();
+    node.transformChildren(this);
+    return node;
+  }
+
+  @override
+  visitConstructorInvocation(ConstructorInvocation node) {
+    if (node.isConst) pushConstantContext();
+    node.transformChildren(this);
+    if (node.isConst) popConstantContext();
+    return node;
+  }
+
+  @override
+  visitListLiteral(ListLiteral node) {
+    if (node.isConst) pushConstantContext();
+    node.transformChildren(this);
+    if (node.isConst) popConstantContext();
+    return node;
+  }
+
+  @override
+  visitMapLiteral(MapLiteral node) {
+    if (node.isConst) pushConstantContext();
+    node.transformChildren(this);
+    if (node.isConst) popConstantContext();
+    return node;
+  }
+}
diff --git a/pkg/kernel/lib/transformations/flags.dart b/pkg/kernel/lib/transformations/flags.dart
new file mode 100644
index 0000000..32cd627
--- /dev/null
+++ b/pkg/kernel/lib/transformations/flags.dart
@@ -0,0 +1,21 @@
+library kernel.transformations.flags;
+
+import '../ast.dart';
+
+/// Flags summarizing the kinds of AST nodes contained in a given member or
+/// class, for speeding up transformations that only affect certain types of
+/// nodes.
+///
+/// These are set by the frontend and the deserializer.
+class TransformerFlag {
+  /// The class or member contains 'super' calls, that is, one of the AST nodes
+  /// [SuperPropertyGet], [SuperPropertySet], [SuperMethodInvocation].
+  static const int superCalls = 1 << 0;
+
+  /// Temporary flag used by the verifier to indicate that the given member
+  /// has been seen.
+  static const int seenByVerifier = 1 << 1;
+
+  // TODO(asgerf):  We could also add a flag for 'async' and will probably have
+  // one for closures as well.
+}
diff --git a/pkg/kernel/lib/transformations/infer_values.dart b/pkg/kernel/lib/transformations/infer_values.dart
new file mode 100644
index 0000000..c7d51c5
--- /dev/null
+++ b/pkg/kernel/lib/transformations/infer_values.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.infer_types;
+
+import '../ast.dart';
+import '../type_propagation/type_propagation.dart';
+
+Program transformProgram(Program program) {
+  TypePropagation propagation = new TypePropagation(program);
+
+  var attacher = new InferredValueAttacher(propagation, program);
+  attacher.attachInferredValues();
+
+  return program;
+}
+
+class InferredValueAttacher extends RecursiveVisitor {
+  final TypePropagation propagation;
+  final Program program;
+
+  InferredValueAttacher(this.propagation, this.program);
+
+  attachInferredValues() => program.accept(this);
+
+  visitField(Field node) {
+    node.inferredValue = propagation.getFieldValue(node);
+    super.visitField(node);
+  }
+
+  visitFunctionNode(FunctionNode node) {
+    node.positionalParameters.forEach(_annotateVariableDeclaration);
+    node.namedParameters.forEach(_annotateVariableDeclaration);
+    node.inferredReturnValue = propagation.getReturnValue(node);
+    super.visitFunctionNode(node);
+  }
+
+  _annotateVariableDeclaration(VariableDeclaration variable) {
+    variable.inferredValue = propagation.getParameterValue(variable);
+  }
+}
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
new file mode 100644
index 0000000..7669b1a
--- /dev/null
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -0,0 +1,368 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.mixin_full_resolution;
+
+import '../ast.dart';
+import '../class_hierarchy.dart';
+import '../clone.dart';
+import '../core_types.dart';
+import '../type_algebra.dart';
+
+Program transformProgram(Program program) {
+  new MixinFullResolution().transform(program);
+  return program;
+}
+
+/// Replaces all mixin applications with regular classes, cloning all fields
+/// and procedures from the mixed-in class, cloning all constructors from the
+/// base class.
+///
+/// Super calls (as well as super initializer invocations) are also resolved
+/// to their targets in this pass.
+class MixinFullResolution {
+  ClassHierarchy hierarchy;
+  CoreTypes coreTypes;
+
+  void transform(Program program) {
+    var transformedClasses = new Set<Class>();
+
+    // Desugar all mixin application classes by copying in fields/methods from
+    // the mixin and constructors from the base class.
+    var processedClasses = new Set<Class>();
+    for (var library in program.libraries) {
+      for (var class_ in library.classes) {
+        transformClass(processedClasses, transformedClasses, class_);
+      }
+    }
+
+    hierarchy = new ClassHierarchy(program);
+    coreTypes = new CoreTypes(program);
+
+    // Resolve all super call expressions and super initializers.
+    for (var library in program.libraries) {
+      for (var class_ in library.classes) {
+        final bool hasTransformedSuperclass =
+            transformedClasses.contains(class_.superclass);
+
+        for (var procedure in class_.procedures) {
+          if (procedure.containsSuperCalls) {
+            new SuperCallResolutionTransformer(
+                    hierarchy, coreTypes, class_.superclass)
+                .visit(procedure);
+          }
+        }
+        for (var constructor in class_.constructors) {
+          if (constructor.containsSuperCalls) {
+            new SuperCallResolutionTransformer(
+                    hierarchy, coreTypes, class_.superclass)
+                .visit(constructor);
+          }
+          if (hasTransformedSuperclass && constructor.initializers.length > 0) {
+            new SuperInitializerResolutionTransformer(class_.superclass)
+                .transformInitializers(constructor.initializers);
+          }
+        }
+      }
+    }
+  }
+
+  transformClass(Set<Class> processedClasses, Set<Class> transformedClasses,
+      Class class_) {
+    // If this class was already handled then so were all classes up to the
+    // [Object] class.
+    if (!processedClasses.add(class_)) return;
+
+    // Ensure super classes have been transformed before this class.
+    if (class_.superclass != null) {
+      transformClass(processedClasses, transformedClasses, class_.superclass);
+    }
+
+    // If this is not a mixin application we don't need to make forwarding
+    // constructors in this class.
+    if (!class_.isMixinApplication) return;
+
+    transformedClasses.add(class_);
+
+    // Clone fields and methods from the mixin class.
+    var substitution = getSubstitutionMap(class_.mixedInType);
+    var cloner = new CloneVisitor(typeSubstitution: substitution);
+    for (var field in class_.mixin.fields) {
+      class_.addMember(cloner.clone(field));
+    }
+    for (var procedure in class_.mixin.procedures) {
+      class_.addMember(cloner.clone(procedure));
+    }
+    // For each generative constructor in the superclass we make a
+    // corresponding forwarding constructor in the subclass.
+    // Named mixin applications already have constructors, so only build the
+    // constructors for anonymous mixin applications.
+    if (class_.constructors.isEmpty) {
+      var superclassSubstitution = getSubstitutionMap(class_.supertype);
+      var superclassCloner =
+          new CloneVisitor(typeSubstitution: superclassSubstitution);
+      for (var superclassConstructor in class_.superclass.constructors) {
+        var forwardingConstructor =
+            buildForwardingConstructor(superclassCloner, superclassConstructor);
+        class_.constructors.add(forwardingConstructor..parent = class_);
+      }
+    }
+
+    // This class implements the mixin type.
+    class_.implementedTypes.add(class_.mixedInType);
+
+    // This class is now a normal class.
+    class_.mixedInType = null;
+  }
+
+  Constructor buildForwardingConstructor(
+      CloneVisitor cloner, Constructor superclassConstructor) {
+    var superFunction = superclassConstructor.function;
+
+    // We keep types and default values for the parameters but always mark the
+    // parameters as final (since we just forward them to the super
+    // constructor).
+    VariableDeclaration cloneVariable(VariableDeclaration variable) {
+      VariableDeclaration clone = cloner.clone(variable);
+      clone.isFinal = true;
+      return clone;
+    }
+
+    // Build a [FunctionNode] which has the same parameters as the one in the
+    // superclass constructor.
+    var positionalParameters =
+        superFunction.positionalParameters.map(cloneVariable).toList();
+    var namedParameters =
+        superFunction.namedParameters.map(cloneVariable).toList();
+    var function = new FunctionNode(new EmptyStatement(),
+        positionalParameters: positionalParameters,
+        namedParameters: namedParameters,
+        requiredParameterCount: superFunction.requiredParameterCount,
+        returnType: const VoidType());
+
+    // Build a [SuperInitializer] which takes all positional/named parameters
+    // and forward them to the super class constructor.
+    var positionalArguments = <Expression>[];
+    for (var variable in positionalParameters) {
+      positionalArguments.add(new VariableGet(variable));
+    }
+    var namedArguments = <NamedExpression>[];
+    for (var variable in namedParameters) {
+      namedArguments
+          .add(new NamedExpression(variable.name, new VariableGet(variable)));
+    }
+    var superInitializer = new SuperInitializer(superclassConstructor,
+        new Arguments(positionalArguments, named: namedArguments));
+
+    // Assemble the constructor.
+    return new Constructor(function,
+        name: superclassConstructor.name,
+        initializers: <Initializer>[superInitializer]);
+  }
+}
+
+class SuperCallResolutionTransformer extends Transformer {
+  final ClassHierarchy hierarchy;
+  final CoreTypes coreTypes;
+  final Class lookupClass;
+  Constructor _invocationMirrorConstructor; // cached
+  Procedure _listFrom; // cached
+
+  SuperCallResolutionTransformer(
+      this.hierarchy, this.coreTypes, this.lookupClass);
+
+  TreeNode visit(TreeNode node) => node.accept(this);
+
+  visitSuperPropertyGet(SuperPropertyGet node) {
+    Member target = hierarchy.getDispatchTarget(lookupClass, node.name);
+    if (target != null) {
+      return new DirectPropertyGet(new ThisExpression(), target);
+    } else {
+      return _callNoSuchMethod(node.name.name, new Arguments.empty(), node,
+          isGetter: true);
+    }
+  }
+
+  visitSuperPropertySet(SuperPropertySet node) {
+    Member target =
+        hierarchy.getDispatchTarget(lookupClass, node.name, setter: true);
+    if (target != null) {
+      return new DirectPropertySet(
+          new ThisExpression(), target, visit(node.value));
+    } else {
+      // Call has to return right-hand-side.
+      VariableDeclaration rightHandSide =
+          new VariableDeclaration.forValue(visit(node.value));
+      Expression result = _callNoSuchMethod(
+          node.name.name, new Arguments([new VariableGet(rightHandSide)]), node,
+          isSetter: true);
+      VariableDeclaration call = new VariableDeclaration.forValue(result);
+      return new Let(
+          rightHandSide, new Let(call, new VariableGet(rightHandSide)));
+    }
+  }
+
+  visitSuperMethodInvocation(SuperMethodInvocation node) {
+    Member target = hierarchy.getDispatchTarget(lookupClass, node.name);
+    Arguments visitedArguments = visit(node.arguments);
+    if (target is Procedure &&
+        !target.isAccessor &&
+        _callIsLegal(target.function, visitedArguments)) {
+      return new DirectMethodInvocation(
+          new ThisExpression(), target, visitedArguments)
+        ..fileOffset = node.fileOffset;
+    } else if (target == null || (target is Procedure && !target.isAccessor)) {
+      // Target not found at all, or call was illegal.
+      return _callNoSuchMethod(node.name.name, visitedArguments, node,
+          isSuper: true);
+    } else if (target != null) {
+      return new MethodInvocation(
+          new DirectPropertyGet(new ThisExpression(), target),
+          new Name('call'),
+          visitedArguments)..fileOffset = node.fileOffset;
+    }
+  }
+
+  /// Create a call to no such method.
+  Expression _callNoSuchMethod(
+      String methodName, Arguments methodArguments, TreeNode node,
+      {isSuper: false, isGetter: false, isSetter: false}) {
+    Member noSuchMethod =
+        hierarchy.getDispatchTarget(lookupClass, new Name("noSuchMethod"));
+    String methodNameUsed = (isGetter)
+        ? "get:$methodName"
+        : (isSetter) ? "set:$methodName" : methodName;
+    if (noSuchMethod != null &&
+        noSuchMethod.function.positionalParameters.length == 1 &&
+        noSuchMethod.function.namedParameters.isEmpty) {
+      // We have a correct noSuchMethod method.
+      ConstructorInvocation invocation = _createInvocation(
+          methodNameUsed, methodArguments, isSuper, new ThisExpression());
+      return new DirectMethodInvocation(
+          new ThisExpression(), noSuchMethod, new Arguments([invocation]))
+        ..fileOffset = node.fileOffset;
+    } else {
+      // Incorrect noSuchMethod method: Call noSuchMethod on Object
+      // with Invocation of noSuchMethod as the method that did not exist.
+      noSuchMethod = hierarchy.getDispatchTarget(
+          hierarchy.rootClass, new Name("noSuchMethod"));
+      ConstructorInvocation invocation = _createInvocation(
+          methodNameUsed, methodArguments, isSuper, new ThisExpression());
+      ConstructorInvocation invocationPrime = _createInvocation("noSuchMethod",
+          new Arguments([invocation]), false, new ThisExpression());
+      return new DirectMethodInvocation(
+          new ThisExpression(), noSuchMethod, new Arguments([invocationPrime]))
+        ..fileOffset = node.fileOffset;
+    }
+  }
+
+  /// Creates an "new _InvocationMirror(...)" invocation.
+  ConstructorInvocation _createInvocation(String methodName,
+      Arguments callArguments, bool isSuperInvocation, Expression receiver) {
+    if (_invocationMirrorConstructor == null) {
+      Class clazz = coreTypes.getCoreClass('dart:core', '_InvocationMirror');
+      _invocationMirrorConstructor = clazz.constructors[0];
+    }
+
+    // The _InvocationMirror constructor takes the following arguments:
+    // * Method name (a string).
+    // * An arguments descriptor - a list consisting of:
+    //   - number of arguments (including receiver).
+    //   - number of positional arguments (including receiver).
+    //   - pairs (2 entries in the list) of
+    //     * named arguments name.
+    //     * index of named argument in arguments list.
+    // * A list of arguments, where the first ones are the positional arguments.
+    // * Whether it's a super invocation or not.
+
+    int numPositionalArguments = callArguments.positional.length + 1;
+    int numArguments = numPositionalArguments + callArguments.named.length;
+    List<Expression> argumentsDescriptor = [
+      new IntLiteral(numArguments),
+      new IntLiteral(numPositionalArguments)
+    ];
+    List<Expression> arguments = [];
+    arguments.add(receiver);
+    for (Expression pos in callArguments.positional) {
+      arguments.add(pos);
+    }
+    for (NamedExpression named in callArguments.named) {
+      argumentsDescriptor.add(new StringLiteral(named.name));
+      argumentsDescriptor.add(new IntLiteral(arguments.length));
+      arguments.add(named.value);
+    }
+
+    return new ConstructorInvocation(
+        _invocationMirrorConstructor,
+        new Arguments([
+          new StringLiteral(methodName),
+          _fixedLengthList(argumentsDescriptor),
+          _fixedLengthList(arguments),
+          new BoolLiteral(isSuperInvocation)
+        ]));
+  }
+
+  /// Create a fixed length list containing given expressions.
+  Expression _fixedLengthList(List<Expression> list) {
+    if (_listFrom == null) {
+      Class clazz = coreTypes.getCoreClass('dart:core', 'List');
+      _listFrom = clazz.procedures.firstWhere((c) => c.name.name == "from");
+    }
+    return new StaticInvocation(
+        _listFrom,
+        new Arguments([new ListLiteral(list)],
+            named: [new NamedExpression("growable", new BoolLiteral(false))]));
+  }
+
+  /// Check that a call to the targetFunction is legal given the arguments.
+  ///
+  /// I.e. check that the number of positional parameters and the names of the
+  /// given named parameters represents a valid call to the function.
+  bool _callIsLegal(FunctionNode targetFunction, Arguments arguments) {
+    if ((targetFunction.requiredParameterCount > arguments.positional.length) ||
+        (targetFunction.positionalParameters.length <
+            arguments.positional.length)) {
+      // Given too few or too many positional arguments
+      return false;
+    }
+
+    // Do we give named that we don't take?
+    Set<String> givenNamed = arguments.named.map((v) => v.name).toSet();
+    Set<String> takenNamed =
+        targetFunction.namedParameters.map((v) => v.name).toSet();
+    givenNamed.removeAll(takenNamed);
+    return givenNamed.isEmpty;
+  }
+}
+
+class SuperInitializerResolutionTransformer extends InitializerVisitor {
+  final Class lookupClass;
+
+  SuperInitializerResolutionTransformer(this.lookupClass);
+
+  transformInitializers(List<Initializer> initializers) {
+    for (var initializer in initializers) {
+      initializer.accept(this);
+    }
+  }
+
+  visitSuperInitializer(SuperInitializer node) {
+    Constructor constructor = node.target;
+    if (constructor.enclosingClass != lookupClass) {
+      // If [node] refers to a constructor target which is not directly the
+      // superclass but some indirect base class then this is because classes in
+      // the middle are mixin applications.  These mixin applications will have
+      // received a forwarding constructor which we are required to use instead.
+      for (var replacement in lookupClass.constructors) {
+        if (constructor.name == replacement.name) {
+          node.target = replacement;
+          return null;
+        }
+      }
+
+      throw new Exception(
+          'Could not find a generative constructor named "${constructor.name}" '
+          'in lookup class "${lookupClass.name}"!');
+    }
+  }
+}
diff --git a/pkg/kernel/lib/transformations/sanitize_for_vm.dart b/pkg/kernel/lib/transformations/sanitize_for_vm.dart
new file mode 100644
index 0000000..f5f86c3
--- /dev/null
+++ b/pkg/kernel/lib/transformations/sanitize_for_vm.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.fixvm;
+
+import '../ast.dart';
+
+/// Ensures that classes all have either a constructor or a procedure.
+///
+/// VM-specific constraints that don't fit in anywhere else can be put here.
+class SanitizeForVM {
+  void transform(Program program) {
+    for (var library in program.libraries) {
+      for (var class_ in library.classes) {
+        if (class_.constructors.isEmpty && class_.procedures.isEmpty) {
+          class_.addMember(new Constructor(
+              new FunctionNode(new InvalidStatement()),
+              name: new Name('')));
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/kernel/lib/transformations/setup_builtin_library.dart b/pkg/kernel/lib/transformations/setup_builtin_library.dart
new file mode 100644
index 0000000..cc4149a
--- /dev/null
+++ b/pkg/kernel/lib/transformations/setup_builtin_library.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.setup_builtin_library;
+
+import '../ast.dart';
+
+// The DartVM has a special `dart:_builtin` library which exposes a
+// `_getMainClosure()` method.  We need to change this method to return a
+// closure of `main()`.
+Program transformProgram(Program program,
+    {String libraryUri: 'dart:_builtin'}) {
+  Procedure mainMethod = program.mainMethod;
+
+  Library builtinLibrary;
+  for (Library library in program.libraries) {
+    if (library.importUri.toString() == libraryUri) {
+      builtinLibrary = library;
+      break;
+    }
+  }
+
+  if (builtinLibrary == null) {
+    throw new Exception('Could not find "dart:_builtin" library');
+  }
+
+  FunctionNode getMainClosure;
+  for (Procedure procedure in builtinLibrary.procedures) {
+    if (procedure.name.name == '_getMainClosure') {
+      getMainClosure = procedure.function;
+      break;
+    }
+  }
+
+  if (getMainClosure == null) {
+    throw new Exception('Could not find "_getMainClosure" in "$libraryUri"');
+  }
+
+  var returnMainStatement = new ReturnStatement(new StaticGet(mainMethod));
+  getMainClosure.body = returnMainStatement;
+  returnMainStatement.parent = getMainClosure;
+
+  return program;
+}
diff --git a/pkg/kernel/lib/transformations/treeshaker.dart b/pkg/kernel/lib/transformations/treeshaker.dart
new file mode 100644
index 0000000..bd33595
--- /dev/null
+++ b/pkg/kernel/lib/transformations/treeshaker.dart
@@ -0,0 +1,779 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.tree_shaker;
+
+import '../ast.dart';
+import '../class_hierarchy.dart';
+import '../core_types.dart';
+
+Program transformProgram(Program program) {
+  new TreeShaker(program).transform(program);
+  return program;
+}
+
+/// Tree shaking based on class hierarchy analysis.
+///
+/// Any dynamic dispatch not on `this` is conservatively assumed to target
+/// any instantiated class that implements a member matching the selector.
+///
+/// Member bodies are analyzed relative to a given "host class" which is the
+/// concrete type of `this` (or null if in static context), so dispatches on
+/// `this` can be resolved more precisely.
+///
+/// The tree shaker computes the following in a fixed-point iteration:
+/// - a set of instantiated classes
+/// - for each member, a set of potential host classes
+/// - a set of names used in dynamic dispatch not on `this`
+///
+/// The `dart:mirrors` library is not supported.
+//
+// TODO(asgerf): Shake off parts of the core libraries based on the Target.
+// TODO(asgerf): Tree shake unused instance fields.
+class TreeShaker {
+  final Program program;
+  final ClassHierarchy hierarchy;
+  final CoreTypes coreTypes;
+
+  /// Names used in a dynamic dispatch invocation that could not be resolved
+  /// to a concrete target (i.e. not on `this`).
+  final Set<Name> _dispatchedNames = new Set<Name>();
+
+  /// Instance members that are potential targets for dynamic dispatch, but
+  /// whose name has not yet been seen in a dynamic dispatch invocation.
+  ///
+  /// The map is indexed by the name of the member, and value is a list of
+  /// interleaved (host class, member) pairs.
+  final Map<Name, List<TreeNode>> _dispatchTargetCandidates =
+      <Name, List<TreeNode>>{};
+
+  /// Map from classes to the set of members that are reachable with that
+  /// class as host.
+  ///
+  /// The map is implemented as a list, indexed according to
+  /// [ClassHierarchy.getClassIndex].
+  final List<Set<Member>> _usedMembersWithHost;
+
+  /// Map from used members (regardless of host) to a summary object describing
+  /// how the member invokes other members on `this`.
+  ///
+  /// The summary object is a heterogenous list containing the [Member]s that
+  /// are invoked using `super` and the [Name]s that are dispatched on `this`.
+  ///
+  /// Names that are dispatched as a setter are preceded by the
+  /// [_setterSentinel] object, to distinguish them from getter/call names.
+  final Map<Member, List<Node>> _usedMembers = <Member, List<Node>>{};
+
+  /// The level to which a class must be retained after tree shaking.
+  ///
+  /// See [ClassRetention].
+  final List<ClassRetention> _classRetention;
+
+  /// Interleaved (host class, member) pairs that are reachable but have not yet
+  /// been analyzed for more uses.
+  final List<TreeNode> _worklist = new List<TreeNode>();
+
+  /// Classes whose interface can be used by external code to invoke user code.
+  final Set<Class> _escapedClasses = new Set<Class>();
+
+  /// AST visitor for finding static uses and dynamic dispatches in code.
+  _TreeShakerVisitor _visitor;
+
+  /// AST visitor for analyzing type annotations on external members.
+  _ExternalTypeVisitor _covariantVisitor;
+  _ExternalTypeVisitor _contravariantVisitor;
+  _ExternalTypeVisitor _bivariantVisitor;
+
+  TreeShaker(Program program, {ClassHierarchy hierarchy, CoreTypes coreTypes})
+      : this._internal(program, hierarchy ?? new ClassHierarchy(program),
+            coreTypes ?? new CoreTypes(program));
+
+  bool isMemberUsed(Member member) {
+    return _usedMembers.containsKey(member);
+  }
+
+  bool isInstantiated(Class classNode) {
+    return getClassRetention(classNode).index >= ClassRetention.Instance.index;
+  }
+
+  bool isHierarchyUsed(Class classNode) {
+    return getClassRetention(classNode).index >= ClassRetention.Hierarchy.index;
+  }
+
+  ClassRetention getClassRetention(Class classNode) {
+    int index = hierarchy.getClassIndex(classNode);
+    return _classRetention[index];
+  }
+
+  /// Applies the tree shaking results to the program.
+  ///
+  /// This removes unused classes, members, and hierarchy data.
+  void transform(Program program) {
+    new _TreeShakingTransformer(this).transform(program);
+  }
+
+  TreeShaker._internal(this.program, ClassHierarchy hierarchy, this.coreTypes)
+      : this.hierarchy = hierarchy,
+        this._usedMembersWithHost =
+            new List<Set<Member>>(hierarchy.classes.length),
+        this._classRetention = new List<ClassRetention>.filled(
+            hierarchy.classes.length, ClassRetention.None) {
+    _visitor = new _TreeShakerVisitor(this);
+    _covariantVisitor = new _ExternalTypeVisitor(this, isCovariant: true);
+    _contravariantVisitor =
+        new _ExternalTypeVisitor(this, isContravariant: true);
+    _bivariantVisitor = new _ExternalTypeVisitor(this,
+        isCovariant: true, isContravariant: true);
+    _build();
+  }
+
+  void _build() {
+    if (program.mainMethod == null) {
+      throw 'Cannot perform tree shaking on a program without a main method';
+    }
+    if (program.mainMethod.function.positionalParameters.length > 0) {
+      // The main method takes a List<String> as argument.
+      _addInstantiatedExternalSubclass(coreTypes.listClass);
+      _addInstantiatedExternalSubclass(coreTypes.stringClass);
+    }
+    _addDispatchedName(new Name('noSuchMethod'));
+    _addPervasiveUses();
+    _addUsedMember(null, program.mainMethod);
+    _iterateWorklist();
+  }
+
+  /// Registers some extremely commonly used core classes as instantiated, so
+  /// we don't have to register them for every use we find.
+  void _addPervasiveUses() {
+    _addInstantiatedExternalSubclass(coreTypes.stringClass);
+    _addInstantiatedExternalSubclass(coreTypes.intClass);
+    _addInstantiatedExternalSubclass(coreTypes.boolClass);
+    _addInstantiatedExternalSubclass(coreTypes.nullClass);
+  }
+
+  /// Registers the given name as seen in a dynamic dispatch, and discovers used
+  /// instance members accordingly.
+  void _addDispatchedName(Name name) {
+    // TODO(asgerf): make use of selector arity and getter/setter kind
+    if (_dispatchedNames.add(name)) {
+      List<TreeNode> targets = _dispatchTargetCandidates[name];
+      if (targets != null) {
+        for (int i = 0; i < targets.length; i += 2) {
+          _addUsedMember(targets[i], targets[i + 1]);
+        }
+      }
+    }
+  }
+
+  /// Registers the given method as a potential target of dynamic dispatch on
+  /// the given class.
+  void _addDispatchTarget(Class host, Member member) {
+    if (_dispatchedNames.contains(member.name)) {
+      _addUsedMember(host, member);
+    } else {
+      _dispatchTargetCandidates.putIfAbsent(member.name, _makeTreeNodeList)
+        ..add(host)
+        ..add(member);
+    }
+  }
+
+  static List<TreeNode> _makeTreeNodeList() => <TreeNode>[];
+
+  /// Registers the given class as instantiated and discovers new dispatch
+  /// target candidates accordingly.
+  void _addInstantiatedClass(Class classNode) {
+    int index = hierarchy.getClassIndex(classNode);
+    ClassRetention retention = _classRetention[index];
+    if (retention.index < ClassRetention.Instance.index) {
+      _classRetention[index] = ClassRetention.Instance;
+      _propagateClassInstanceLevel(classNode, retention);
+    }
+  }
+
+  /// Register that an external subclass of the given class may be instantiated.
+  void _addInstantiatedExternalSubclass(Class classNode) {
+    int index = hierarchy.getClassIndex(classNode);
+    ClassRetention retention = _classRetention[index];
+    if (retention.index < ClassRetention.ExternalInstance.index) {
+      _classRetention[index] = ClassRetention.ExternalInstance;
+      _propagateClassExternalInstanceLevel(classNode, retention);
+    }
+  }
+
+  void _propagateClassExternalInstanceLevel(
+      Class classNode, ClassRetention oldRetention) {
+    if (oldRetention.index >= ClassRetention.ExternalInstance.index) {
+      return;
+    }
+    _propagateClassInstanceLevel(classNode, oldRetention);
+    for (Member member in hierarchy.getInterfaceMembers(classNode)) {
+      if (member is Field) {
+        _covariantVisitor.visit(member.type);
+      } else {
+        _addCallToExternalProcedure(member);
+      }
+    }
+  }
+
+  /// Called when the retention level for [classNode] has been raised from
+  /// [oldRetention] to instance level.
+  ///
+  /// Ensures that the relevant members are put in the worklist, and super types
+  /// and raised to hierarchy level.
+  void _propagateClassInstanceLevel(
+      Class classNode, ClassRetention oldRetention) {
+    if (oldRetention.index >= ClassRetention.Instance.index) {
+      return;
+    }
+    _propagateClassHierarchyLevel(classNode, oldRetention);
+    for (Member member in hierarchy.getDispatchTargets(classNode)) {
+      _addDispatchTarget(classNode, member);
+    }
+    for (Member member
+        in hierarchy.getDispatchTargets(classNode, setters: true)) {
+      _addDispatchTarget(classNode, member);
+    }
+    // TODO(asgerf): Shake off unused instance fields.
+    // For now, just register them all inherited fields as used to ensure the
+    // effects of their initializers are taken into account.  To shake a field,
+    // we still need to preserve the side effects of the initializer.
+    for (Class node = classNode; node != null; node = node.superclass) {
+      for (Field field in node.mixin.fields) {
+        if (!field.isStatic) {
+          _addUsedMember(classNode, field);
+        }
+      }
+    }
+  }
+
+  /// Called when the retention level for [classNode] has been raised from
+  /// [oldRetention] to hierarchy level or higher.
+  ///
+  /// Ensure that all super types and type parameter bounds are also raised
+  /// to hierarchy level.
+  void _propagateClassHierarchyLevel(
+      Class classNode, ClassRetention oldRetention) {
+    if (oldRetention.index >= ClassRetention.Hierarchy.index) {
+      return;
+    }
+    _propagateClassNamespaceLevel(classNode, oldRetention);
+    var visitor = _visitor;
+    classNode.supertype?.accept(visitor);
+    classNode.mixedInType?.accept(visitor);
+    visitList(classNode.implementedTypes, visitor);
+    visitList(classNode.typeParameters, visitor);
+  }
+
+  /// Called when the retention level for [classNode] has been raised from
+  /// [oldRetention] to namespace level or higher.
+  ///
+  /// Ensures that all annotations on the class are analyzed.
+  void _propagateClassNamespaceLevel(
+      Class classNode, ClassRetention oldRetention) {
+    if (oldRetention.index >= ClassRetention.Namespace.index) {
+      return;
+    }
+    visitList(classNode.annotations, _visitor);
+  }
+
+  /// Registers the given class as being used in a type annotation.
+  void _addClassUsedInType(Class classNode) {
+    int index = hierarchy.getClassIndex(classNode);
+    ClassRetention retention = _classRetention[index];
+    if (retention.index < ClassRetention.Hierarchy.index) {
+      _classRetention[index] = ClassRetention.Hierarchy;
+      _propagateClassHierarchyLevel(classNode, retention);
+    }
+  }
+
+  /// Registers the given class or library as containing static members.
+  void _addStaticNamespace(TreeNode container) {
+    assert(container is Class || container is Library);
+    if (container is Class) {
+      int index = hierarchy.getClassIndex(container);
+      var oldRetention = _classRetention[index];
+      if (oldRetention == ClassRetention.None) {
+        _classRetention[index] = ClassRetention.Namespace;
+        _propagateClassNamespaceLevel(container, oldRetention);
+      }
+    }
+  }
+
+  /// Registers the given member as being used, in the following sense:
+  /// - Fields are used if they can be read or written or their initializer is
+  ///   evaluated.
+  /// - Constructors are used if they can be invoked, either directly or through
+  ///   the initializer list of another constructor.
+  /// - Procedures are used if they can be invoked or torn off.
+  void _addUsedMember(Class host, Member member) {
+    if (host != null) {
+      // Check if the member has been seen with this host before.
+      int index = hierarchy.getClassIndex(host);
+      Set<Member> members = _usedMembersWithHost[index] ??= new Set<Member>();
+      if (!members.add(member)) return;
+      _usedMembers.putIfAbsent(member, _makeIncompleteSummary);
+    } else {
+      // Check if the member has been seen before.
+      if (_usedMembers.containsKey(member)) return;
+      _usedMembers[member] = _makeIncompleteSummary();
+      if (member is! Constructor) {
+        _addStaticNamespace(member.parent);
+      }
+    }
+    _worklist..add(host)..add(member);
+    if (member is Procedure && member.isExternal) {
+      _addCallToExternalProcedure(member);
+    }
+  }
+
+  /// Models the impact of a call from user code to an external implementation
+  /// of [member] based on its type annotations.
+  ///
+  /// Types in covariant position are assumed to be instantiated externally,
+  /// and types in contravariant position are assumed to have their methods
+  /// invoked by the external code.
+  void _addCallToExternalProcedure(Procedure member) {
+    FunctionNode function = member.function;
+    _covariantVisitor.visit(function.returnType);
+    for (int i = 0; i < function.positionalParameters.length; ++i) {
+      _contravariantVisitor.visit(function.positionalParameters[i].type);
+    }
+    for (int i = 0; i < function.namedParameters.length; ++i) {
+      _contravariantVisitor.visit(function.namedParameters[i].type);
+    }
+  }
+
+  /// Called when external code may invoke the interface of the given class.
+  void _addEscapedClass(Class node) {
+    if (!_escapedClasses.add(node)) return;
+    for (Member member in hierarchy.getInterfaceMembers(node)) {
+      if (member is Procedure) {
+        _addDispatchedName(member.name);
+      }
+    }
+  }
+
+  /// Creates a incomplete summary object, indicating that a member has not
+  /// yet been analyzed.
+  static List<Node> _makeIncompleteSummary() => <Node>[null];
+
+  bool isIncompleteSummary(List<Node> summary) {
+    return summary.isNotEmpty && summary[0] == null;
+  }
+
+  void _iterateWorklist() {
+    while (_worklist.isNotEmpty) {
+      // Get the host and member.
+      Member member = _worklist.removeLast();
+      Class host = _worklist.removeLast();
+
+      // Analyze the method body if we have not done so before.
+      List<Node> summary = _usedMembers[member];
+      if (isIncompleteSummary(summary)) {
+        summary.clear();
+        _visitor.analyzeAndBuildSummary(member, summary);
+      }
+
+      // Apply the summary in the context of this host.
+      for (int i = 0; i < summary.length; ++i) {
+        Node summaryNode = summary[i];
+        if (summaryNode is Member) {
+          _addUsedMember(host, summaryNode);
+        } else if (summaryNode is Name) {
+          Member target = hierarchy.getDispatchTarget(host, summaryNode);
+          if (target != null) {
+            _addUsedMember(host, target);
+          }
+        } else if (identical(summaryNode, _setterSentinel)) {
+          Name name = summary[++i];
+          Member target = hierarchy.getDispatchTarget(host, name, setter: true);
+          if (target != null) {
+            _addUsedMember(host, target);
+          }
+        } else {
+          throw 'Unexpected summary node: $summaryNode';
+        }
+      }
+    }
+  }
+
+  String getDiagnosticString() {
+    return """
+dispatchNames: ${_dispatchedNames.length}
+dispatchTargetCandidates.keys: ${_dispatchTargetCandidates.length}
+usedMembersWithHost: ${_usedMembersWithHost.length}
+usedMembers: ${_usedMembers.length}
+classRetention: ${_classRetention.length}
+escapedClasses: ${_escapedClasses.length}
+""";
+  }
+}
+
+/// Sentinel that occurs in method summaries in front of each name that should
+/// be interpreted as a setter.
+final Node _setterSentinel = const InvalidType();
+
+/// Searches the AST for static references and dynamically dispatched names.
+class _TreeShakerVisitor extends RecursiveVisitor {
+  final TreeShaker shaker;
+  final CoreTypes coreTypes;
+  List<Node> summary;
+
+  _TreeShakerVisitor(TreeShaker shaker)
+      : this.shaker = shaker,
+        this.coreTypes = shaker.coreTypes;
+
+  void analyzeAndBuildSummary(Node node, List<Node> summary) {
+    this.summary = summary;
+    node.accept(this);
+  }
+
+  @override
+  visitFunctionNode(FunctionNode node) {
+    switch (node.asyncMarker) {
+      case AsyncMarker.Sync:
+        break;
+      case AsyncMarker.SyncStar:
+        shaker._addInstantiatedExternalSubclass(coreTypes.iterableClass);
+        break;
+      case AsyncMarker.Async:
+        shaker._addInstantiatedExternalSubclass(coreTypes.futureClass);
+        break;
+      case AsyncMarker.AsyncStar:
+        shaker._addInstantiatedExternalSubclass(coreTypes.streamClass);
+        break;
+      case AsyncMarker.SyncYielding:
+        break;
+    }
+    node.visitChildren(this);
+  }
+
+  void addUseFrom(Member target, Class from) {
+    shaker._addUsedMember(from, target);
+  }
+
+  void addUseFromCurrentHost(Member target) {
+    summary.add(target);
+  }
+
+  void addStaticUse(Member target) {
+    shaker._addUsedMember(null, target);
+  }
+
+  void addSelfDispatch(Name name, {bool setter: false}) {
+    if (setter) {
+      summary..add(_setterSentinel)..add(name);
+    } else {
+      summary.add(name);
+    }
+  }
+
+  @override
+  visitSuperInitializer(SuperInitializer node) {
+    addUseFromCurrentHost(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitRedirectingInitializer(RedirectingInitializer node) {
+    addUseFromCurrentHost(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitConstructorInvocation(ConstructorInvocation node) {
+    shaker._addInstantiatedClass(node.target.enclosingClass);
+    addUseFrom(node.target, node.target.enclosingClass);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitStaticInvocation(StaticInvocation node) {
+    addStaticUse(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitDirectMethodInvocation(DirectMethodInvocation node) {
+    if (node.receiver is! ThisExpression) {
+      // TODO(asgerf): Support arbitrary direct calls.
+      throw 'Direct calls are only supported on "this"';
+    }
+    addUseFromCurrentHost(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    if (node.receiver is ThisExpression) {
+      addSelfDispatch(node.name);
+    } else {
+      shaker._addDispatchedName(node.name);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  visitStaticGet(StaticGet node) {
+    addStaticUse(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitStaticSet(StaticSet node) {
+    addStaticUse(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitDirectPropertyGet(DirectPropertyGet node) {
+    if (node.receiver is! ThisExpression) {
+      // TODO(asgerf): Support arbitrary direct calls.
+      throw 'Direct calls are only supported on "this"';
+    }
+    addUseFromCurrentHost(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitDirectPropertySet(DirectPropertySet node) {
+    if (node.receiver is! ThisExpression) {
+      // TODO(asgerf): Support arbitrary direct calls.
+      throw 'Direct calls are only supported on "this"';
+    }
+    addUseFromCurrentHost(node.target);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitPropertyGet(PropertyGet node) {
+    if (node.receiver is ThisExpression) {
+      addSelfDispatch(node.name);
+    } else {
+      shaker._addDispatchedName(node.name);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  visitPropertySet(PropertySet node) {
+    if (node.receiver is ThisExpression) {
+      addSelfDispatch(node.name, setter: true);
+    } else {
+      shaker._addDispatchedName(node.name);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  visitListLiteral(ListLiteral node) {
+    shaker._addInstantiatedExternalSubclass(coreTypes.listClass);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitMapLiteral(MapLiteral node) {
+    shaker._addInstantiatedExternalSubclass(coreTypes.mapClass);
+    node.visitChildren(this);
+  }
+
+  static final Name _toStringName = new Name('toString');
+
+  @override
+  visitStringConcatenation(StringConcatenation node) {
+    shaker._addDispatchedName(_toStringName);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitInterfaceType(InterfaceType node) {
+    shaker._addClassUsedInType(node.classNode);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitDoubleLiteral(DoubleLiteral node) {
+    shaker._addInstantiatedExternalSubclass(coreTypes.doubleClass);
+  }
+
+  @override
+  visitSymbolLiteral(SymbolLiteral node) {
+    shaker._addInstantiatedExternalSubclass(coreTypes.symbolClass);
+    // Note: we do not support 'dart:mirrors' right now, so nothing else needs
+    // to be done for symbols.
+  }
+
+  @override
+  visitTypeLiteral(TypeLiteral node) {
+    shaker._addInstantiatedExternalSubclass(coreTypes.typeClass);
+    node.visitChildren(this);
+  }
+}
+
+/// The degree to which a class is needed in a program.
+///
+/// Each level implies those before it.
+enum ClassRetention {
+  /// The class can be removed.
+  None,
+
+  /// The class contains used static members but is otherwise unused.
+  Namespace,
+
+  /// The class is used in a type or has an instantiated subtype, or for some
+  /// other reason must have its hierarchy information preserved.
+  Hierarchy,
+
+  /// The class is instantiated.
+  Instance,
+
+  /// The class has an instantiated external subclass.
+  ExternalInstance,
+}
+
+/// Removes classes and members that are not needed.
+///
+/// There must not be any dangling references in the program afterwards.
+class _TreeShakingTransformer extends Transformer {
+  final TreeShaker shaker;
+
+  _TreeShakingTransformer(this.shaker);
+
+  void transform(Program program) {
+    for (var library in program.libraries) {
+      if (library.importUri.scheme == 'dart') {
+        // As long as patching happens in the backend, we cannot shake off
+        // anything in the core libraries.
+        continue;
+      }
+      library.transformChildren(this);
+      // Note: we can't shake off empty libraries yet since we don't check if
+      // there are private names that use the library.
+    }
+  }
+
+  Class visitClass(Class node) {
+    switch (shaker.getClassRetention(node)) {
+      case ClassRetention.None:
+        return null; // Remove the class.
+
+      case ClassRetention.Namespace:
+        // The class is only a namespace for static members.  Remove its
+        // hierarchy information.   This is mandatory, since these references
+        // might otherwise become dangling.
+        node.supertype = shaker.coreTypes.objectClass.asRawSupertype;
+        node.implementedTypes.clear();
+        node.typeParameters.clear();
+        // Mixin applications cannot have static members.
+        assert(node.mixedInType == null);
+        // Unused members will be removed below.
+        break;
+
+      case ClassRetention.Hierarchy:
+      case ClassRetention.Instance:
+      case ClassRetention.ExternalInstance:
+        break;
+    }
+    node.transformChildren(this);
+    if (node.constructors.isEmpty && node.procedures.isEmpty) {
+      // The VM does not like classes without any members, so ensure there is
+      // always a constructor left.
+      node.addMember(new Constructor(new FunctionNode(new EmptyStatement())));
+    }
+    return node;
+  }
+
+  Member defaultMember(Member node) {
+    if (!shaker.isMemberUsed(node)) {
+      return null; // Remove unused member.
+    }
+    return node;
+  }
+
+  TreeNode defaultTreeNode(TreeNode node) {
+    return node; // Do not traverse into other nodes.
+  }
+}
+
+class _ExternalTypeVisitor extends DartTypeVisitor {
+  final TreeShaker shaker;
+  final bool isCovariant;
+  final bool isContravariant;
+  ClassHierarchy get hierarchy => shaker.hierarchy;
+
+  _ExternalTypeVisitor(this.shaker,
+      {this.isCovariant: false, this.isContravariant: false});
+
+  void visit(DartType type) => type?.accept(this);
+
+  /// Analyze [type] with the opposite variance.
+  void visitContravariant(DartType type) {
+    if (isCovariant && isContravariant) {
+      type?.accept(this);
+    } else if (isContravariant) {
+      type?.accept(shaker._covariantVisitor);
+    } else {
+      type?.accept(shaker._contravariantVisitor);
+    }
+  }
+
+  visitCovariant(DartType type) => type?.accept(this);
+
+  visitBivariant(DartType type) => shaker._bivariantVisitor.visit(type);
+
+  visitInvalidType(InvalidType node) {}
+
+  visitDynamicType(DynamicType node) {
+    // TODO(asgerf): Find a suitable model for untyped externals, e.g. track
+    // them to the first type boundary.
+  }
+
+  visitVoidType(VoidType node) {}
+
+  visitInterfaceType(InterfaceType node) {
+    if (isCovariant) {
+      shaker._addInstantiatedExternalSubclass(node.classNode);
+    }
+    if (isContravariant) {
+      shaker._addEscapedClass(node.classNode);
+    }
+    for (int i = 0; i < node.typeArguments.length; ++i) {
+      DartType typeArgument = node.typeArguments[i];
+      // In practice we don't get much out of analyzing variance here, so
+      // just use a whitelist of classes that can be seen as covariant
+      // for external purposes.
+      // TODO(asgerf): Variance analysis might pay off for other external APIs.
+      if (isWhitelistedCovariant(node.classNode)) {
+        visitCovariant(typeArgument);
+      } else {
+        visitBivariant(typeArgument);
+      }
+    }
+  }
+
+  visitFunctionType(FunctionType node) {
+    visit(node.returnType);
+    for (int i = 0; i < node.positionalParameters.length; ++i) {
+      visitContravariant(node.positionalParameters[i]);
+    }
+    for (int i = 0; i < node.namedParameters.length; ++i) {
+      visitContravariant(node.namedParameters[i].type);
+    }
+  }
+
+  visitTypeParameterType(TypeParameterType node) {}
+
+  /// Just treat a couple of whitelisted classes as having covariant type
+  /// parameters.
+  bool isWhitelistedCovariant(Class classNode) {
+    if (classNode.typeParameters.isEmpty) return false;
+    CoreTypes coreTypes = shaker.coreTypes;
+    return classNode == coreTypes.iteratorClass ||
+        classNode == coreTypes.iterableClass ||
+        classNode == coreTypes.futureClass ||
+        classNode == coreTypes.streamClass ||
+        classNode == coreTypes.listClass ||
+        classNode == coreTypes.mapClass;
+  }
+}
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
new file mode 100644
index 0000000..19508b1
--- /dev/null
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -0,0 +1,643 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_algebra;
+
+import 'ast.dart';
+
+/// Returns a type where all occurrences of the given type parameters have been
+/// replaced with the corresponding types.
+///
+/// This will copy only the subterms of [type] that contain substituted
+/// variables; all other [DartType] objects will be reused.
+///
+/// In particular, if no variables were substituted, this is guaranteed to
+/// return the [type] instance (not a copy), so the caller may use [identical]
+/// to efficiently check if a distinct type was created.
+DartType substitute(DartType type, Map<TypeParameter, DartType> substitution) {
+  if (substitution.isEmpty) return type;
+  return Substitution.fromMap(substitution).substituteType(type);
+}
+
+/// Returns a mapping from the type parameters declared on the class of [type]
+/// to the actual type arguments provided in [type].
+///
+/// This can be passed as argument to [substitute].
+Map<TypeParameter, DartType> getSubstitutionMap(Supertype type) {
+  return type.typeArguments.isEmpty
+      ? const <TypeParameter, DartType>{}
+      : new Map<TypeParameter, DartType>.fromIterables(
+          type.classNode.typeParameters, type.typeArguments);
+}
+
+/// Like [substitute], except when a type in the [substitution] map references
+/// another substituted type variable, the mapping for that type is recursively
+/// inserted.
+///
+/// For example `Set<G>` substituted with `{T -> String, G -> List<T>}` results
+/// in `Set<List<String>>`.
+///
+/// Returns `null` if the substitution map contains a cycle reachable from a
+/// type variable in [type] (the resulting type would be infinite).
+///
+/// The [substitution] map will be mutated so that the right-hand sides may
+/// be remapped to the deeply substituted type, but only for the keys that are
+/// reachable from [type].
+///
+/// As with [substitute], this is guaranteed to return the same instance if no
+/// substitution was performed.
+DartType substituteDeep(
+    DartType type, Map<TypeParameter, DartType> substitution) {
+  if (substitution.isEmpty) return type;
+  var substitutor = new _DeepTypeSubstitutor(substitution);
+  var result = substitutor.visit(type);
+  return substitutor.isInfinite ? null : result;
+}
+
+/// Returns true if [type] contains a reference to any of the given [variables].
+///
+/// It is an error to call this with a [type] that contains a [FunctionType]
+/// that declares one of the parameters in [variables].
+bool containsTypeVariable(DartType type, Set<TypeParameter> variables) {
+  if (variables.isEmpty) return false;
+  return new _OccurrenceVisitor(variables).visit(type);
+}
+
+/// Given a set of type variables, finds a substitution of those variables such
+/// that the two given types becomes equal, or returns `null` if no such
+/// substitution exists.
+///
+/// For example, unifying `List<T>` with `List<String>`, where `T` is a
+/// quantified variable, yields the substitution `T = String`.
+///
+/// If successful, this equation holds:
+///
+///     substitute(type1, substitution) == substitute(type2, substitution)
+///
+/// The unification can fail for two reasons:
+/// - incompatible types, e.g. `List<T>` cannot be unified with `Set<T>`.
+/// - infinite types: e.g. `T` cannot be unified with `List<T>` because it
+///   would create the infinite type `List<List<List<...>>>`.
+Map<TypeParameter, DartType> unifyTypes(
+    DartType type1, DartType type2, Set<TypeParameter> quantifiedVariables) {
+  var unifier = new _TypeUnification(type1, type2, quantifiedVariables);
+  return unifier.success ? unifier.substitution : null;
+}
+
+/// Generates a fresh copy of the given type parameters, with their bounds
+/// substituted to reference the new parameters.
+///
+/// The returned object contains the fresh type parameter list as well as a
+/// mapping to be used for replacing other types to use the new type parameters.
+FreshTypeParameters getFreshTypeParameters(List<TypeParameter> typeParameters) {
+  var freshParameters = new List<TypeParameter>.generate(
+      typeParameters.length, (i) => new TypeParameter(typeParameters[i].name),
+      growable: true);
+  var map = <TypeParameter, DartType>{};
+  for (int i = 0; i < typeParameters.length; ++i) {
+    map[typeParameters[i]] = new TypeParameterType(freshParameters[i]);
+    freshParameters[i].bound = substitute(typeParameters[i].bound, map);
+  }
+  return new FreshTypeParameters(freshParameters, Substitution.fromMap(map));
+}
+
+class FreshTypeParameters {
+  final List<TypeParameter> freshTypeParameters;
+  final Substitution substitution;
+
+  FreshTypeParameters(this.freshTypeParameters, this.substitution);
+
+  DartType substitute(DartType type) => substitution.substituteType(type);
+
+  Supertype substituteSuper(Supertype type) {
+    return substitution.substituteSupertype(type);
+  }
+}
+
+// ------------------------------------------------------------------------
+//                              IMPLEMENTATION
+// ------------------------------------------------------------------------
+
+abstract class Substitution {
+  const Substitution();
+
+  static const Substitution empty = _NullSubstitution.instance;
+
+  /// Substitutes each parameter to the type it maps to in [map].
+  static Substitution fromMap(Map<TypeParameter, DartType> map) {
+    if (map.isEmpty) return _NullSubstitution.instance;
+    return new _MapSubstitution(map, map);
+  }
+
+  /// Substitutes all occurrences of the given type parameters with the
+  /// corresponding upper or lower bound, depending on the variance of the
+  /// context where it occurs.
+  ///
+  /// For example the type `(T) => T` with the bounds `bottom <: T <: num`
+  /// becomes `(bottom) => num` (in this example, `num` is the upper bound,
+  /// and `bottom` is the lower bound).
+  ///
+  /// This is a way to obtain an upper bound for a type while eliminating all
+  /// references to certain type variables.
+  static Substitution fromUpperAndLowerBounds(
+      Map<TypeParameter, DartType> upper, Map<TypeParameter, DartType> lower) {
+    if (upper.isEmpty && lower.isEmpty) return _NullSubstitution.instance;
+    return new _MapSubstitution(upper, lower);
+  }
+
+  /// Substitutes the type parameters on the class of [supertype] with the
+  /// type arguments provided in [supertype].
+  static Substitution fromSupertype(Supertype supertype) {
+    if (supertype.typeArguments.isEmpty) return _NullSubstitution.instance;
+    return fromMap(new Map<TypeParameter, DartType>.fromIterables(
+        supertype.classNode.typeParameters, supertype.typeArguments));
+  }
+
+  /// Substitutes the type parameters on the class of [type] with the
+  /// type arguments provided in [type].
+  static Substitution fromInterfaceType(InterfaceType type) {
+    if (type.typeArguments.isEmpty) return _NullSubstitution.instance;
+    return fromMap(new Map<TypeParameter, DartType>.fromIterables(
+        type.classNode.typeParameters, type.typeArguments));
+  }
+
+  /// Substitutes the Nth parameter in [parameters] with the Nth type in
+  /// [types].
+  static Substitution fromPairs(
+      List<TypeParameter> parameters, List<DartType> types) {
+    // TODO(asgerf): Investigate if it is more efficient to implement
+    // substitution based on parallel pairwise lists instead of Maps.
+    assert(parameters.length == types.length);
+    if (parameters.isEmpty) return _NullSubstitution.instance;
+    return fromMap(
+        new Map<TypeParameter, DartType>.fromIterables(parameters, types));
+  }
+
+  /// Substitutes the type parameters on the class with bottom or dynamic,
+  /// depending on the covariance of its use.
+  static Substitution bottomForClass(Class class_) {
+    if (class_.typeParameters.isEmpty) return _NullSubstitution.instance;
+    return new _ClassBottomSubstitution(class_);
+  }
+
+  /// Substitutes both variables from [first] and [second], favoring those from
+  /// [first] if they overlap.
+  ///
+  /// Neither substitution is applied to the results of the other, so this does
+  /// *not* correspond to a sequence of two subsitutions. For example, combining
+  /// `{T -> List<G>}` with `{G -> String}` does not correspond to
+  /// `{T -> List<String>}` because the result from substituting `T` is not
+  /// searched for occurences of `G`.
+  static Substitution combine(Substitution first, Substitution second) {
+    if (first == _NullSubstitution.instance) return second;
+    if (second == _NullSubstitution.instance) return first;
+    return new _CombinedSubstitution(first, second);
+  }
+
+  DartType getSubstitute(TypeParameter parameter, bool upperBound);
+
+  DartType substituteType(DartType node, {bool contravariant: false}) {
+    return new _TopSubstitutor(this, contravariant).visit(node);
+  }
+
+  Supertype substituteSupertype(Supertype node) {
+    return new _TopSubstitutor(this, false).visitSupertype(node);
+  }
+}
+
+class _NullSubstitution extends Substitution {
+  static const _NullSubstitution instance = const _NullSubstitution();
+
+  const _NullSubstitution();
+
+  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+    return new TypeParameterType(parameter);
+  }
+
+  @override
+  DartType substituteType(DartType node, {bool contravariant: false}) => node;
+
+  @override
+  Supertype substituteSupertype(Supertype node) => node;
+}
+
+class _MapSubstitution extends Substitution {
+  final Map<TypeParameter, DartType> upper;
+  final Map<TypeParameter, DartType> lower;
+
+  _MapSubstitution(this.upper, this.lower);
+
+  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+    return upperBound ? upper[parameter] : lower[parameter];
+  }
+}
+
+class _TopSubstitutor extends _TypeSubstitutor {
+  final Substitution substitution;
+
+  _TopSubstitutor(this.substitution, bool contravariant) : super(null) {
+    if (contravariant) {
+      invertVariance();
+    }
+  }
+
+  DartType lookup(TypeParameter parameter, bool upperBound) {
+    return substitution.getSubstitute(parameter, upperBound);
+  }
+
+  TypeParameter freshTypeParameter(TypeParameter node) {
+    throw 'Create a fresh environment first';
+  }
+}
+
+class _ClassBottomSubstitution extends Substitution {
+  final Class class_;
+
+  _ClassBottomSubstitution(this.class_);
+
+  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+    if (parameter.parent == class_) {
+      return upperBound ? const BottomType() : const DynamicType();
+    }
+    return null;
+  }
+}
+
+class _CombinedSubstitution extends Substitution {
+  final Substitution first, second;
+
+  _CombinedSubstitution(this.first, this.second);
+
+  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+    return first.getSubstitute(parameter, upperBound) ??
+        second.getSubstitute(parameter, upperBound);
+  }
+}
+
+class _InnerTypeSubstitutor extends _TypeSubstitutor {
+  final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
+
+  _InnerTypeSubstitutor(_TypeSubstitutor outer) : super(outer);
+
+  DartType lookup(TypeParameter parameter, bool upperBound) {
+    return substitution[parameter];
+  }
+
+  TypeParameter freshTypeParameter(TypeParameter node) {
+    var fresh = new TypeParameter(node.name);
+    substitution[node] = new TypeParameterType(fresh);
+    fresh.bound = visit(node.bound);
+    return fresh;
+  }
+}
+
+abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> {
+  final _TypeSubstitutor outer;
+  bool covariantContext = true;
+
+  _TypeSubstitutor(this.outer) {
+    covariantContext = outer == null ? true : outer.covariantContext;
+  }
+
+  DartType lookup(TypeParameter parameter, bool upperBound);
+
+  /// The number of times a variable from this environment has been used in
+  /// a substitution.
+  ///
+  /// There is a strict requirement that we must return the same instance for
+  /// types that were not altered by the substitution.  This counter lets us
+  /// check quickly if anything happened in a substitution.
+  int useCounter = 0;
+
+  _InnerTypeSubstitutor newInnerEnvironment() {
+    return new _InnerTypeSubstitutor(this);
+  }
+
+  void invertVariance() {
+    covariantContext = !covariantContext;
+  }
+
+  Supertype visitSupertype(Supertype node) {
+    if (node.typeArguments.isEmpty) return node;
+    int before = useCounter;
+    var typeArguments = node.typeArguments.map(visit).toList();
+    if (useCounter == before) return node;
+    return new Supertype(node.classNode, typeArguments);
+  }
+
+  NamedType visitNamedType(NamedType node) {
+    int before = useCounter;
+    var type = visit(node.type);
+    if (useCounter == before) return node;
+    return new NamedType(node.name, type);
+  }
+
+  DartType visit(DartType node) => node.accept(this);
+
+  DartType visitInvalidType(InvalidType node) => node;
+  DartType visitDynamicType(DynamicType node) => node;
+  DartType visitVoidType(VoidType node) => node;
+  DartType visitBottomType(BottomType node) => node;
+
+  DartType visitInterfaceType(InterfaceType node) {
+    if (node.typeArguments.isEmpty) return node;
+    int before = useCounter;
+    var typeArguments = node.typeArguments.map(visit).toList();
+    if (useCounter == before) return node;
+    return new InterfaceType(node.classNode, typeArguments);
+  }
+
+  List<TypeParameter> freshTypeParameters(List<TypeParameter> parameters) {
+    if (parameters.isEmpty) return const <TypeParameter>[];
+    return parameters.map(freshTypeParameter).toList();
+  }
+
+  TypeParameter freshTypeParameter(TypeParameter node);
+
+  DartType visitFunctionType(FunctionType node) {
+    // This is a bit tricky because we have to generate fresh type parameters
+    // in order to change the bounds.  At the same time, if the function type
+    // was unaltered, we have to return the [node] object (not a copy!).
+    // Substituting a type for a fresh type variable should not be confused with
+    // a "real" substitution.
+    //
+    // Create an inner environment to generate fresh type parameters.  The use
+    // counter on the inner environment tells if the fresh type parameters have
+    // any uses, but does not tell if the resulting function type is distinct.
+    // Our own use counter will get incremented if something from our
+    // environment has been used inside the function.
+    var inner = node.typeParameters.isEmpty ? this : newInnerEnvironment();
+    int before = this.useCounter;
+    // Invert the variance when translating parameters.
+    inner.invertVariance();
+    var typeParameters = inner.freshTypeParameters(node.typeParameters);
+    var positionalParameters = node.positionalParameters.isEmpty
+        ? const <DartType>[]
+        : node.positionalParameters.map(inner.visit).toList();
+    var namedParameters = node.namedParameters.isEmpty
+        ? const <NamedType>[]
+        : node.namedParameters.map(inner.visitNamedType).toList();
+    inner.invertVariance();
+    var returnType = inner.visit(node.returnType);
+    if (this.useCounter == before) return node;
+    return new FunctionType(positionalParameters, returnType,
+        namedParameters: namedParameters,
+        typeParameters: typeParameters,
+        requiredParameterCount: node.requiredParameterCount);
+  }
+
+  void bumpCountersUntil(_TypeSubstitutor target) {
+    var node = this;
+    while (node != target) {
+      ++node.useCounter;
+      node = node.outer;
+    }
+    ++target.useCounter;
+  }
+
+  DartType getSubstitute(TypeParameter variable) {
+    var environment = this;
+    while (environment != null) {
+      var replacement = environment.lookup(variable, covariantContext);
+      if (replacement != null) {
+        bumpCountersUntil(environment);
+        return replacement;
+      }
+      environment = environment.outer;
+    }
+    return null;
+  }
+
+  DartType visitTypeParameterType(TypeParameterType node) {
+    return getSubstitute(node.parameter) ?? node;
+  }
+}
+
+class _DeepTypeSubstitutor extends _InnerTypeSubstitutor {
+  int depth = 0;
+  bool isInfinite = false;
+
+  _DeepTypeSubstitutor(Map<TypeParameter, DartType> substitution,
+      [_DeepTypeSubstitutor outer])
+      : super(outer) {
+    this.substitution.addAll(substitution);
+  }
+
+  @override
+  _DeepTypeSubstitutor newInnerEnvironment() {
+    return new _DeepTypeSubstitutor(<TypeParameter, DartType>{}, this);
+  }
+
+  @override
+  DartType visitTypeParameterType(TypeParameterType node) {
+    DartType replacement = getSubstitute(node.parameter);
+    if (replacement == null) return node;
+    if (isInfinite) return replacement;
+    ++depth;
+    if (depth > substitution.length) {
+      isInfinite = true;
+      --depth;
+      return replacement;
+    } else {
+      replacement = visit(replacement);
+      // Update type to the fully fleshed-out type.
+      substitution[node.parameter] = replacement;
+      --depth;
+      return replacement;
+    }
+  }
+}
+
+class _TypeUnification {
+  // Acyclic invariant: There are no cycles in the map, that is, all types can
+  //   be resolved to finite types by substituting all contained type variables.
+  //
+  // The acyclic invariant holds everywhere except during cycle detection.
+  //
+  // It is not checked that the substitution satisfies the bound on the type
+  // parameter.
+  final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
+
+  /// Variables that may be assigned freely in order to obtain unification.
+  ///
+  /// These are sometimes referred to as existentially quantified variables.
+  final Set<TypeParameter> quantifiedVariables;
+
+  /// Variables that are bound by a function type inside one of the types.
+  /// These may not occur in a substitution, because these variables are not in
+  /// scope at the existentially quantified variables.
+  ///
+  /// For example, suppose we are trying to satisfy the equation:
+  ///
+  ///     ∃S. <E>(E, S) => E  =  <E>(E, E) => E
+  ///
+  /// That is, we must choose `S` such that the generic function type
+  /// `<E>(E, S) => E` becomes `<E>(E, E) => E`.  Choosing `S = E` is not a
+  /// valid solution, because `E` is not in scope where `S` is quantified.
+  /// The two function types cannot be unified.
+  final Set<TypeParameter> _universallyQuantifiedVariables =
+      new Set<TypeParameter>();
+
+  bool success = true;
+
+  _TypeUnification(DartType type1, DartType type2, this.quantifiedVariables) {
+    _unify(type1, type2);
+    if (success && substitution.length >= 2) {
+      for (var key in substitution.keys) {
+        substitution[key] = substituteDeep(substitution[key], substitution);
+      }
+    }
+  }
+
+  DartType _substituteHead(TypeParameterType type) {
+    for (int i = 0; i <= substitution.length; ++i) {
+      DartType nextType = substitution[type.parameter];
+      if (nextType == null) return type;
+      if (nextType is TypeParameterType) {
+        type = nextType;
+      } else {
+        return nextType;
+      }
+    }
+    // The cycle should have been found by _trySubstitution when the cycle
+    // was created.
+    throw 'Unexpected cycle found during unification';
+  }
+
+  bool _unify(DartType type1, DartType type2) {
+    if (!success) return false;
+    type1 = type1 is TypeParameterType ? _substituteHead(type1) : type1;
+    type2 = type2 is TypeParameterType ? _substituteHead(type2) : type2;
+    if (type1 is DynamicType && type2 is DynamicType) return true;
+    if (type1 is VoidType && type2 is VoidType) return true;
+    if (type1 is InvalidType && type2 is InvalidType) return true;
+    if (type1 is BottomType && type2 is BottomType) return true;
+    if (type1 is InterfaceType && type2 is InterfaceType) {
+      if (type1.classNode != type2.classNode) return _fail();
+      assert(type1.typeArguments.length == type2.typeArguments.length);
+      for (int i = 0; i < type1.typeArguments.length; ++i) {
+        if (!_unify(type1.typeArguments[i], type2.typeArguments[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+    if (type1 is FunctionType && type2 is FunctionType) {
+      if (type1.typeParameters.length != type2.typeParameters.length ||
+          type1.positionalParameters.length !=
+              type2.positionalParameters.length ||
+          type1.namedParameters.length != type2.namedParameters.length ||
+          type1.requiredParameterCount != type2.requiredParameterCount) {
+        return _fail();
+      }
+      // When unifying two generic functions, transform the equation like this:
+      //
+      //    ∃S. <E>(fn1) = <T>(fn2)
+      //      ==>
+      //    ∃S. ∀G. fn1[G/E] = fn2[G/T]
+      //
+      // That is, assume some fixed identical choice of type parameters for both
+      // functions and try to unify the instantiated function types.
+      assert(!type1.typeParameters.any(quantifiedVariables.contains));
+      assert(!type2.typeParameters.any(quantifiedVariables.contains));
+      var leftInstance = <TypeParameter, DartType>{};
+      var rightInstance = <TypeParameter, DartType>{};
+      for (int i = 0; i < type1.typeParameters.length; ++i) {
+        var instantiator = new TypeParameter(type1.typeParameters[i].name);
+        var instantiatorType = new TypeParameterType(instantiator);
+        leftInstance[type1.typeParameters[i]] = instantiatorType;
+        rightInstance[type2.typeParameters[i]] = instantiatorType;
+        _universallyQuantifiedVariables.add(instantiator);
+      }
+      for (int i = 0; i < type1.typeParameters.length; ++i) {
+        var left = substitute(type1.typeParameters[i].bound, leftInstance);
+        var right = substitute(type2.typeParameters[i].bound, rightInstance);
+        if (!_unify(left, right)) return false;
+      }
+      for (int i = 0; i < type1.positionalParameters.length; ++i) {
+        var left = substitute(type1.positionalParameters[i], leftInstance);
+        var right = substitute(type2.positionalParameters[i], rightInstance);
+        if (!_unify(left, right)) return false;
+      }
+      for (int i = 0; i < type1.namedParameters.length; ++i) {
+        if (type1.namedParameters[i].name != type2.namedParameters[i].name) {
+          return false;
+        }
+        var left = substitute(type1.namedParameters[i].type, leftInstance);
+        var right = substitute(type2.namedParameters[i].type, rightInstance);
+        if (!_unify(left, right)) return false;
+      }
+      var leftReturn = substitute(type1.returnType, leftInstance);
+      var rightReturn = substitute(type2.returnType, rightInstance);
+      if (!_unify(leftReturn, rightReturn)) return false;
+      return true;
+    }
+    if (type1 is TypeParameterType &&
+        type2 is TypeParameterType &&
+        type1.parameter == type2.parameter) {
+      return true;
+    }
+    if (type1 is TypeParameterType &&
+        quantifiedVariables.contains(type1.parameter)) {
+      return _trySubstitution(type1.parameter, type2);
+    }
+    if (type2 is TypeParameterType &&
+        quantifiedVariables.contains(type2.parameter)) {
+      return _trySubstitution(type2.parameter, type1);
+    }
+    return _fail();
+  }
+
+  bool _trySubstitution(TypeParameter variable, DartType type) {
+    if (containsTypeVariable(type, _universallyQuantifiedVariables)) {
+      return _fail();
+    }
+    // Set the plain substitution first and then generate the deep
+    // substitution to detect cycles.
+    substitution[variable] = type;
+    DartType deepSubstitute = substituteDeep(type, substitution);
+    if (deepSubstitute == null) return _fail();
+    substitution[variable] = deepSubstitute;
+    return true;
+  }
+
+  bool _fail() {
+    return success = false;
+  }
+}
+
+class _OccurrenceVisitor extends DartTypeVisitor<bool> {
+  final Set<TypeParameter> variables;
+
+  _OccurrenceVisitor(this.variables);
+
+  bool visit(DartType node) => node.accept(this);
+
+  bool visitNamedType(NamedType node) {
+    return visit(node.type);
+  }
+
+  bool visitInvalidType(InvalidType node) => false;
+  bool visitDynamicType(DynamicType node) => false;
+  bool visitVoidType(VoidType node) => false;
+
+  bool visitInterfaceType(InterfaceType node) {
+    return node.typeArguments.any(visit);
+  }
+
+  bool visitFunctionType(FunctionType node) {
+    return node.typeParameters.any(handleTypeParameter) ||
+        node.positionalParameters.any(visit) ||
+        node.namedParameters.any(visitNamedType) ||
+        visit(node.returnType);
+  }
+
+  bool visitTypeParameterType(TypeParameterType node) {
+    return variables == null || variables.contains(node.parameter);
+  }
+
+  bool handleTypeParameter(TypeParameter node) {
+    assert(!variables.contains(node));
+    return node.bound.accept(this);
+  }
+}
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
new file mode 100644
index 0000000..ab0351e
--- /dev/null
+++ b/pkg/kernel/lib/type_checker.dart
@@ -0,0 +1,863 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_checker;
+
+import 'ast.dart';
+import 'class_hierarchy.dart';
+import 'core_types.dart';
+import 'type_algebra.dart';
+import 'type_environment.dart';
+
+/// Performs strong-mode type checking on the kernel IR.
+///
+/// A concrete subclass of [TypeChecker] must implement [checkAssignable] and
+/// [fail] in order to deal with subtyping requirements and error handling.
+abstract class TypeChecker {
+  final CoreTypes coreTypes;
+  final ClassHierarchy hierarchy;
+  TypeEnvironment environment;
+
+  TypeChecker(this.coreTypes, this.hierarchy) {
+    environment = new TypeEnvironment(coreTypes, hierarchy);
+  }
+
+  void checkProgram(Program program) {
+    for (var library in program.libraries) {
+      if (library.importUri.scheme == 'dart') continue;
+      for (var class_ in library.classes) {
+        hierarchy.forEachOverridePair(class_,
+            (Member ownMember, Member superMember, bool isSetter) {
+          checkOverride(class_, ownMember, superMember, isSetter);
+        });
+      }
+    }
+    var visitor = new TypeCheckingVisitor(this, environment);
+    for (var library in program.libraries) {
+      if (library.importUri.scheme == 'dart') continue;
+      for (var class_ in library.classes) {
+        environment.thisType = class_.thisType;
+        for (var field in class_.fields) {
+          visitor.visitField(field);
+        }
+        for (var constructor in class_.constructors) {
+          visitor.visitConstructor(constructor);
+        }
+        for (var procedure in class_.procedures) {
+          visitor.visitProcedure(procedure);
+        }
+      }
+      environment.thisType = null;
+      for (var procedure in library.procedures) {
+        visitor.visitProcedure(procedure);
+      }
+      for (var field in library.fields) {
+        visitor.visitField(field);
+      }
+    }
+  }
+
+  DartType getterType(Class host, Member member) {
+    var hostType = hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
+    var substitution = Substitution.fromSupertype(hostType);
+    return substitution.substituteType(member.getterType);
+  }
+
+  DartType setterType(Class host, Member member) {
+    var hostType = hierarchy.getClassAsInstanceOf(host, member.enclosingClass);
+    var substitution = Substitution.fromSupertype(hostType);
+    return substitution.substituteType(member.setterType, contravariant: true);
+  }
+
+  void checkOverride(
+      Class host, Member ownMember, Member superMember, bool isSetter) {
+    if (isSetter) {
+      checkAssignable(ownMember, setterType(host, superMember),
+          setterType(host, ownMember));
+    } else {
+      checkAssignable(ownMember, getterType(host, ownMember),
+          getterType(host, superMember));
+    }
+  }
+
+  /// Check that [from] is a subtype of [to].
+  ///
+  /// [where] is an AST node indicating roughly where the check is required.
+  void checkAssignable(TreeNode where, DartType from, DartType to);
+
+  /// Indicates that type checking failed.
+  void fail(TreeNode where, String message);
+}
+
+class TypeCheckingVisitor
+    implements
+        ExpressionVisitor<DartType>,
+        StatementVisitor<Null>,
+        MemberVisitor<Null>,
+        InitializerVisitor<Null> {
+  final TypeChecker checker;
+  final TypeEnvironment environment;
+
+  CoreTypes get coreTypes => environment.coreTypes;
+  ClassHierarchy get hierarchy => environment.hierarchy;
+  Class get currentClass => environment.thisType.classNode;
+
+  TypeCheckingVisitor(this.checker, this.environment);
+
+  void checkAssignable(TreeNode where, DartType from, DartType to) {
+    checker.checkAssignable(where, from, to);
+  }
+
+  void checkAssignableExpression(Expression from, DartType to) {
+    checker.checkAssignable(from, visitExpression(from), to);
+  }
+
+  void fail(TreeNode node, String message) {
+    checker.fail(node, message);
+  }
+
+  DartType visitExpression(Expression node) => node.accept(this);
+
+  void visitStatement(Statement node) {
+    node.accept(this);
+  }
+
+  void visitInitializer(Initializer node) {
+    node.accept(this);
+  }
+
+  defaultMember(Member node) => throw 'Unused';
+
+  DartType defaultBasicLiteral(BasicLiteral node) {
+    return defaultExpression(node);
+  }
+
+  DartType defaultExpression(Expression node) {
+    throw 'Unexpected expression ${node.runtimeType}';
+  }
+
+  defaultStatement(Statement node) {
+    throw 'Unexpected statement ${node.runtimeType}';
+  }
+
+  defaultInitializer(Initializer node) {
+    throw 'Unexpected initializer ${node.runtimeType}';
+  }
+
+  visitField(Field node) {
+    if (node.initializer != null) {
+      checkAssignableExpression(node.initializer, node.type);
+    }
+  }
+
+  visitConstructor(Constructor node) {
+    environment.returnType = null;
+    environment.yieldType = null;
+    node.initializers.forEach(visitInitializer);
+    handleFunctionNode(node.function);
+  }
+
+  visitProcedure(Procedure node) {
+    environment.returnType = _getInternalReturnType(node.function);
+    environment.yieldType = _getYieldType(node.function);
+    handleFunctionNode(node.function);
+  }
+
+  void handleFunctionNode(FunctionNode node) {
+    var oldAsyncMarker = environment.currentAsyncMarker;
+    environment.currentAsyncMarker = node.asyncMarker;
+    node.positionalParameters
+        .skip(node.requiredParameterCount)
+        .forEach(handleOptionalParameter);
+    node.namedParameters.forEach(handleOptionalParameter);
+    if (node.body != null) {
+      visitStatement(node.body);
+    }
+    environment.currentAsyncMarker = oldAsyncMarker;
+  }
+
+  void handleNestedFunctionNode(FunctionNode node) {
+    var oldReturn = environment.returnType;
+    var oldYield = environment.yieldType;
+    environment.returnType = _getInternalReturnType(node);
+    environment.yieldType = _getYieldType(node);
+    handleFunctionNode(node);
+    environment.returnType = oldReturn;
+    environment.yieldType = oldYield;
+  }
+
+  void handleOptionalParameter(VariableDeclaration parameter) {
+    if (parameter.initializer != null) {
+      checkAssignableExpression(parameter.initializer, parameter.type);
+    }
+  }
+
+  Substitution getReceiverType(
+      TreeNode access, Expression receiver, Member member) {
+    var type = visitExpression(receiver);
+    Class superclass = member.enclosingClass;
+    if (superclass.supertype == null) {
+      return Substitution.empty; // Members on Object are always accessible.
+    }
+    while (type is TypeParameterType) {
+      type = (type as TypeParameterType).parameter.bound;
+    }
+    if (type is BottomType) {
+      // The bottom type is a subtype of all types, so it should be allowed.
+      return Substitution.bottomForClass(superclass);
+    }
+    if (type is InterfaceType) {
+      // The receiver type should implement the interface declaring the member.
+      var upcastType = hierarchy.getTypeAsInstanceOf(type, superclass);
+      if (upcastType != null) {
+        return Substitution.fromInterfaceType(upcastType);
+      }
+    }
+    if (type is FunctionType && superclass == coreTypes.functionClass) {
+      assert(type.typeParameters.isEmpty);
+      return Substitution.empty;
+    }
+    // Note that we do not allow 'dynamic' here.  Dynamic calls should not
+    // have a declared interface target.
+    fail(access, '$member is not accessible on a receiver of type $type');
+    return Substitution.bottomForClass(superclass); // Continue type checking.
+  }
+
+  Substitution getSuperReceiverType(Member member) {
+    return Substitution.fromSupertype(
+        hierarchy.getClassAsInstanceOf(currentClass, member.enclosingClass));
+  }
+
+  DartType handleCall(Arguments arguments, FunctionNode function,
+      {Substitution receiver: Substitution.empty,
+      List<TypeParameter> typeParameters}) {
+    typeParameters ??= function.typeParameters;
+    if (arguments.positional.length < function.requiredParameterCount) {
+      fail(arguments, 'Too few positional arguments');
+      return const BottomType();
+    }
+    if (arguments.positional.length > function.positionalParameters.length) {
+      fail(arguments, 'Too many positional arguments');
+      return const BottomType();
+    }
+    if (arguments.types.length != typeParameters.length) {
+      fail(arguments, 'Wrong number of type arguments');
+      return const BottomType();
+    }
+    var instantiation = Substitution.fromPairs(typeParameters, arguments.types);
+    var substitution = Substitution.combine(receiver, instantiation);
+    for (int i = 0; i < typeParameters.length; ++i) {
+      var argument = arguments.types[i];
+      var bound = substitution.substituteType(typeParameters[i].bound);
+      checkAssignable(arguments, argument, bound);
+    }
+    for (int i = 0; i < arguments.positional.length; ++i) {
+      var expectedType = substitution.substituteType(
+          function.positionalParameters[i].type,
+          contravariant: true);
+      checkAssignableExpression(arguments.positional[i], expectedType);
+    }
+    for (int i = 0; i < arguments.named.length; ++i) {
+      var argument = arguments.named[i];
+      bool found = false;
+      for (int j = 0; j < function.namedParameters.length; ++j) {
+        if (argument.name == function.namedParameters[j].name) {
+          var expectedType = substitution.substituteType(
+              function.namedParameters[j].type,
+              contravariant: true);
+          checkAssignableExpression(argument.value, expectedType);
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        fail(argument.value, 'Unexpected named parameter: ${argument.name}');
+        return const BottomType();
+      }
+    }
+    return substitution.substituteType(function.returnType);
+  }
+
+  DartType _getInternalReturnType(FunctionNode function) {
+    switch (function.asyncMarker) {
+      case AsyncMarker.Sync:
+        return function.returnType;
+
+      case AsyncMarker.Async:
+        Class container = coreTypes.futureClass;
+        DartType returnType = function.returnType;
+        if (returnType is InterfaceType && returnType.classNode == container) {
+          return returnType.typeArguments.single;
+        }
+        return const DynamicType();
+
+      case AsyncMarker.SyncStar:
+      case AsyncMarker.AsyncStar:
+      case AsyncMarker.SyncYielding:
+        return null;
+
+      default:
+        throw 'Unexpected async marker: ${function.asyncMarker}';
+    }
+  }
+
+  DartType _getYieldType(FunctionNode function) {
+    switch (function.asyncMarker) {
+      case AsyncMarker.Sync:
+      case AsyncMarker.Async:
+        return null;
+
+      case AsyncMarker.SyncStar:
+      case AsyncMarker.AsyncStar:
+        Class container = function.asyncMarker == AsyncMarker.SyncStar
+            ? coreTypes.iterableClass
+            : coreTypes.streamClass;
+        DartType returnType = function.returnType;
+        if (returnType is InterfaceType && returnType.classNode == container) {
+          return returnType.typeArguments.single;
+        }
+        return const DynamicType();
+
+      case AsyncMarker.SyncYielding:
+        return function.returnType;
+
+      default:
+        throw 'Unexpected async marker: ${function.asyncMarker}';
+    }
+  }
+
+  @override
+  DartType visitAsExpression(AsExpression node) {
+    visitExpression(node.operand);
+    return node.type;
+  }
+
+  @override
+  DartType visitAwaitExpression(AwaitExpression node) {
+    return environment.unfutureType(visitExpression(node.operand));
+  }
+
+  @override
+  DartType visitBoolLiteral(BoolLiteral node) {
+    return environment.boolType;
+  }
+
+  @override
+  DartType visitConditionalExpression(ConditionalExpression node) {
+    checkAssignableExpression(node.condition, environment.boolType);
+    checkAssignableExpression(node.then, node.staticType);
+    checkAssignableExpression(node.otherwise, node.staticType);
+    return node.staticType;
+  }
+
+  @override
+  DartType visitConstructorInvocation(ConstructorInvocation node) {
+    Constructor target = node.target;
+    Arguments arguments = node.arguments;
+    Class class_ = target.enclosingClass;
+    handleCall(arguments, target.function,
+        typeParameters: class_.typeParameters);
+    return new InterfaceType(target.enclosingClass, arguments.types);
+  }
+
+  @override
+  DartType visitDirectMethodInvocation(DirectMethodInvocation node) {
+    return handleCall(node.arguments, node.target.function,
+        receiver: getReceiverType(node, node.receiver, node.target));
+  }
+
+  @override
+  DartType visitDirectPropertyGet(DirectPropertyGet node) {
+    var receiver = getReceiverType(node, node.receiver, node.target);
+    return receiver.substituteType(node.target.getterType);
+  }
+
+  @override
+  DartType visitDirectPropertySet(DirectPropertySet node) {
+    var receiver = getReceiverType(node, node.receiver, node.target);
+    var value = visitExpression(node.value);
+    checkAssignable(node, value,
+        receiver.substituteType(node.target.setterType, contravariant: true));
+    return value;
+  }
+
+  @override
+  DartType visitDoubleLiteral(DoubleLiteral node) {
+    return environment.doubleType;
+  }
+
+  @override
+  DartType visitFunctionExpression(FunctionExpression node) {
+    handleNestedFunctionNode(node.function);
+    return node.function.functionType;
+  }
+
+  @override
+  DartType visitIntLiteral(IntLiteral node) {
+    return environment.intType;
+  }
+
+  @override
+  DartType visitInvalidExpression(InvalidExpression node) {
+    return const BottomType();
+  }
+
+  @override
+  DartType visitIsExpression(IsExpression node) {
+    visitExpression(node.operand);
+    return environment.boolType;
+  }
+
+  @override
+  DartType visitLet(Let node) {
+    var value = visitExpression(node.variable.initializer);
+    if (node.variable.type is DynamicType) {
+      node.variable.type = value;
+    }
+    return visitExpression(node.body);
+  }
+
+  @override
+  DartType visitListLiteral(ListLiteral node) {
+    for (var item in node.expressions) {
+      checkAssignableExpression(item, node.typeArgument);
+    }
+    return environment.literalListType(node.typeArgument);
+  }
+
+  @override
+  DartType visitLogicalExpression(LogicalExpression node) {
+    checkAssignableExpression(node.left, environment.boolType);
+    checkAssignableExpression(node.right, environment.boolType);
+    return environment.boolType;
+  }
+
+  @override
+  DartType visitMapLiteral(MapLiteral node) {
+    for (var entry in node.entries) {
+      checkAssignableExpression(entry.key, node.keyType);
+      checkAssignableExpression(entry.value, node.valueType);
+    }
+    return environment.literalMapType(node.keyType, node.valueType);
+  }
+
+  DartType handleDynamicCall(DartType receiver, Arguments arguments) {
+    arguments.positional.forEach(visitExpression);
+    arguments.named.forEach((NamedExpression n) => visitExpression(n.value));
+    return const DynamicType();
+  }
+
+  DartType handleFunctionCall(
+      TreeNode access, FunctionType function, Arguments arguments) {
+    if (function.requiredParameterCount > arguments.positional.length) {
+      fail(access, 'Too few positional arguments');
+      return const BottomType();
+    }
+    if (function.positionalParameters.length < arguments.positional.length) {
+      fail(access, 'Too many positional arguments');
+      return const BottomType();
+    }
+    if (function.typeParameters.length != arguments.types.length) {
+      fail(access, 'Wrong number of type arguments');
+      return const BottomType();
+    }
+    var instantiation =
+        Substitution.fromPairs(function.typeParameters, arguments.types);
+    for (int i = 0; i < arguments.positional.length; ++i) {
+      var expectedType = instantiation.substituteType(
+          function.positionalParameters[i],
+          contravariant: true);
+      checkAssignableExpression(arguments.positional[i], expectedType);
+    }
+    for (int i = 0; i < arguments.named.length; ++i) {
+      var argument = arguments.named[i];
+      bool found = false;
+      for (int j = 0; j < function.namedParameters.length; ++j) {
+        if (argument.name == function.namedParameters[j].name) {
+          var expectedType = instantiation.substituteType(
+              function.namedParameters[j].type,
+              contravariant: true);
+          checkAssignableExpression(argument.value, expectedType);
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        fail(argument.value, 'Unexpected named parameter: ${argument.name}');
+        return const BottomType();
+      }
+    }
+    return instantiation.substituteType(function.returnType);
+  }
+
+  @override
+  DartType visitMethodInvocation(MethodInvocation node) {
+    var target = node.interfaceTarget;
+    if (target == null) {
+      var receiver = visitExpression(node.receiver);
+      if (node.name.name == '==') {
+        visitExpression(node.arguments.positional.single);
+        return environment.boolType;
+      }
+      if (node.name.name == 'call' && receiver is FunctionType) {
+        return handleFunctionCall(node, receiver, node.arguments);
+      }
+      return handleDynamicCall(receiver, node.arguments);
+    } else if (environment.isOverloadedArithmeticOperator(target)) {
+      assert(node.arguments.positional.length == 1);
+      var receiver = visitExpression(node.receiver);
+      var argument = visitExpression(node.arguments.positional[0]);
+      return environment.getTypeOfOverloadedArithmetic(receiver, argument);
+    } else {
+      return handleCall(node.arguments, target.function,
+          receiver: getReceiverType(node, node.receiver, node.interfaceTarget));
+    }
+  }
+
+  @override
+  DartType visitPropertyGet(PropertyGet node) {
+    if (node.interfaceTarget == null) {
+      visitExpression(node.receiver);
+      return const DynamicType();
+    } else {
+      var receiver = getReceiverType(node, node.receiver, node.interfaceTarget);
+      return receiver.substituteType(node.interfaceTarget.getterType);
+    }
+  }
+
+  @override
+  DartType visitPropertySet(PropertySet node) {
+    var value = visitExpression(node.value);
+    if (node.interfaceTarget != null) {
+      var receiver = getReceiverType(node, node.receiver, node.interfaceTarget);
+      checkAssignable(
+          node.value,
+          value,
+          receiver.substituteType(node.interfaceTarget.setterType,
+              contravariant: true));
+    } else {
+      visitExpression(node.receiver);
+    }
+    return value;
+  }
+
+  @override
+  DartType visitNot(Not node) {
+    visitExpression(node.operand);
+    return environment.boolType;
+  }
+
+  @override
+  DartType visitNullLiteral(NullLiteral node) {
+    return const BottomType();
+  }
+
+  @override
+  DartType visitRethrow(Rethrow node) {
+    return const BottomType();
+  }
+
+  @override
+  DartType visitStaticGet(StaticGet node) {
+    return node.target.getterType;
+  }
+
+  @override
+  DartType visitStaticInvocation(StaticInvocation node) {
+    return handleCall(node.arguments, node.target.function);
+  }
+
+  @override
+  DartType visitStaticSet(StaticSet node) {
+    var value = visitExpression(node.value);
+    checkAssignable(node.value, value, node.target.setterType);
+    return value;
+  }
+
+  @override
+  DartType visitStringConcatenation(StringConcatenation node) {
+    node.expressions.forEach(visitExpression);
+    return environment.stringType;
+  }
+
+  @override
+  DartType visitStringLiteral(StringLiteral node) {
+    return environment.stringType;
+  }
+
+  @override
+  DartType visitSuperMethodInvocation(SuperMethodInvocation node) {
+    if (node.interfaceTarget == null) {
+      return handleDynamicCall(environment.thisType, node.arguments);
+    } else {
+      return handleCall(node.arguments, node.interfaceTarget.function,
+          receiver: getSuperReceiverType(node.interfaceTarget));
+    }
+  }
+
+  @override
+  DartType visitSuperPropertyGet(SuperPropertyGet node) {
+    if (node.interfaceTarget == null) {
+      return const DynamicType();
+    } else {
+      var receiver = getSuperReceiverType(node.interfaceTarget);
+      return receiver.substituteType(node.interfaceTarget.getterType);
+    }
+  }
+
+  @override
+  DartType visitSuperPropertySet(SuperPropertySet node) {
+    var value = visitExpression(node.value);
+    if (node.interfaceTarget != null) {
+      var receiver = getSuperReceiverType(node.interfaceTarget);
+      checkAssignable(
+          node.value,
+          value,
+          receiver.substituteType(node.interfaceTarget.setterType,
+              contravariant: true));
+    }
+    return value;
+  }
+
+  @override
+  DartType visitSymbolLiteral(SymbolLiteral node) {
+    return environment.symbolType;
+  }
+
+  @override
+  DartType visitThisExpression(ThisExpression node) {
+    return environment.thisType;
+  }
+
+  @override
+  DartType visitThrow(Throw node) {
+    visitExpression(node.expression);
+    return const BottomType();
+  }
+
+  @override
+  DartType visitTypeLiteral(TypeLiteral node) {
+    return environment.typeType;
+  }
+
+  @override
+  DartType visitVariableGet(VariableGet node) {
+    return node.promotedType ?? node.variable.type;
+  }
+
+  @override
+  DartType visitVariableSet(VariableSet node) {
+    var value = visitExpression(node.value);
+    checkAssignable(node.value, value, node.variable.type);
+    return value;
+  }
+
+  @override
+  visitAssertStatement(AssertStatement node) {
+    visitExpression(node.condition);
+    if (node.message != null) {
+      visitExpression(node.message);
+    }
+  }
+
+  @override
+  visitBlock(Block node) {
+    node.statements.forEach(visitStatement);
+  }
+
+  @override
+  visitBreakStatement(BreakStatement node) {}
+
+  @override
+  visitContinueSwitchStatement(ContinueSwitchStatement node) {}
+
+  @override
+  visitDoStatement(DoStatement node) {
+    visitStatement(node.body);
+    checkAssignableExpression(node.condition, environment.boolType);
+  }
+
+  @override
+  visitEmptyStatement(EmptyStatement node) {}
+
+  @override
+  visitExpressionStatement(ExpressionStatement node) {
+    visitExpression(node.expression);
+  }
+
+  @override
+  visitForInStatement(ForInStatement node) {
+    var iterable = visitExpression(node.iterable);
+    // TODO(asgerf): Store interface targets on for-in loops or desugar them,
+    // instead of doing the ad-hoc resolution here.
+    if (node.isAsync) {
+      checkAssignable(node, getStreamElementType(iterable), node.variable.type);
+    } else {
+      checkAssignable(
+          node, getIterableElementType(iterable), node.variable.type);
+    }
+    visitStatement(node.body);
+  }
+
+  static final Name iteratorName = new Name('iterator');
+  static final Name nextName = new Name('next');
+
+  DartType getIterableElementType(DartType iterable) {
+    if (iterable is InterfaceType) {
+      var iteratorGetter =
+          hierarchy.getInterfaceMember(iterable.classNode, iteratorName);
+      if (iteratorGetter == null) return const DynamicType();
+      var iteratorType = Substitution
+          .fromInterfaceType(iterable)
+          .substituteType(iteratorGetter.getterType);
+      if (iteratorType is InterfaceType) {
+        var nextGetter =
+            hierarchy.getInterfaceMember(iteratorType.classNode, nextName);
+        if (nextGetter == null) return const DynamicType();
+        return Substitution
+            .fromInterfaceType(iteratorType)
+            .substituteType(nextGetter.getterType);
+      }
+    }
+    return const DynamicType();
+  }
+
+  DartType getStreamElementType(DartType stream) {
+    if (stream is InterfaceType) {
+      var asStream =
+          hierarchy.getTypeAsInstanceOf(stream, coreTypes.streamClass);
+      if (asStream == null) return const DynamicType();
+      return asStream.typeArguments.single;
+    }
+    return const DynamicType();
+  }
+
+  @override
+  visitForStatement(ForStatement node) {
+    node.variables.forEach(visitVariableDeclaration);
+    if (node.condition != null) {
+      checkAssignableExpression(node.condition, environment.boolType);
+    }
+    node.updates.forEach(visitExpression);
+    visitStatement(node.body);
+  }
+
+  @override
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    handleNestedFunctionNode(node.function);
+  }
+
+  @override
+  visitIfStatement(IfStatement node) {
+    checkAssignableExpression(node.condition, environment.boolType);
+    visitStatement(node.then);
+    if (node.otherwise != null) {
+      visitStatement(node.otherwise);
+    }
+  }
+
+  @override
+  visitInvalidStatement(InvalidStatement node) {}
+
+  @override
+  visitLabeledStatement(LabeledStatement node) {
+    visitStatement(node.body);
+  }
+
+  @override
+  visitReturnStatement(ReturnStatement node) {
+    if (node.expression != null) {
+      if (environment.returnType == null) {
+        fail(node, 'Return of a value from void method');
+      } else {
+        var type = visitExpression(node.expression);
+        if (environment.currentAsyncMarker == AsyncMarker.Async) {
+          type = environment.unfutureType(type);
+        }
+        checkAssignable(node.expression, type, environment.returnType);
+      }
+    }
+  }
+
+  @override
+  visitSwitchStatement(SwitchStatement node) {
+    visitExpression(node.expression);
+    for (var switchCase in node.cases) {
+      switchCase.expressions.forEach(visitExpression);
+      visitStatement(switchCase.body);
+    }
+  }
+
+  @override
+  visitTryCatch(TryCatch node) {
+    visitStatement(node.body);
+    for (var catchClause in node.catches) {
+      visitStatement(catchClause.body);
+    }
+  }
+
+  @override
+  visitTryFinally(TryFinally node) {
+    visitStatement(node.body);
+    visitStatement(node.finalizer);
+  }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    if (node.initializer != null) {
+      checkAssignableExpression(node.initializer, node.type);
+    }
+  }
+
+  @override
+  visitWhileStatement(WhileStatement node) {
+    checkAssignableExpression(node.condition, environment.boolType);
+    visitStatement(node.body);
+  }
+
+  @override
+  visitYieldStatement(YieldStatement node) {
+    if (node.isYieldStar) {
+      Class container = environment.currentAsyncMarker == AsyncMarker.AsyncStar
+          ? coreTypes.streamClass
+          : coreTypes.iterableClass;
+      var type = visitExpression(node.expression);
+      var asContainer = type is InterfaceType
+          ? hierarchy.getTypeAsInstanceOf(type, container)
+          : null;
+      if (asContainer != null) {
+        checkAssignable(node.expression, asContainer.typeArguments[0],
+            environment.yieldType);
+      } else {
+        fail(node.expression, '$type is not an instance of $container');
+      }
+    } else {
+      checkAssignableExpression(node.expression, environment.yieldType);
+    }
+  }
+
+  @override
+  visitFieldInitializer(FieldInitializer node) {
+    checkAssignableExpression(node.value, node.field.type);
+  }
+
+  @override
+  visitRedirectingInitializer(RedirectingInitializer node) {
+    handleCall(node.arguments, node.target.function,
+        typeParameters: const <TypeParameter>[]);
+  }
+
+  @override
+  visitSuperInitializer(SuperInitializer node) {
+    handleCall(node.arguments, node.target.function,
+        typeParameters: const <TypeParameter>[]);
+  }
+
+  @override
+  visitLocalInitializer(LocalInitializer node) {
+    visitVariableDeclaration(node.variable);
+  }
+
+  @override
+  visitInvalidInitializer(InvalidInitializer node) {}
+}
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
new file mode 100644
index 0000000..c354c44
--- /dev/null
+++ b/pkg/kernel/lib/type_environment.dart
@@ -0,0 +1,225 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_environment;
+
+import 'ast.dart';
+import 'class_hierarchy.dart';
+import 'core_types.dart';
+import 'type_algebra.dart';
+
+typedef void ErrorHandler(TreeNode node, String message);
+
+class TypeEnvironment extends SubtypeTester {
+  final CoreTypes coreTypes;
+  final ClassHierarchy hierarchy;
+  InterfaceType thisType;
+
+  DartType returnType;
+  DartType yieldType;
+  AsyncMarker currentAsyncMarker = AsyncMarker.Sync;
+
+  /// An error handler for use in debugging, or `null` if type errors should not
+  /// be tolerated.  See [typeError].
+  ErrorHandler errorHandler;
+
+  TypeEnvironment(this.coreTypes, this.hierarchy);
+
+  InterfaceType get objectType => coreTypes.objectClass.rawType;
+  InterfaceType get nullType => coreTypes.nullClass.rawType;
+  InterfaceType get boolType => coreTypes.boolClass.rawType;
+  InterfaceType get intType => coreTypes.intClass.rawType;
+  InterfaceType get numType => coreTypes.numClass.rawType;
+  InterfaceType get doubleType => coreTypes.doubleClass.rawType;
+  InterfaceType get stringType => coreTypes.stringClass.rawType;
+  InterfaceType get symbolType => coreTypes.symbolClass.rawType;
+  InterfaceType get typeType => coreTypes.typeClass.rawType;
+  InterfaceType get rawFunctionType => coreTypes.functionClass.rawType;
+
+  Class get intClass => coreTypes.intClass;
+  Class get numClass => coreTypes.numClass;
+
+  InterfaceType literalListType(DartType elementType) {
+    return new InterfaceType(coreTypes.listClass, <DartType>[elementType]);
+  }
+
+  InterfaceType literalMapType(DartType key, DartType value) {
+    return new InterfaceType(coreTypes.mapClass, <DartType>[key, value]);
+  }
+
+  InterfaceType iterableType(DartType type) {
+    return new InterfaceType(coreTypes.iterableClass, <DartType>[type]);
+  }
+
+  InterfaceType streamType(DartType type) {
+    return new InterfaceType(coreTypes.streamClass, <DartType>[type]);
+  }
+
+  InterfaceType futureType(DartType type) {
+    return new InterfaceType(coreTypes.futureClass, <DartType>[type]);
+  }
+
+  /// Removes any number of `Future<>` types wrapping a type.
+  DartType unfutureType(DartType type) {
+    return type is InterfaceType && type.classNode == coreTypes.futureClass
+        ? unfutureType(type.typeArguments[0])
+        : type;
+  }
+
+  /// Called if the computation of a static type failed due to a type error.
+  ///
+  /// This should never happen in production.  The frontend should report type
+  /// errors, and either recover from the error during translation or abort
+  /// compilation if unable to recover.
+  ///
+  /// By default, this throws an exception, since programs in kernel are assumed
+  /// to be correctly typed.
+  ///
+  /// An [errorHandler] may be provided in order to override the default
+  /// behavior and tolerate the presence of type errors.  This can be useful for
+  /// debugging IR producers which are required to produce a strongly typed IR.
+  void typeError(TreeNode node, String message) {
+    if (errorHandler != null) {
+      errorHandler(node, message);
+    } else {
+      throw '$message in $node';
+    }
+  }
+
+  /// True if [member] is a binary operator that returns an `int` if both
+  /// operands are `int`, and otherwise returns `double`.
+  ///
+  /// This is a case of type-based overloading, which in Dart is only supported
+  /// by giving special treatment to certain arithmetic operators.
+  bool isOverloadedArithmeticOperator(Procedure member) {
+    Class class_ = member.enclosingClass;
+    if (class_ == coreTypes.intClass || class_ == coreTypes.numClass) {
+      String name = member.name.name;
+      return name == '+' || name == '-' || name == '*' || name == 'remainder';
+    }
+    return false;
+  }
+
+  /// Returns the static return type of an overloaded arithmetic operator
+  /// (see [isOverloadedArithmeticOperator]) given the static type of the
+  /// operands.
+  ///
+  /// If both types are `int`, the returned type is `int`.
+  /// If either type is `double`, the returned type is `double`.
+  /// If both types refer to the same type variable (typically with `num` as
+  /// the upper bound), then that type variable is returned.
+  /// Otherwise `num` is returned.
+  DartType getTypeOfOverloadedArithmetic(DartType type1, DartType type2) {
+    if (type1 == type2) return type1;
+    if (type1 == doubleType || type2 == doubleType) return doubleType;
+    return numType;
+  }
+}
+
+/// The part of [TypeEnvironment] that deals with subtype tests.
+///
+/// This lives in a separate class so it can be tested independently of the SDK.
+abstract class SubtypeTester {
+  InterfaceType get objectType;
+  InterfaceType get rawFunctionType;
+  ClassHierarchy get hierarchy;
+
+  /// Returns true if [subtype] is a subtype of [supertype].
+  bool isSubtypeOf(DartType subtype, DartType supertype) {
+    if (identical(subtype, supertype)) return true;
+    if (subtype is BottomType) return true;
+    if (supertype is DynamicType || supertype == objectType) {
+      return true;
+    }
+    if (subtype is InterfaceType && supertype is InterfaceType) {
+      var upcastType =
+          hierarchy.getTypeAsInstanceOf(subtype, supertype.classNode);
+      if (upcastType == null) return false;
+      for (int i = 0; i < upcastType.typeArguments.length; ++i) {
+        // Termination: the 'supertype' parameter decreases in size.
+        if (!isSubtypeOf(
+            upcastType.typeArguments[i], supertype.typeArguments[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+    if (subtype is TypeParameterType) {
+      if (supertype is TypeParameterType &&
+          subtype.parameter == supertype.parameter) {
+        return true;
+      }
+      // Termination: if there are no cyclically bound type parameters, this
+      // recursive call can only occur a finite number of times, before reaching
+      // a shrinking recursive call (or terminating).
+      return isSubtypeOf(subtype.parameter.bound, supertype);
+    }
+    if (subtype is FunctionType) {
+      if (supertype == rawFunctionType) return true;
+      if (supertype is FunctionType) {
+        return _isFunctionSubtypeOf(subtype, supertype);
+      }
+    }
+    return false;
+  }
+
+  bool _isFunctionSubtypeOf(FunctionType subtype, FunctionType supertype) {
+    if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
+      return false;
+    }
+    if (subtype.positionalParameters.length <
+        supertype.positionalParameters.length) {
+      return false;
+    }
+    if (subtype.typeParameters.length != supertype.typeParameters.length) {
+      return false;
+    }
+    if (subtype.typeParameters.isNotEmpty) {
+      var substitution = <TypeParameter, DartType>{};
+      for (int i = 0; i < subtype.typeParameters.length; ++i) {
+        var subParameter = subtype.typeParameters[i];
+        var superParameter = supertype.typeParameters[i];
+        substitution[subParameter] = new TypeParameterType(superParameter);
+      }
+      for (int i = 0; i < subtype.typeParameters.length; ++i) {
+        var subParameter = subtype.typeParameters[i];
+        var superParameter = supertype.typeParameters[i];
+        var subBound = substitute(subParameter.bound, substitution);
+        // Termination: if there are no cyclically bound type parameters, this
+        // recursive call can only occur a finite number of times before
+        // reaching a shrinking recursive call (or terminating).
+        if (!isSubtypeOf(superParameter.bound, subBound)) {
+          return false;
+        }
+      }
+      subtype = substitute(subtype.withoutTypeParameters, substitution);
+    }
+    if (supertype.returnType is! VoidType &&
+        !isSubtypeOf(subtype.returnType, supertype.returnType)) {
+      return false;
+    }
+    for (int i = 0; i < supertype.positionalParameters.length; ++i) {
+      var supertypeParameter = supertype.positionalParameters[i];
+      var subtypeParameter = subtype.positionalParameters[i];
+      // Termination: Both types shrink in size.
+      if (!isSubtypeOf(supertypeParameter, subtypeParameter)) {
+        return false;
+      }
+    }
+    int subtypeNameIndex = 0;
+    for (NamedType supertypeParameter in supertype.namedParameters) {
+      while (subtypeNameIndex < subtype.namedParameters.length &&
+          subtype.namedParameters[subtypeNameIndex].name !=
+              supertypeParameter.name) {
+        ++subtypeNameIndex;
+      }
+      if (subtypeNameIndex == subtype.namedParameters.length) return false;
+      NamedType subtypeParameter = subtype.namedParameters[subtypeNameIndex];
+      // Termination: Both types shrink in size.
+      if (!isSubtypeOf(supertypeParameter.type, subtypeParameter.type)) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git a/pkg/kernel/lib/type_propagation/builder.dart b/pkg/kernel/lib/type_propagation/builder.dart
new file mode 100644
index 0000000..f33e12e
--- /dev/null
+++ b/pkg/kernel/lib/type_propagation/builder.dart
@@ -0,0 +1,1977 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.builder;
+
+import '../ast.dart';
+import '../class_hierarchy.dart';
+import '../core_types.dart';
+import 'canonicalizer.dart';
+import 'constraints.dart';
+import 'type_propagation.dart';
+import 'visualizer.dart';
+
+/// Maps AST nodes to constraint variables at the level of function boundaries.
+///
+/// Bindings internally in a function are only preserved by the [Visualizer].
+class VariableMapping {
+  /// Variable holding all values that may flow into the given field.
+  final Map<Field, int> fields = <Field, int>{};
+
+  /// Variable holding all values that may be returned from the given function.
+  final Map<FunctionNode, int> returns = <FunctionNode, int>{};
+
+  /// Variable holding all values that may be passed into the given function
+  /// parameter (possibly through a default parameter value).
+  final Map<VariableDeclaration, int> parameters = <VariableDeclaration, int>{};
+
+  /// Variable holding the function object for the given function.
+  final Map<FunctionNode, int> functions = <FunctionNode, int>{};
+
+  static VariableMapping make(int _) => new VariableMapping();
+}
+
+/// Maps AST nodes to the lattice employed by the constraint system.
+class LatticeMapping {
+  /// Lattice point containing the torn-off functions originating from an
+  /// instance procedure that overrides the given procedure.
+  final Map<Procedure, int> functionsOverridingMethod = <Procedure, int>{};
+
+  /// Lattice point containing all torn-off functions originating from an
+  /// instance procedure of the given name,
+  ///
+  /// This ensures that calls to a method with unknown receiver may still
+  /// recover some information about the callee based on the name alone.
+  final Map<Name, int> functionsWithName = <Name, int>{};
+
+  /// Maps a class index to a lattice point containing all values that are
+  /// subtypes of that class.
+  final List<int> subtypesOfClass;
+
+  /// Maps a class index to a lattice point containing all values that are
+  /// subclasses of that class.
+  final List<int> subclassesOfClass;
+
+  LatticeMapping(int numberOfClasses)
+      : subtypesOfClass = new List<int>(numberOfClasses),
+        subclassesOfClass = new List<int>(numberOfClasses);
+}
+
+/// Generates a [ConstraintSystem] to be solved by [Solver].
+class Builder {
+  final Program program;
+  final ClassHierarchy hierarchy;
+  final CoreTypes coreTypes;
+  final ConstraintSystem constraints;
+  final FieldNames fieldNames;
+  final Visualizer visualizer;
+
+  final LatticeMapping lattice;
+
+  /// Bindings for all members. The values inferred for these variables is the
+  /// output of the analysis.
+  ///
+  /// For static members, these are the canonical variables representing the
+  /// member.
+  ///
+  /// For instance members, these are the context-insensitive joins over all
+  /// the specialized copies of the instance member.
+  final VariableMapping global = new VariableMapping();
+
+  /// Maps a class index to the bindings for instance members specific to that
+  /// class as the host class.
+  final List<VariableMapping> classMapping;
+
+  final Map<TypeParameter, int> functionTypeParameters = <TypeParameter, int>{};
+
+  /// Variable holding the result of the declaration-site field initializer
+  /// for the given field.
+  final Map<Field, int> declarationSiteFieldInitializer = <Field, int>{};
+
+  /// Maps a class index to the result of [getInterfaceEscapeVariable].
+  final List<int> interfaceEscapeVariables;
+
+  /// Maps a class index to the result of [getExternalInstanceVariable].
+  final List<int> externalClassVariables;
+  final List<int> externalClassValues;
+
+  final List<int> externalClassWorklist = <int>[];
+
+  final Uint31PairMap<int> _stores = new Uint31PairMap<int>();
+  final Uint31PairMap<int> _loads = new Uint31PairMap<int>();
+  final List<InferredValue> _baseTypeOfLatticePoint = <InferredValue>[];
+
+  int bottomNode;
+  int dynamicNode;
+  int boolNode;
+  int intNode;
+  int doubleNode;
+  int stringNode;
+  int symbolNode;
+  int typeNode;
+  int listNode;
+  int mapNode;
+  int nullNode;
+  int iterableNode;
+  int futureNode;
+  int streamNode;
+  int functionValueNode;
+
+  int iteratorField;
+  int currentField;
+
+  /// Lattice point containing all function values.
+  int latticePointForAllFunctions;
+
+  Member identicalFunction;
+
+  bool verbose;
+
+  Builder(Program program,
+      {ClassHierarchy hierarchy,
+      FieldNames names,
+      CoreTypes coreTypes,
+      Visualizer visualizer,
+      bool verbose: false})
+      : this._internal(
+            program,
+            hierarchy ?? new ClassHierarchy(program),
+            names ?? new FieldNames(),
+            coreTypes ?? new CoreTypes(program),
+            visualizer,
+            verbose);
+
+  Builder._internal(this.program, ClassHierarchy hierarchy, FieldNames names,
+      this.coreTypes, Visualizer visualizer, this.verbose)
+      : this.hierarchy = hierarchy,
+        this.fieldNames = names,
+        this.visualizer = visualizer,
+        this.constraints = new ConstraintSystem(),
+        this.classMapping = new List<VariableMapping>.generate(
+            hierarchy.classes.length, VariableMapping.make),
+        this.interfaceEscapeVariables = new List<int>(hierarchy.classes.length),
+        this.externalClassVariables = new List<int>(hierarchy.classes.length),
+        this.externalClassValues = new List<int>(hierarchy.classes.length),
+        this.lattice = new LatticeMapping(hierarchy.classes.length) {
+    if (visualizer != null) {
+      visualizer.builder = this;
+      visualizer.constraints = constraints;
+      visualizer.fieldNames = fieldNames;
+    }
+
+    // Build the subtype lattice points.
+    // The order in which lattice points are created determines how ambiguous
+    // upper bounds are resolved.  The lattice point with highest index among
+    // the potential upper bounds is the result of a join.
+    // We create all the subtype lattice point before all the subclass lattice
+    // points, to ensure that subclass information takes precedence over
+    // subtype information.
+    for (int i = 0; i < hierarchy.classes.length; ++i) {
+      Class class_ = hierarchy.classes[i];
+      List<int> supers = <int>[];
+      if (class_.supertype != null) {
+        supers.add(getLatticePointForSubtypesOfClass(class_.superclass));
+      }
+      if (class_.mixedInType != null) {
+        supers.add(getLatticePointForSubtypesOfClass(class_.mixedInClass));
+      }
+      for (Supertype supertype in class_.implementedTypes) {
+        supers.add(getLatticePointForSubtypesOfClass(supertype.classNode));
+      }
+      int subtypePoint = newLatticePoint(supers, class_,
+          i == 0 ? BaseClassKind.Subclass : BaseClassKind.Subtype);
+      lattice.subtypesOfClass[i] = subtypePoint;
+      visualizer?.annotateLatticePoint(subtypePoint, class_, 'subtype');
+    }
+
+    // Build the lattice points for subclasses and exact classes.
+    for (int i = 0; i < hierarchy.classes.length; ++i) {
+      Class class_ = hierarchy.classes[i];
+      int subtypePoint = lattice.subtypesOfClass[i];
+      assert(subtypePoint != null);
+      int subclassPoint;
+      if (class_.supertype == null) {
+        subclassPoint = subtypePoint;
+      } else {
+        subclassPoint = newLatticePoint(<int>[
+          getLatticePointForSubclassesOf(class_.superclass),
+          subtypePoint
+        ], class_, BaseClassKind.Subclass);
+      }
+      lattice.subclassesOfClass[i] = subclassPoint;
+      int concretePoint =
+          newLatticePoint(<int>[subclassPoint], class_, BaseClassKind.Exact);
+      int value = constraints.newValue(concretePoint);
+      int variable = constraints.newVariable();
+      // We construct the constraint system so the first N variables and values
+      // correspond to the N classes in the program.
+      assert(variable == i);
+      assert(value == -i);
+      visualizer?.annotateLatticePoint(subclassPoint, class_, 'subclass');
+      visualizer?.annotateLatticePoint(concretePoint, class_, 'concrete');
+      visualizer?.annotateVariable(variable, class_);
+      visualizer?.annotateValue(value, class_);
+      addInput(value, ValueBit.other, variable);
+    }
+
+    bottomNode = newVariable(null, 'bottom');
+    dynamicNode = getExternalInstanceVariable(coreTypes.objectClass);
+    boolNode = getExternalInstanceVariable(coreTypes.boolClass);
+    intNode = getExternalInstanceVariable(coreTypes.intClass);
+    doubleNode = getExternalInstanceVariable(coreTypes.doubleClass);
+    stringNode = getExternalInstanceVariable(coreTypes.stringClass);
+    symbolNode = getExternalInstanceVariable(coreTypes.symbolClass);
+    typeNode = getExternalInstanceVariable(coreTypes.typeClass);
+    listNode = getExternalInstanceVariable(coreTypes.listClass);
+    mapNode = getExternalInstanceVariable(coreTypes.mapClass);
+    iterableNode = getExternalInstanceVariable(coreTypes.iterableClass);
+    futureNode = getExternalInstanceVariable(coreTypes.futureClass);
+    streamNode = getExternalInstanceVariable(coreTypes.streamClass);
+    functionValueNode = getExternalInstanceVariable(coreTypes.functionClass);
+    nullNode = newVariable(null, 'Null');
+
+    iteratorField = getPropertyField(Names.iterator);
+    currentField = getPropertyField(Names.current);
+
+    latticePointForAllFunctions =
+        getLatticePointForSubtypesOfClass(coreTypes.functionClass);
+
+    identicalFunction = coreTypes.getCoreProcedure('dart:core', 'identical');
+
+    // Seed bitmasks for built-in values.
+    constraints.addBitmaskInput(ValueBit.null_, nullNode);
+    constraints.addBitmaskInput(ValueBit.all, dynamicNode);
+
+    for (Library library in program.libraries) {
+      for (Procedure procedure in library.procedures) {
+        buildProcedure(null, procedure);
+      }
+      for (Field field in library.fields) {
+        buildStaticField(field);
+      }
+      for (Class class_ in library.classes) {
+        for (Procedure procedure in class_.procedures) {
+          if (procedure.isStatic) {
+            buildProcedure(null, procedure);
+          }
+        }
+        for (Field field in class_.fields) {
+          if (field.isStatic) {
+            buildStaticField(field);
+          }
+        }
+        if (!class_.isAbstract) {
+          buildInstanceValue(class_);
+        }
+      }
+    }
+
+    // We don't track the values flowing into the identical function, as it
+    // causes a lot of spurious escape.  Every class that inherits Object.==
+    // would escape its 'this' value into a dynamic context.
+    // Mark the identical() parameters as 'dynamic' so the output is sound.
+    for (int i = 0; i < 2; ++i) {
+      constraints.addAssign(
+          dynamicNode,
+          getSharedParameterVariable(
+              identicalFunction.function.positionalParameters[i]));
+    }
+
+    // Build constraints mocking the external interfaces.
+    while (externalClassWorklist.isNotEmpty) {
+      int classIndex = externalClassWorklist.removeLast();
+      _buildExternalClassValue(classIndex);
+    }
+  }
+
+  int newLatticePoint(
+      List<int> parentLatticePoints, Class baseClass, BaseClassKind kind) {
+    _baseTypeOfLatticePoint.add(new InferredValue(baseClass, kind, 0));
+    return constraints.newLatticePoint(parentLatticePoints);
+  }
+
+  void addInput(int value, int bitmask, int destination) {
+    constraints.addAllocation(value, destination);
+    constraints.addBitmaskInput(bitmask, destination);
+  }
+
+  /// Returns an [InferredValue] with the base type relation for the given
+  /// lattice point but whose bitmask is 0.  The bitmask must be filled in
+  /// before this value is exposed to analysis clients.
+  InferredValue getBaseTypeOfLatticePoint(int latticePoint) {
+    return _baseTypeOfLatticePoint[latticePoint];
+  }
+
+  /// Returns the lattice point containing all subtypes of the given class.
+  int getLatticePointForSubtypesOfClass(Class classNode) {
+    int index = hierarchy.getClassIndex(classNode);
+    return lattice.subtypesOfClass[index];
+  }
+
+  /// Returns the lattice point containing all subclasses of the given class.
+  int getLatticePointForSubclassesOf(Class classNode) {
+    int index = hierarchy.getClassIndex(classNode);
+    return lattice.subclassesOfClass[index];
+  }
+
+  /// Returns the lattice point containing all function implementing the given
+  /// instance method.
+  int getLatticePointForFunctionsOverridingMethod(Procedure node) {
+    assert(!node.isStatic);
+    if (node.isAccessor) return latticePointForAllFunctions;
+    if (node.enclosingClass.supertype == null)
+      return latticePointForAllFunctions;
+    return lattice.functionsOverridingMethod[node] ??=
+        _makeLatticePointForFunctionsOverridingMethod(node);
+  }
+
+  int _makeLatticePointForFunctionsOverridingMethod(Procedure node) {
+    Class host = node.enclosingClass;
+    Member superMember = host.supertype == null
+        ? null
+        : hierarchy.getInterfaceMember(host.superclass, node.name);
+    int super_;
+    if (superMember is Procedure && !superMember.isAccessor) {
+      super_ = getLatticePointForFunctionsOverridingMethod(superMember);
+    } else {
+      super_ = getLatticePointForFunctionsWithName(node.name);
+    }
+    int point = newLatticePoint(
+        <int>[super_], coreTypes.functionClass, BaseClassKind.Subtype);
+    visualizer?.annotateLatticePoint(point, node, 'overriders');
+    return point;
+  }
+
+  int newVariable([TreeNode node, String info]) {
+    int variable = constraints.newVariable();
+    visualizer?.annotateVariable(variable, node, info);
+    return variable;
+  }
+
+  VariableMapping getClassMapping(Class host) {
+    if (host == null) return global;
+    int index = hierarchy.getClassIndex(host);
+    return classMapping[index];
+  }
+
+  /// Returns a variable that should contain all values that may be contained
+  /// in any copy the given field (hence "shared" between the copies).
+  int getSharedFieldVariable(Field field) {
+    return global.fields[field] ??= newVariable(field);
+  }
+
+  /// Returns a variable representing the given field on the given class.
+  ///
+  /// If the field is static, [host] should be `null`.
+  int getFieldVariable(Class host, Field field) {
+    if (host == null) return getSharedFieldVariable(field);
+    VariableMapping mapping = getClassMapping(host);
+    return mapping.fields[field] ??= _makeFieldVariable(host, field);
+  }
+
+  int _makeFieldVariable(Class host, Field field) {
+    // Create a variable specific to this host class, and add an assignment
+    // to the global sink for this field.
+    assert(host != null);
+    int variable = newVariable(field);
+    int sink = getSharedFieldVariable(field);
+    constraints.addSink(variable, sink);
+    visualizer?.annotateSink(variable, sink, field);
+    return variable;
+  }
+
+  /// Variable containing all values that may be passed into the given parameter
+  /// of any instantiation of the given function (hence "shared" between them).
+  int getSharedParameterVariable(VariableDeclaration node) {
+    return global.parameters[node] ??= newVariable(node, 'shared parameter');
+  }
+
+  int getParameterVariable(Class host, VariableDeclaration node) {
+    if (host == null) return getSharedParameterVariable(node);
+    VariableMapping mapping = getClassMapping(host);
+    return mapping.parameters[node] ??= _makeParameterVariable(host, node);
+  }
+
+  int _makeParameterVariable(Class host, VariableDeclaration node) {
+    assert(host != null);
+    int variable = newVariable(node, 'parameter');
+    int sink = getSharedParameterVariable(node);
+    constraints.addSink(variable, sink);
+    visualizer?.annotateSink(variable, sink, node);
+    return variable;
+  }
+
+  /// Returns the variable representing all the values that would be checked
+  /// against the given function type parameter in checked mode.
+  ///
+  /// This is used to model the behavior of external generic methods.
+  ///
+  /// For example:
+  ///
+  ///     class List {
+  ///         external static factory List<T> filled<T>(int length, T value);
+  ///     }
+  ///
+  /// A variable `v` representing `T` will be generated. All values that are
+  /// passed into the `value` parameter will flow into `v`, and `v` will
+  /// in turn flow into the type parameter field of `List`, because the method
+  /// returns `List<T>`.  Also see [FieldNames.getTypeParameterField].
+  int getFunctionTypeParameterVariable(TypeParameter node) {
+    return functionTypeParameters[node] ??= newVariable(node);
+  }
+
+  /// Variable containing all values that may be returned from any instantiation
+  /// of the given function (hence "shared" between them).
+  int getSharedReturnVariable(FunctionNode node) {
+    return global.returns[node] ??= newVariable(node, 'return');
+  }
+
+  int getReturnVariable(Class host, Procedure node) {
+    if (host == null) return getSharedReturnVariable(node.function);
+    VariableMapping mapping = getClassMapping(host);
+    return mapping.returns[node.function] ??= _makeReturnVariable(host, node);
+  }
+
+  int _makeReturnVariable(Class host, Procedure node) {
+    assert(host != null);
+    int variable = newVariable(node, 'return');
+    int sink = getSharedReturnVariable(node.function);
+    constraints.addSink(variable, sink);
+    visualizer?.annotateSink(variable, sink, node);
+    return variable;
+  }
+
+  /// Returns a variable containing all the function objects for all
+  /// instantiations of the given function.
+  int getSharedTearOffVariable(FunctionNode node) {
+    return global.functions[node] ??= newVariable(node);
+  }
+
+  /// Returns a variable containing the torn-off copy of the given function
+  /// occurring in static context.
+  int getStaticTearOffVariable(FunctionNode node) {
+    return global.functions[node] ??= _makeStaticTearOffVariable(node);
+  }
+
+  int _makeStaticTearOffVariable(FunctionNode node) {
+    return newFunction(node);
+  }
+
+  /// Returns a variable containing the torn-off copy of the given procedure.
+  int getTearOffVariable(Class host, Procedure node) {
+    if (host == null) return getStaticTearOffVariable(node.function);
+    VariableMapping mapping = getClassMapping(host);
+    return mapping.functions[node.function] ??=
+        _makeTearOffVariable(host, node);
+  }
+
+  int _makeTearOffVariable(Class host, Procedure node) {
+    int variable = newFunction(node.function, node);
+    int sink = getSharedTearOffVariable(node.function);
+    constraints.addSink(variable, sink);
+    visualizer?.annotateSink(variable, sink, node);
+    return variable;
+  }
+
+  /// Returns the variable holding the result of a 'get' selector dispatched
+  /// to the given member, or `null` if the member cannot respond to a 'get'
+  /// selector.
+  int getMemberGetter(Class host, Member member) {
+    if (member is Field) {
+      return getFieldVariable(host, member);
+    } else if (member is Procedure) {
+      if (member.isGetter) {
+        return getReturnVariable(host, member);
+      } else if (!member.isAccessor) {
+        return getTearOffVariable(host, member);
+      }
+    }
+    return null;
+  }
+
+  /// Returns the variable holding the argument to a 'set' selector dispatched
+  /// to the given member, or `null` if the member cannot respond to a 'set'
+  /// selector.
+  int getMemberSetter(Class host, Member member) {
+    if (member is Field && !member.isFinal) {
+      return getFieldVariable(host, member);
+    } else if (member is Procedure && member.isSetter) {
+      return getParameterVariable(
+          host, member.function.positionalParameters[0]);
+    }
+    return null;
+  }
+
+  /// Returns a lattice point containing all instance methods with the given
+  /// name.
+  int getLatticePointForFunctionsWithName(Name name) {
+    if (name == null) return latticePointForAllFunctions;
+    return lattice.functionsWithName[name] ??=
+        _makeLatticePointForFunctionsWithName(name);
+  }
+
+  int _makeLatticePointForFunctionsWithName(Name name) {
+    int point = newLatticePoint(<int>[latticePointForAllFunctions],
+        coreTypes.functionClass, BaseClassKind.Subtype);
+    visualizer?.annotateLatticePoint(point, null, 'Methods of name $name');
+    return point;
+  }
+
+  /// Returns a variable holding a new function value annotated with given AST
+  /// node.
+  ///
+  /// If the function is the body of an instance procedure, it should be passed
+  /// as [member] to ensure an effective lattice is built for it.
+  /// Otherwise, [member] should be omitted.
+  int newFunction(FunctionNode node, [Procedure member]) {
+    assert(node != null);
+    int functionVariable = newVariable(node);
+    int baseLatticePoint = member == null
+        ? latticePointForAllFunctions
+        : getLatticePointForFunctionsOverridingMethod(member);
+    int latticePoint = newLatticePoint(<int>[baseLatticePoint],
+        coreTypes.functionClass, BaseClassKind.Subtype);
+    visualizer?.annotateLatticePoint(latticePoint, member, 'function');
+    int minArity = node.requiredParameterCount;
+    int maxArity = node.positionalParameters.length;
+    int functionValue = constraints.newValue(latticePoint);
+    for (int i = 0; i < node.positionalParameters.length; ++i) {
+      int variable = newVariable();
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        int field = fieldNames.getPositionalParameterField(arity, i);
+        constraints.setStoreLocation(functionValue, field, variable);
+        constraints.setLoadLocation(functionValue, field, variable);
+      }
+    }
+    for (int i = 0; i < node.namedParameters.length; ++i) {
+      int variable = newVariable();
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        int field = fieldNames.getNamedParameterField(
+            arity, node.namedParameters[i].name);
+        constraints.setStoreLocation(functionValue, field, variable);
+        constraints.setLoadLocation(functionValue, field, variable);
+      }
+    }
+    int returnVariable = newVariable();
+    for (int arity = minArity; arity <= maxArity; ++arity) {
+      int returnField = fieldNames.getReturnField(arity);
+      constraints.setStoreLocation(functionValue, returnField, returnVariable);
+      constraints.setLoadLocation(functionValue, returnField, returnVariable);
+    }
+    visualizer?.annotateFunction(functionValue, node);
+    visualizer?.annotateValue(functionValue, member, 'function');
+    addInput(functionValue, ValueBit.other, functionVariable);
+    constraints.setLoadLocation(
+        functionValue, fieldNames.callHandlerField, functionVariable);
+    constraints.setLoadLocation(functionValue,
+        fieldNames.getPropertyField(Names.call_), functionVariable);
+    return functionVariable;
+  }
+
+  /// Returns a variable containing the concrete instances of the given class.
+  int getInstanceVariable(Class node) {
+    assert(!node.isAbstract);
+    return hierarchy.getClassIndex(node);
+  }
+
+  /// Returns the value representing the concrete instances of the given class.
+  int getInstanceValue(Class node) {
+    assert(!node.isAbstract);
+    // Values are negated to help distinguish them from variables and
+    // lattice points.
+    return -hierarchy.getClassIndex(node);
+  }
+
+  /// Returns a variable containing the external instances of the given class.
+  ///
+  /// An "external instance of C" is an instance allocated by external code,
+  /// and is either a direct instance of C or an instance of an external class
+  /// that implements C.
+  ///
+  /// For the moment, basic types like `int` and `bool` are treated as external
+  /// instances of their respective classes.
+  ///
+  /// Unlike [getInstanceVariable], this method ensures that the relevant
+  /// constraints have been generated to model an external implementation of the
+  /// class.
+  int getExternalInstanceVariable(Class node) {
+    int classIndex = hierarchy.getClassIndex(node);
+    return externalClassVariables[classIndex] ??=
+        _makeExternalInstanceVariable(node, classIndex);
+  }
+
+  int getValueBitForExternalClass(Class node) {
+    if (node == coreTypes.intClass) {
+      return ValueBit.integer;
+    } else if (node == coreTypes.doubleClass) {
+      return ValueBit.double_;
+    } else if (node == coreTypes.stringClass) {
+      return ValueBit.string;
+    } else {
+      return ValueBit.other;
+    }
+  }
+
+  int _makeExternalInstanceVariable(Class node, int classIndex) {
+    if (node == coreTypes.numClass) {
+      // Don't build an interface based on the "num" class, instead treat it
+      // as the union of "int" and "double".
+      int variable = newVariable(node);
+      constraints.addAssign(intNode, variable);
+      constraints.addAssign(doubleNode, variable);
+      return variable;
+    }
+    int baseLatticePoint = getLatticePointForSubtypesOfClass(node);
+    // TODO(asgerf): Use more fine-grained handling of externals, based on
+    //   metadata or on a specification read from a separate file (issue #22).
+    int latticePoint =
+        newLatticePoint(<int>[baseLatticePoint], node, BaseClassKind.Subtype);
+    visualizer?.annotateLatticePoint(latticePoint, node, 'external');
+    int value = constraints.newValue(latticePoint);
+    int variable = newVariable(node, 'external');
+    addInput(value, getValueBitForExternalClass(node), variable);
+    externalClassValues[classIndex] = value;
+    externalClassWorklist.add(classIndex);
+    return variable;
+  }
+
+  void _buildExternalClassValue(int index) {
+    Class node = hierarchy.classes[index];
+    int variable = externalClassVariables[index];
+    int externalObject = externalClassValues[index];
+    Name previousName = null;
+    for (Member member in hierarchy.getInterfaceMembers(node, setters: false)) {
+      // Do not generate an interface member for a given name more than once.
+      // This can happen if a class inherits two methods through different
+      // inheritance paths.
+      if (member.name == previousName) continue;
+      previousName = member.name;
+      _buildExternalInterfaceMember(node, member, externalObject, variable,
+          isSetter: false);
+    }
+    previousName = null;
+    for (Member member in hierarchy.getInterfaceMembers(node, setters: true)) {
+      if (member.name == previousName) continue;
+      previousName = member.name;
+      _buildExternalInterfaceMember(node, member, externalObject, variable,
+          isSetter: true);
+    }
+    for (TypeParameter parameter in node.typeParameters) {
+      int field = fieldNames.getTypeParameterField(parameter);
+      int location = newVariable(parameter);
+      constraints.setStoreLocation(externalObject, field, location);
+      constraints.setLoadLocation(externalObject, field, location);
+    }
+  }
+
+  void _buildExternalInterfaceMember(
+      Class host, Member member, int object, int variable,
+      {bool isSetter}) {
+    // TODO(asgerf): Handle nullability of return values.
+    TypeEnvironment environment =
+        new TypeEnvironment(this, host, member, thisVariable: variable);
+    int propertyField = fieldNames.getPropertyField(member.name);
+    if (member is Field) {
+      int fieldType = buildCovariantType(member.type, environment);
+      if (isSetter) {
+        constraints.setStoreLocation(object, propertyField, fieldType);
+      } else {
+        constraints.setLoadLocation(object, propertyField, fieldType);
+      }
+    } else {
+      Procedure procedure = member;
+      FunctionNode function = procedure.function;
+      if (procedure.isGetter) {
+        int returned = buildCovariantType(function.returnType, environment);
+        constraints.setLoadLocation(object, propertyField, returned);
+      } else if (procedure.isSetter) {
+        int escaping = environment.getLoad(variable, propertyField);
+        buildContravariantType(
+            function.positionalParameters[0].type, environment, escaping);
+      } else {
+        int externalMember = buildCovariantFunctionType(function, environment);
+        constraints.setLoadLocation(object, propertyField, externalMember);
+      }
+    }
+  }
+
+  /// Returns a variable that is exposed to external calls through the
+  /// given interface.
+  ///
+  /// For example, consider this code with a simplified version of SendPort:
+  ///
+  ///     abstract class SendPort {
+  ///         void send(dynamic x);
+  ///     }
+  ///
+  ///     class MySendPort implements SendPort {
+  ///         void send(x) { ... }
+  ///     }
+  ///
+  ///     external void spawnFunction(SendPort readyPort);
+  ///
+  ///     main() {
+  ///         spawnFunction(new MySendPort());
+  ///     }
+  ///
+  /// We must ensure that the parameter to `MySendPort::send` is inferred to
+  /// be unknown because the external function `spawnFunction` may cause an
+  /// invocation of its `send` method with an unknown argument.
+  ///
+  /// The interface escape variable for this version of `SendPort` would be a
+  /// variable `v` with constraints corresponding to a call `v.send(<dynamic>)`.
+  ///
+  /// Values that escape into an external parameter typed as `SendPort`, such
+  /// as `new MySendPort()` must then be made to flow into `v`.
+  int getInterfaceEscapeVariable(Class node) {
+    int index = hierarchy.getClassIndex(node);
+    return interfaceEscapeVariables[index] ??
+        _buildInterfaceEscapeVariable(node, index);
+  }
+
+  int _buildInterfaceEscapeVariable(Class node, int index) {
+    int escapingObject = constraints.newVariable();
+    visualizer?.annotateVariable(escapingObject, node, 'escape point');
+    interfaceEscapeVariables[index] = escapingObject;
+    for (Member member in hierarchy.getInterfaceMembers(node, setters: false)) {
+      _buildEscapingInterfaceMember(node, member, escapingObject);
+    }
+    for (Member member in hierarchy.getInterfaceMembers(node, setters: true)) {
+      _buildEscapingInterfaceMember(node, member, escapingObject);
+    }
+    return escapingObject;
+  }
+
+  /// Models the behavior of external code invoking [member] on
+  /// [escapingObject].
+  void _buildEscapingInterfaceMember(
+      Class host, Member member, int escapingObject) {
+    TypeEnvironment environment =
+        new TypeEnvironment(this, host, member, thisVariable: escapingObject);
+    int propertyField = fieldNames.getPropertyField(member.name);
+    if (member is Field) {
+      int escapingMember = environment.getLoad(escapingObject, propertyField);
+      buildContravariantType(member.type, environment, escapingMember);
+    } else {
+      Procedure procedure = member;
+      FunctionNode function = procedure.function;
+      if (procedure.isGetter) {
+        int escapingMember = environment.getLoad(escapingObject, propertyField);
+        buildContravariantType(
+            function.returnType, environment, escapingMember);
+      } else if (procedure.isSetter) {
+        VariableDeclaration parameter = function.positionalParameters[0];
+        int argument = buildCovariantType(parameter.type, environment);
+        environment.addStore(escapingObject, propertyField, argument);
+      } else {
+        int escapingMember = environment.getLoad(escapingObject, propertyField);
+        buildContravariantFunctionType(function, environment, escapingMember);
+      }
+    }
+  }
+
+  /// Returns a variable with the possible values of [type] as provided by
+  /// external code.
+  int buildCovariantType(DartType type, TypeEnvironment environment) {
+    return new CovariantExternalTypeVisitor(this, environment).visit(type);
+  }
+
+  /// Like [buildCovariantType], but for the function type implied by the
+  /// type annotations on a function AST node.
+  int buildCovariantFunctionType(
+      FunctionNode node, TypeEnvironment environment) {
+    return new CovariantExternalTypeVisitor(this, environment)
+        .buildFunctionNode(node);
+  }
+
+  /// Generates constraints to model the behavior of [input] escaping into
+  /// external code through a parameter annotated with [type].
+  void buildContravariantType(
+      DartType type, TypeEnvironment environment, int input) {
+    new ContravariantExternalTypeVisitor(this, environment, input).visit(type);
+  }
+
+  /// Like [buildContravariantType], but for the function type implied by the
+  /// type annotations on a function AST node.
+  void buildContravariantFunctionType(
+      FunctionNode node, TypeEnvironment environment, int input) {
+    new ContravariantExternalTypeVisitor(this, environment, input)
+        .buildFunctionNode(node);
+  }
+
+  int getPropertyField(Name name) {
+    return fieldNames.getPropertyField(name);
+  }
+
+  int getPositionalParameterField(int arity, int position) {
+    return fieldNames.getPositionalParameterField(arity, position);
+  }
+
+  int getNamedParameterField(int arity, String name) {
+    return fieldNames.getNamedParameterField(arity, name);
+  }
+
+  int getReturnField(int arity) {
+    return fieldNames.getReturnField(arity);
+  }
+
+  void buildInstanceValue(Class host) {
+    int value = getInstanceValue(host);
+    for (Member target in hierarchy.getDispatchTargets(host, setters: false)) {
+      var getter = getMemberGetter(host, target);
+      constraints.setLoadLocation(value, getPropertyField(target.name), getter);
+    }
+    for (Member target in hierarchy.getDispatchTargets(host, setters: true)) {
+      constraints.setStoreLocation(
+          value, getPropertyField(target.name), getMemberSetter(host, target));
+    }
+    for (Class node = host; node != null; node = node.superclass) {
+      for (Procedure procedure in node.mixin.procedures) {
+        if (!procedure.isStatic) {
+          buildProcedure(host, procedure);
+        }
+      }
+      for (Constructor constructor in node.constructors) {
+        buildConstructor(host, constructor);
+      }
+    }
+    // If the object is callable as a function, set up its call handler.
+    Member callHandler = hierarchy.getDispatchTarget(host, Names.call_);
+    if (callHandler != null) {
+      if (callHandler is Procedure && !callHandler.isAccessor) {
+        constraints.setLoadLocation(value, fieldNames.callHandlerField,
+            getTearOffVariable(host, callHandler));
+      } else {
+        // Generate `this.[call] = this.call.[call]` where [call] is the
+        // call handler field, corresponding to repeatedly reading "call".
+        var environment = new TypeEnvironment(this, host, callHandler);
+        int getter = getMemberGetter(host, callHandler);
+        constraints.setLoadLocation(value, fieldNames.callHandlerField,
+            environment.getLoad(getter, fieldNames.callHandlerField));
+      }
+    }
+  }
+
+  void buildStaticField(Field field) {
+    var environment = new Environment(this, null, field);
+    int initializer = field.initializer == null
+        ? nullNode
+        : new StatementBuilder(this, environment)
+            .buildExpression(field.initializer);
+    environment.addAssign(initializer, getSharedFieldVariable(field));
+  }
+
+  void buildProcedure(Class hostClass, Procedure node) {
+    if (node.isAbstract) return;
+    int host = hostClass == null ? null : getInstanceVariable(hostClass);
+    int function = getTearOffVariable(hostClass, node);
+    int returnVariable = getReturnVariable(hostClass, node);
+    var environment = new Environment(this, hostClass, node,
+        returnVariable: returnVariable, thisVariable: host);
+    buildFunctionNode(node.function, environment,
+        addTypeBasedSummary: node.isExternal, function: function);
+  }
+
+  int getDeclarationSiteFieldInitializer(Field field) {
+    if (field.initializer == null) return nullNode;
+    return declarationSiteFieldInitializer[field] ??=
+        _makeDeclarationSiteFieldInitializer(field);
+  }
+
+  int _makeDeclarationSiteFieldInitializer(Field field) {
+    final initializerEnvironment = new Environment(this, null, field);
+    return new StatementBuilder(this, initializerEnvironment)
+        .buildExpression(field.initializer);
+  }
+
+  void buildConstructor(Class hostClass, Constructor node) {
+    int host = getInstanceVariable(hostClass);
+    var environment =
+        new Environment(this, hostClass, node, thisVariable: host);
+    buildFunctionNode(node.function, environment);
+    InitializerBuilder builder = new InitializerBuilder(this, environment);
+    Set<Field> initializedFields = new Set<Field>();
+    for (Initializer initializer in node.initializers) {
+      builder.build(initializer);
+      if (initializer is FieldInitializer) {
+        initializedFields.add(initializer.field);
+      }
+    }
+    for (Field field in node.enclosingClass.mixin.fields) {
+      if (field.isInstanceMember) {
+        // Note: ensure the initializer is built even if it is not used.
+        int initializer = getDeclarationSiteFieldInitializer(field);
+        if (!initializedFields.contains(field)) {
+          int variable = getFieldVariable(hostClass, field);
+          environment.addAssign(initializer, variable);
+        }
+      }
+    }
+  }
+
+  /// Builds constraints to model the behavior of the given function.
+  ///
+  /// If the function is external, [addTypeBasedSummary] should be `true`;
+  /// its parameter and return type are then used to model its behavior instead
+  /// of the body.
+  ///
+  /// [function] should be a variable holding the function object itself, if
+  /// such an object exists (which is always the case except for constructors,
+  /// which currently do have function values).
+  void buildFunctionNode(FunctionNode node, Environment environment,
+      {int function, bool addTypeBasedSummary: false}) {
+    var expressionBuilder =
+        new StatementBuilder(this, environment).expressionBuilder;
+    int minArity = node.requiredParameterCount;
+    int maxArity = node.positionalParameters.length;
+    for (int i = 0; i < node.positionalParameters.length; ++i) {
+      var parameter = node.positionalParameters[i];
+      int variable = getParameterVariable(environment.host, parameter);
+      environment.localVariables[parameter] = variable;
+      if (function != null) {
+        for (int arity = minArity; arity <= maxArity; ++arity) {
+          if (i < arity) {
+            environment.addLoad(
+                function, getPositionalParameterField(arity, i), variable);
+          }
+        }
+      }
+      if (i >= node.requiredParameterCount) {
+        int parameterDefault = parameter.initializer == null
+            ? nullNode
+            : expressionBuilder.build(parameter.initializer);
+        environment.addAssign(parameterDefault, variable);
+      }
+      if (addTypeBasedSummary) {
+        buildContravariantType(parameter.type, environment, variable);
+      }
+    }
+    for (int i = 0; i < node.namedParameters.length; ++i) {
+      var parameter = node.namedParameters[i];
+      int variable = getParameterVariable(environment.host, parameter);
+      environment.localVariables[parameter] = variable;
+      if (function != null) {
+        for (int arity = minArity; arity <= maxArity; ++arity) {
+          environment.addLoad(function,
+              getNamedParameterField(arity, parameter.name), variable);
+        }
+      }
+      int parameterDefault = parameter.initializer == null
+          ? nullNode
+          : expressionBuilder.build(parameter.initializer);
+      environment.addAssign(parameterDefault, variable);
+      if (addTypeBasedSummary) {
+        buildContravariantType(parameter.type, environment, variable);
+      }
+    }
+    if (environment.returnVariable == null) {
+      environment.returnVariable = newVariable(node, 'return');
+      environment.addSink(
+          environment.returnVariable, getSharedReturnVariable(node));
+    } else {
+      visualizer?.annotateVariable(environment.returnVariable, node, 'return');
+    }
+    if (function != null) {
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        environment.addStore(
+            function, getReturnField(arity), environment.returnVariable);
+      }
+    }
+    if (addTypeBasedSummary) {
+      int returnFromType = buildCovariantType(node.returnType, environment);
+      environment.addAssign(returnFromType, environment.returnVariable);
+    } else if (node.body != null) {
+      Completion completes =
+          new StatementBuilder(this, environment).build(node.body);
+      if (completes == Completion.Maybe) {
+        // Null is returned when control falls over the end.
+        environment.addAssign(nullNode, environment.returnVariable);
+      }
+    }
+  }
+
+  /// Returns true if we can assume that externals treat the given types as
+  /// covariant.
+  ///
+  /// For example, if an external method returns a `List`, the values stored
+  /// in the list from user code are not considered escaping.
+  bool isAssumedCovariant(Class classNode) {
+    return classNode == coreTypes.listClass ||
+        classNode == coreTypes.mapClass ||
+        classNode == coreTypes.iterableClass ||
+        classNode == coreTypes.iteratorClass ||
+        classNode == coreTypes.futureClass ||
+        classNode == coreTypes.streamClass;
+  }
+
+  Set<String> _unsupportedNodes = new Set<String>();
+
+  int unsupported(Node node) {
+    if (verbose && _unsupportedNodes.add('${node.runtimeType}')) {
+      print('Unsupported: ${node.runtimeType}');
+    }
+    return dynamicNode;
+  }
+}
+
+/// Generates unique IDs for fields in the constraint system.
+///
+/// We use several fields in the constraint system that do not correspond to
+/// Dart fields.  A "field" in this context should be seen as a storage location
+/// that is specific to an instance.
+class FieldNames {
+  final TupleCanonicalizer _table = new TupleCanonicalizer();
+  static const int _TagName = 1;
+  static const int _TagPositionalParameter = 2;
+  static const int _TagNamedParameter = 3;
+  static const int _TagReturn = 4;
+  static const int _TagTypeParameter = 5;
+  static const int _TagCallHandler = 6;
+
+  /// Field mapping an object to the function value that should be invoked when
+  /// the object is called as a function.
+  ///
+  /// This is the equivalent of repeatedly reading the "call" property of an
+  /// object until a function value is found.
+  int callHandlerField;
+
+  FieldNames() {
+    callHandlerField = _table.get1(_TagCallHandler);
+  }
+
+  /// Field representing the value returned from a getter, passed into a setter,
+  /// or stored in a Dart field with the given name.
+  int getPropertyField(Name name) {
+    return _table.get2(_TagName, name);
+  }
+
+  /// Field representing the given positional parameter passed to a method
+  /// invoked with the given arity.
+  int getPositionalParameterField(int arity, int position) {
+    return _table.get3(_TagPositionalParameter, arity, position);
+  }
+
+  /// Field representing the given named parameter passed to a method invoked
+  /// with the given arity.
+  int getNamedParameterField(int arity, String name) {
+    return _table.get3(_TagNamedParameter, arity, name);
+  }
+
+  /// Field representing the return value of a method invoked the given arity.
+  int getReturnField(int arity) {
+    return _table.get2(_TagReturn, arity);
+  }
+
+  /// Field representing the values that would be checked against the given
+  /// type parameter in checked mode.
+  ///
+  /// The type-based modeling of externals uses this to handle types that
+  /// involve type variables.  Roughly speaking, we assume that a method whose
+  /// return type is a type variable T can return any value that was passed into
+  /// any parameter of type T.  In particular, this is used to model the
+  /// external backend storage in collection types.
+  ///
+  /// This field keeps track of the values that may flow into and out of a
+  /// type variable for a given instance.
+  int getTypeParameterField(TypeParameter parameter) {
+    return _table.get2(_TagTypeParameter, parameter);
+  }
+
+  int get length => _table.length;
+
+  String getDiagnosticNameOfField(int field) {
+    List<Object> tuple = _table.getFromIndex(field);
+    switch (tuple[0]) {
+      case _TagName:
+        return '${tuple[1]}';
+      case _TagPositionalParameter:
+        return 'pos(${tuple[1]},${tuple[2]})';
+      case _TagNamedParameter:
+        return 'named(${tuple[1]},${tuple[2]})';
+      case _TagReturn:
+        return 'return(${tuple[1]})';
+      case _TagTypeParameter:
+        return 'type-param(${tuple[1]})';
+      case _TagCallHandler:
+        return 'call-handler()';
+      default:
+        return '!error';
+    }
+  }
+}
+
+class TypeEnvironment {
+  final Builder builder;
+  final Class host;
+  final Member member;
+  int thisVariable;
+
+  ConstraintSystem get constraints => builder.constraints;
+  Visualizer get visualizer => builder.visualizer;
+
+  TypeEnvironment(this.builder, this.host, this.member, {this.thisVariable});
+
+  void addAssign(int source, int destination) {
+    constraints.addAssign(source, destination);
+    visualizer?.annotateAssign(source, destination, member);
+  }
+
+  int getJoin(int first, int second) {
+    // TODO(asgerf): Avoid redundant joins in common cases.
+    int joinPoint = constraints.newVariable();
+    addAssign(first, joinPoint);
+    addAssign(second, joinPoint);
+    return joinPoint;
+  }
+
+  int getLoad(int object, int field) {
+    int variable = builder._loads.lookup(object, field);
+    if (variable != null) return variable;
+    variable = constraints.newVariable();
+    constraints.addLoad(object, field, variable);
+    visualizer?.annotateLoad(object, field, variable, member);
+    builder._loads.put(variable);
+    return variable;
+  }
+
+  void addLoad(int object, int field, int destination) {
+    constraints.addLoad(object, field, destination);
+    visualizer?.annotateLoad(object, field, destination, member);
+  }
+
+  int getStore(int object, int field) {
+    int variable = builder._stores.lookup(object, field);
+    if (variable != null) return variable;
+    variable = constraints.newVariable();
+    constraints.addStore(object, field, variable);
+    visualizer?.annotateStore(object, field, variable, member);
+    builder._stores.put(variable);
+    return variable;
+  }
+
+  void addStore(int object, int field, int source) {
+    addAssign(source, getStore(object, field));
+  }
+
+  void addSink(int source, int sink) {
+    constraints.addSink(source, sink);
+    visualizer?.annotateSink(source, sink, member);
+  }
+}
+
+class Environment extends TypeEnvironment {
+  final Map<VariableDeclaration, int> localVariables;
+  int returnVariable;
+
+  Environment(Builder builder, Class host, Member member,
+      {int thisVariable, this.returnVariable})
+      : localVariables = <VariableDeclaration, int>{},
+        super(builder, host, member, thisVariable: thisVariable);
+
+  Environment.inner(Environment outer, {this.returnVariable})
+      : localVariables = outer.localVariables,
+        super(outer.builder, outer.host, outer.member,
+            thisVariable: outer.thisVariable);
+
+  int getVariable(VariableDeclaration variable) {
+    return localVariables[variable] ??= builder.newVariable(variable);
+  }
+}
+
+class ExpressionBuilder extends ExpressionVisitor<int> {
+  final Builder builder;
+  final Environment environment;
+  final StatementBuilder statementBuilder;
+
+  ConstraintSystem get constraints => builder.constraints;
+  Visualizer get visualizer => builder.visualizer;
+  FieldNames get fieldNames => builder.fieldNames;
+
+  ExpressionBuilder(this.builder, this.statementBuilder, this.environment);
+
+  int build(Expression node) {
+    int variable = node.accept(this);
+    visualizer?.annotateVariable(variable, node);
+    return variable;
+  }
+
+  int unsupported(Expression node) {
+    return builder.unsupported(node);
+  }
+
+  defaultExpression(Expression node) {
+    return unsupported(node);
+  }
+
+  int visitInvalidExpression(InvalidExpression node) {
+    return builder.bottomNode;
+  }
+
+  int visitVariableGet(VariableGet node) {
+    return environment.getVariable(node.variable);
+  }
+
+  int visitVariableSet(VariableSet node) {
+    int rightHandSide = build(node.value);
+    int variable = environment.getVariable(node.variable);
+    environment.addAssign(rightHandSide, variable);
+    return rightHandSide;
+  }
+
+  int visitPropertyGet(PropertyGet node) {
+    if (node.receiver is ThisExpression) {
+      Class host = environment.host;
+      Member target = builder.hierarchy.getDispatchTarget(host, node.name);
+      int source = builder.getMemberGetter(host, target);
+      return source == null ? builder.bottomNode : source;
+    }
+    int object = build(node.receiver);
+    int field = fieldNames.getPropertyField(node.name);
+    return environment.getLoad(object, field);
+  }
+
+  int visitPropertySet(PropertySet node) {
+    int object = build(node.receiver);
+    int rightHandSide = build(node.value);
+    if (node.receiver is ThisExpression) {
+      Class host = environment.host;
+      Member target =
+          builder.hierarchy.getDispatchTarget(host, node.name, setter: true);
+      int destination = builder.getMemberSetter(host, target);
+      if (destination != null) {
+        environment.addAssign(rightHandSide, destination);
+      }
+      return rightHandSide;
+    }
+    int field = fieldNames.getPropertyField(node.name);
+    environment.addStore(object, field, rightHandSide);
+    return rightHandSide;
+  }
+
+  int visitDirectPropertyGet(DirectPropertyGet node) {
+    return builder.getMemberGetter(environment.host, node.target);
+  }
+
+  int visitDirectPropertySet(DirectPropertySet node) {
+    int rightHandSide = build(node.value);
+    int destination = builder.getMemberSetter(environment.host, node.target);
+    if (destination != null) {
+      environment.addAssign(rightHandSide, destination);
+    }
+    return rightHandSide;
+  }
+
+  int visitSuperPropertyGet(SuperPropertyGet node) {
+    return unsupported(node);
+  }
+
+  int visitSuperPropertySet(SuperPropertySet node) {
+    build(node.value);
+    return unsupported(node);
+  }
+
+  int visitStaticGet(StaticGet node) {
+    return builder.getMemberGetter(null, node.target);
+  }
+
+  int visitStaticSet(StaticSet node) {
+    int rightHandSide = build(node.value);
+    int destination = builder.getMemberSetter(null, node.target);
+    assert(destination != null); // Static accessors must be valid.
+    environment.addAssign(rightHandSide, destination);
+    return rightHandSide;
+  }
+
+  int visitMethodInvocation(MethodInvocation node) {
+    // Resolve calls on 'this' directly.
+    if (node.receiver is ThisExpression) {
+      Class host = environment.host;
+      Member target = builder.hierarchy.getDispatchTarget(host, node.name);
+      if (target is Procedure && !target.isAccessor) {
+        FunctionNode function = target.function;
+        passArgumentsToFunction(node.arguments, host, function);
+        return builder.getReturnVariable(host, target);
+      }
+    }
+    // Dispatch call dynamically.
+    int receiver = build(node.receiver);
+    int methodProperty = builder.getPropertyField(node.name);
+    int function = node.name.name == 'call'
+        ? receiver
+        : environment.getLoad(receiver, methodProperty);
+    // We have to dispatch through any number of 'call' getters to get to
+    // the actual function.  The 'call handler' field unfolds all the 'call'
+    // getters and refers directly to the actual function (if it exists).
+    // TODO(asgerf): When we have strong mode types, skip the 'call handler'
+    //     load if the static type system resolves the target to a method.
+    //     It is only needed for getters, fields, and untyped calls.
+    int handler = environment.getLoad(function, fieldNames.callHandlerField);
+    visualizer?.annotateVariable(function, node, 'function');
+    visualizer?.annotateVariable(handler, node, 'call handler');
+    int arity = node.arguments.positional.length;
+    for (int i = 0; i < node.arguments.positional.length; ++i) {
+      int field = builder.getPositionalParameterField(arity, i);
+      int argument = build(node.arguments.positional[i]);
+      environment.addStore(handler, field, argument);
+    }
+    for (int i = 0; i < node.arguments.named.length; ++i) {
+      NamedExpression namedNode = node.arguments.named[i];
+      int field = builder.getNamedParameterField(arity, namedNode.name);
+      int argument = build(namedNode.value);
+      environment.addStore(handler, field, argument);
+    }
+    return environment.getLoad(handler, builder.getReturnField(arity));
+  }
+
+  void passArgumentsToFunction(
+      Arguments node, Class host, FunctionNode function) {
+    // TODO(asgerf): Check that arity matches (although mismatches are rare).
+    for (int i = 0; i < node.positional.length; ++i) {
+      int argument = build(node.positional[i]);
+      if (i < function.positionalParameters.length) {
+        int parameter = builder.getParameterVariable(
+            host, function.positionalParameters[i]);
+        environment.addAssign(argument, parameter);
+      }
+    }
+    for (int i = 0; i < node.named.length; ++i) {
+      NamedExpression namedNode = node.named[i];
+      int argument = build(namedNode.value);
+      // TODO(asgerf): Avoid the slow lookup for named parameters.
+      for (int j = 0; j < function.namedParameters.length; ++j) {
+        var namedParameter = function.namedParameters[j];
+        if (namedParameter.name == namedNode.name) {
+          int parameter = builder.getParameterVariable(host, namedParameter);
+          environment.addAssign(argument, parameter);
+          break;
+        }
+      }
+    }
+  }
+
+  int visitDirectMethodInvocation(DirectMethodInvocation node) {
+    // TODO(asgerf): Support cases where the receiver is not 'this'.
+    passArgumentsToFunction(
+        node.arguments, environment.host, node.target.function);
+    return builder.getReturnVariable(environment.host, node.target);
+  }
+
+  int visitSuperMethodInvocation(SuperMethodInvocation node) {
+    return unsupported(node);
+  }
+
+  void passArgumentsNowhere(Arguments node) {
+    for (int i = 0; i < node.positional.length; ++i) {
+      build(node.positional[i]);
+    }
+    for (int i = 0; i < node.named.length; ++i) {
+      build(node.named[i].value);
+    }
+  }
+
+  int visitStaticInvocation(StaticInvocation node) {
+    if (node.target == builder.identicalFunction) {
+      // Ignore calls to identical() as they cause a lot of spurious escape.
+      passArgumentsNowhere(node.arguments);
+      return builder.boolNode;
+    }
+    passArgumentsToFunction(node.arguments, null, node.target.function);
+    return builder.getReturnVariable(null, node.target);
+  }
+
+  int visitConstructorInvocation(ConstructorInvocation node) {
+    Class host = node.target.enclosingClass;
+    passArgumentsToFunction(node.arguments, host, node.target.function);
+    return builder.getInstanceVariable(host);
+  }
+
+  int visitNot(Not node) {
+    build(node.operand);
+    return builder.boolNode;
+  }
+
+  int visitLogicalExpression(LogicalExpression node) {
+    build(node.left);
+    build(node.right);
+    return builder.boolNode;
+  }
+
+  int visitConditionalExpression(ConditionalExpression node) {
+    build(node.condition);
+    int then = build(node.then);
+    int otherwise = build(node.otherwise);
+    return environment.getJoin(then, otherwise);
+  }
+
+  int visitStringConcatenation(StringConcatenation node) {
+    for (int i = 0; i < node.expressions.length; ++i) {
+      build(node.expressions[i]);
+    }
+    return builder.stringNode;
+  }
+
+  int visitIsExpression(IsExpression node) {
+    build(node.operand);
+    return builder.boolNode;
+  }
+
+  int visitAsExpression(AsExpression node) {
+    return build(node.operand);
+  }
+
+  int visitSymbolLiteral(SymbolLiteral node) {
+    return builder.symbolNode;
+  }
+
+  int visitTypeLiteral(TypeLiteral node) {
+    return builder.typeNode;
+  }
+
+  int visitThisExpression(ThisExpression node) {
+    return environment.thisVariable;
+  }
+
+  int visitRethrow(Rethrow node) {
+    return builder.bottomNode;
+  }
+
+  int visitThrow(Throw node) {
+    build(node.expression);
+    return builder.bottomNode;
+  }
+
+  int visitListLiteral(ListLiteral node) {
+    var object = builder.listNode;
+    TypeParameter parameter = builder.coreTypes.listClass.typeParameters.single;
+    int field = fieldNames.getTypeParameterField(parameter);
+    for (int i = 0; i < node.expressions.length; ++i) {
+      int content = build(node.expressions[i]);
+      environment.addStore(object, field, content);
+    }
+    return object;
+  }
+
+  int visitMapLiteral(MapLiteral node) {
+    var object = builder.mapNode;
+    List<TypeParameter> parameters = builder.coreTypes.mapClass.typeParameters;
+    int keys = fieldNames.getTypeParameterField(parameters[0]);
+    int values = fieldNames.getTypeParameterField(parameters[1]);
+    for (int i = 0; i < node.entries.length; ++i) {
+      var entry = node.entries[i];
+      environment.addStore(object, keys, build(entry.key));
+      environment.addStore(object, values, build(entry.value));
+    }
+    return object;
+  }
+
+  int visitAwaitExpression(AwaitExpression node) {
+    return unsupported(node);
+  }
+
+  int visitFunctionExpression(FunctionExpression node) {
+    return buildInnerFunction(node.function);
+  }
+
+  int visitStringLiteral(StringLiteral node) {
+    return builder.stringNode;
+  }
+
+  int visitIntLiteral(IntLiteral node) {
+    return builder.intNode;
+  }
+
+  int visitDoubleLiteral(DoubleLiteral node) {
+    return builder.doubleNode;
+  }
+
+  int visitBoolLiteral(BoolLiteral node) {
+    return builder.boolNode;
+  }
+
+  int visitNullLiteral(NullLiteral node) {
+    return builder.nullNode;
+  }
+
+  int visitLet(Let node) {
+    environment.localVariables[node.variable] =
+        build(node.variable.initializer);
+    return build(node.body);
+  }
+
+  int buildInnerFunction(FunctionNode node, {VariableDeclaration self}) {
+    int variable = builder.newFunction(node);
+    if (self != null) {
+      assert(!environment.localVariables.containsKey(self));
+      environment.localVariables[self] = variable;
+    }
+    Environment inner = new Environment.inner(environment);
+    builder.buildFunctionNode(node, inner, function: variable);
+    return variable;
+  }
+}
+
+/// Indicates whether a statement can complete normally.
+enum Completion {
+  /// The statement might complete normally.
+  Maybe,
+
+  /// The statement never completes normally, because it throws, returns,
+  /// breaks, loops forever, etc.
+  Never,
+}
+
+Completion neverCompleteIf(bool condition) {
+  return condition ? Completion.Never : Completion.Maybe;
+}
+
+Completion completeIfBoth(Completion first, Completion second) {
+  return first == Completion.Maybe && second == Completion.Maybe
+      ? Completion.Maybe
+      : Completion.Never;
+}
+
+Completion completeIfEither(Completion first, Completion second) {
+  return first == Completion.Maybe || second == Completion.Maybe
+      ? Completion.Maybe
+      : Completion.Never;
+}
+
+bool _isTrueConstant(Expression node) {
+  return node is BoolLiteral && node.value == true;
+}
+
+bool _isThrowing(Expression node) {
+  return node is Throw || node is Rethrow;
+}
+
+/// Translates a statement to constraints.
+///
+/// The visit methods return a [Completion] indicating if the statement can
+/// complete normally.  This is used to check if null can be returned due to
+/// control falling over the end of the method.
+class StatementBuilder extends StatementVisitor<Completion> {
+  final Builder builder;
+  final Environment environment;
+  ExpressionBuilder expressionBuilder;
+
+  ConstraintSystem get constraints => builder.constraints;
+  Visualizer get visualizer => builder.visualizer;
+  FieldNames get names => builder.fieldNames;
+
+  StatementBuilder(this.builder, this.environment) {
+    expressionBuilder = new ExpressionBuilder(builder, this, environment);
+  }
+
+  Completion build(Statement node) => node.accept(this);
+
+  Completion buildOptional(Statement node) {
+    return node != null ? node.accept(this) : Completion.Maybe;
+  }
+
+  int buildExpression(Expression node) {
+    return expressionBuilder.build(node);
+  }
+
+  void unsupported(Statement node) {
+    builder.unsupported(node);
+  }
+
+  Completion visitInvalidStatement(InvalidStatement node) => Completion.Never;
+
+  visitExpressionStatement(ExpressionStatement node) {
+    buildExpression(node.expression);
+    return neverCompleteIf(_isThrowing(node.expression));
+  }
+
+  visitBlock(Block node) {
+    for (int i = 0; i < node.statements.length; ++i) {
+      if (build(node.statements[i]) == Completion.Never) {
+        return Completion.Never;
+      }
+    }
+    return Completion.Maybe;
+  }
+
+  visitEmptyStatement(EmptyStatement node) => Completion.Maybe;
+
+  visitAssertStatement(AssertStatement node) {
+    unsupported(node);
+    return Completion.Maybe;
+  }
+
+  visitLabeledStatement(LabeledStatement node) {
+    build(node.body);
+    // We don't track reachability of breaks in the body, so just assume we
+    // might hit a break.
+    return Completion.Maybe;
+  }
+
+  visitBreakStatement(BreakStatement node) => Completion.Never;
+
+  visitWhileStatement(WhileStatement node) {
+    buildExpression(node.condition);
+    build(node.body);
+    return neverCompleteIf(_isTrueConstant(node.condition));
+  }
+
+  visitDoStatement(DoStatement node) {
+    build(node.body);
+    buildExpression(node.condition);
+    return neverCompleteIf(_isTrueConstant(node.condition));
+  }
+
+  visitForStatement(ForStatement node) {
+    for (int i = 0; i < node.variables.length; ++i) {
+      build(node.variables[i]);
+    }
+    if (node.condition != null) {
+      buildExpression(node.condition);
+    }
+    for (int i = 0; i < node.updates.length; ++i) {
+      buildExpression(node.updates[i]);
+    }
+    build(node.body);
+    return neverCompleteIf(_isTrueConstant(node.condition));
+  }
+
+  visitForInStatement(ForInStatement node) {
+    int iterable = buildExpression(node.iterable);
+    int iterator = environment.getLoad(iterable, builder.iteratorField);
+    int current = environment.getLoad(iterator, builder.currentField);
+    int variable = environment.getVariable(node.variable);
+    environment.addAssign(current, variable);
+    build(node.body);
+    return Completion.Maybe;
+  }
+
+  visitSwitchStatement(SwitchStatement node) {
+    buildExpression(node.expression);
+    Completion lastCanComplete = Completion.Maybe;
+    for (int i = 0; i < node.cases.length; ++i) {
+      // There is no need to visit the expression since constants cannot
+      // have side effects.
+      // Note that only the last case can actually fall out of the switch,
+      // as the others will throw an exception if they fall through.
+      // Also note that breaks from the switch have been desugared to breaks
+      // to a [LabeledStatement].
+      lastCanComplete = build(node.cases[i].body);
+    }
+    return lastCanComplete;
+  }
+
+  visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    return Completion.Never;
+  }
+
+  visitIfStatement(IfStatement node) {
+    buildExpression(node.condition);
+    Completion thenCompletes = build(node.then);
+    Completion elseCompletes = buildOptional(node.otherwise);
+    return completeIfEither(thenCompletes, elseCompletes);
+  }
+
+  visitReturnStatement(ReturnStatement node) {
+    if (node.expression != null) {
+      int returned = buildExpression(node.expression);
+      environment.addAssign(returned, environment.returnVariable);
+    }
+    return Completion.Never;
+  }
+
+  visitTryCatch(TryCatch node) {
+    Completion bodyCompletes = build(node.body);
+    Completion catchCompletes = Completion.Never;
+    for (int i = 0; i < node.catches.length; ++i) {
+      Catch catchNode = node.catches[i];
+      if (catchNode.exception != null) {
+        environment.localVariables[catchNode.exception] = builder.dynamicNode;
+      }
+      if (catchNode.stackTrace != null) {
+        environment.localVariables[catchNode.stackTrace] = builder.dynamicNode;
+      }
+      if (build(catchNode.body) == Completion.Maybe) {
+        catchCompletes = Completion.Maybe;
+      }
+    }
+    return completeIfEither(bodyCompletes, catchCompletes);
+  }
+
+  visitTryFinally(TryFinally node) {
+    Completion bodyCompletes = build(node.body);
+    Completion finalizerCompletes = build(node.finalizer);
+    return completeIfBoth(bodyCompletes, finalizerCompletes);
+  }
+
+  visitYieldStatement(YieldStatement node) {
+    unsupported(node);
+    return Completion.Maybe;
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    int initializer = node.initializer == null
+        ? builder.nullNode
+        : buildExpression(node.initializer);
+    int variable = environment.getVariable(node);
+    environment.addAssign(initializer, variable);
+    return neverCompleteIf(_isThrowing(node.initializer));
+  }
+
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    expressionBuilder.buildInnerFunction(node.function, self: node.variable);
+    return Completion.Maybe;
+  }
+}
+
+class InitializerBuilder extends InitializerVisitor<Null> {
+  final Builder builder;
+  final Environment environment;
+  ExpressionBuilder expressionBuilder;
+
+  FieldNames get fieldNames => builder.fieldNames;
+
+  InitializerBuilder(this.builder, this.environment) {
+    expressionBuilder =
+        new StatementBuilder(builder, environment).expressionBuilder;
+  }
+
+  void build(Initializer node) {
+    node.accept(this);
+  }
+
+  int buildExpression(Expression node) {
+    return expressionBuilder.build(node);
+  }
+
+  visitInvalidInitializer(InvalidInitializer node) {}
+
+  visitFieldInitializer(FieldInitializer node) {
+    int fieldVariable = builder.getFieldVariable(environment.host, node.field);
+    int rightHandSide = buildExpression(node.value);
+    environment.addAssign(rightHandSide, fieldVariable);
+  }
+
+  visitSuperInitializer(SuperInitializer node) {
+    expressionBuilder.passArgumentsToFunction(
+        node.arguments, environment.host, node.target.function);
+  }
+
+  visitRedirectingInitializer(RedirectingInitializer node) {
+    expressionBuilder.passArgumentsToFunction(
+        node.arguments, environment.host, node.target.function);
+  }
+
+  visitLocalInitializer(LocalInitializer node) {
+    environment.localVariables[node.variable] =
+        buildExpression(node.variable.initializer);
+  }
+}
+
+class Names {
+  static final Name current = new Name('current');
+  static final Name iterator = new Name('iterator');
+  static final Name then = new Name('then');
+  static final Name call_ = new Name('call');
+}
+
+/// Returns a variable with the possible values of a given type, as provided
+/// by external code.
+class CovariantExternalTypeVisitor extends DartTypeVisitor<int> {
+  final Builder builder;
+  final TypeEnvironment environment;
+
+  FieldNames get fieldNames => builder.fieldNames;
+
+  CovariantExternalTypeVisitor(this.builder, this.environment);
+
+  void visitContravariant(DartType type, int input) {
+    return new ContravariantExternalTypeVisitor(builder, environment, input)
+        .visit(type);
+  }
+
+  int visit(DartType type) => type.accept(this);
+
+  int visitInvalidType(InvalidType node) {
+    return builder.bottomNode;
+  }
+
+  int visitDynamicType(DynamicType node) {
+    return builder.dynamicNode;
+  }
+
+  int visitVoidType(VoidType node) {
+    return builder.nullNode;
+  }
+
+  int visitInterfaceType(InterfaceType node) {
+    int object = builder.getExternalInstanceVariable(node.classNode);
+    for (int i = 0; i < node.typeArguments.length; ++i) {
+      int field =
+          fieldNames.getTypeParameterField(node.classNode.typeParameters[i]);
+      int outputValue = visit(node.typeArguments[i]);
+      environment.addStore(object, field, outputValue);
+      if (!builder.isAssumedCovariant(node.classNode)) {
+        int userValue = environment.getLoad(object, field);
+        visitContravariant(node.typeArguments[i], userValue);
+      }
+    }
+    return object;
+  }
+
+  int visitTypeParameterType(TypeParameterType node) {
+    if (node.parameter.parent is Class) {
+      assert(environment.thisVariable != null);
+      return environment.getLoad(environment.thisVariable,
+          fieldNames.getTypeParameterField(node.parameter));
+    } else {
+      return builder.getFunctionTypeParameterVariable(node.parameter);
+    }
+  }
+
+  int visitFunctionType(FunctionType node) {
+    // TODO: Handle arity range.
+    int arity = node.positionalParameters.length;
+    int function = builder.functionValueNode;
+    for (int i = 0; i < node.positionalParameters.length; ++i) {
+      int field = fieldNames.getPositionalParameterField(arity, i);
+      int argument = environment.getLoad(function, field);
+      visitContravariant(node.positionalParameters[i], argument);
+    }
+    for (int i = 0; i < node.namedParameters.length; ++i) {
+      var parameter = node.namedParameters[i];
+      int field = fieldNames.getNamedParameterField(arity, parameter.name);
+      int argument = environment.getLoad(function, field);
+      visitContravariant(parameter.type, argument);
+    }
+    int returnVariable = visit(node.returnType);
+    environment.addStore(
+        function, fieldNames.getReturnField(arity), returnVariable);
+    return function;
+  }
+
+  /// Equivalent to visiting the FunctionType for the given function.
+  int buildFunctionNode(FunctionNode node) {
+    int minArity = node.requiredParameterCount;
+    int maxArity = node.positionalParameters.length;
+    Member member = node.parent is Member ? node.parent : null;
+    int function = builder.newFunction(node, member);
+    for (int arity = minArity; arity <= maxArity; ++arity) {
+      for (int i = 0; i < arity; ++i) {
+        int field = fieldNames.getPositionalParameterField(arity, i);
+        int argument = environment.getLoad(function, field);
+        visitContravariant(node.positionalParameters[i].type, argument);
+      }
+    }
+    for (int i = 0; i < node.namedParameters.length; ++i) {
+      VariableDeclaration variable = node.namedParameters[i];
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        int field = fieldNames.getNamedParameterField(arity, variable.name);
+        int argument = environment.getLoad(function, field);
+        visitContravariant(variable.type, argument);
+      }
+    }
+    int returnVariable = visit(node.returnType);
+    for (int arity = minArity; arity <= maxArity; ++arity) {
+      environment.addStore(
+          function, fieldNames.getReturnField(arity), returnVariable);
+    }
+    return function;
+  }
+}
+
+/// Generates constraints to model the behavior of a value escaping into
+/// external code through a given type.
+class ContravariantExternalTypeVisitor extends DartTypeVisitor<Null> {
+  final Builder builder;
+  final TypeEnvironment environment;
+  final int input;
+
+  FieldNames get fieldNames => builder.fieldNames;
+  ConstraintSystem get constraints => builder.constraints;
+
+  ContravariantExternalTypeVisitor(this.builder, this.environment, this.input);
+
+  void visit(DartType type) {
+    type.accept(this);
+  }
+
+  void visitContravariant(DartType type, int input) {
+    return new ContravariantExternalTypeVisitor(builder, environment, input)
+        .visit(type);
+  }
+
+  int visitCovariant(DartType type) {
+    return new CovariantExternalTypeVisitor(builder, environment).visit(type);
+  }
+
+  visitInvalidType(InvalidType node) {}
+
+  visitDynamicType(DynamicType node) {}
+
+  visitVoidType(VoidType node) {}
+
+  visitInterfaceType(InterfaceType node) {
+    int escapePoint = builder.getInterfaceEscapeVariable(node.classNode);
+    environment.addAssign(input, escapePoint);
+  }
+
+  visitTypeParameterType(TypeParameterType node) {
+    if (node.parameter.parent is Class) {
+      assert(environment.thisVariable != null);
+      environment.addStore(environment.thisVariable,
+          fieldNames.getTypeParameterField(node.parameter), input);
+    } else {
+      environment.addAssign(
+          input, builder.getFunctionTypeParameterVariable(node.parameter));
+    }
+  }
+
+  visitFunctionType(FunctionType node) {
+    int minArity = node.requiredParameterCount;
+    int maxArity = node.positionalParameters.length;
+    for (int i = 0; i < node.positionalParameters.length; ++i) {
+      int argument = visitCovariant(node.positionalParameters[i]);
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        int field = fieldNames.getPositionalParameterField(arity, i);
+        environment.addStore(input, field, argument);
+      }
+    }
+    for (var parameter in node.namedParameters) {
+      int argument = visitCovariant(parameter.type);
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        int field = fieldNames.getNamedParameterField(arity, parameter.name);
+        environment.addStore(input, field, argument);
+      }
+    }
+    for (int arity = minArity; arity <= maxArity; ++arity) {
+      int returnLocation =
+          environment.getLoad(input, fieldNames.getReturnField(arity));
+      visitContravariant(node.returnType, returnLocation);
+    }
+  }
+
+  /// Equivalent to visiting the FunctionType for the given function.
+  void buildFunctionNode(FunctionNode node) {
+    int minArity = node.requiredParameterCount;
+    int maxArity = node.positionalParameters.length;
+    for (int arity = minArity; arity <= maxArity; ++arity) {
+      for (int i = 0; i < arity; ++i) {
+        int argument = visitCovariant(node.positionalParameters[i].type);
+        int field = fieldNames.getPositionalParameterField(arity, i);
+        environment.addStore(input, field, argument);
+      }
+    }
+    for (int i = 0; i < node.namedParameters.length; ++i) {
+      VariableDeclaration variable = node.namedParameters[i];
+      int argument = visitCovariant(variable.type);
+      for (int arity = minArity; arity <= maxArity; ++arity) {
+        int field = fieldNames.getNamedParameterField(arity, variable.name);
+        environment.addStore(input, field, argument);
+      }
+    }
+    for (int arity = minArity; arity <= maxArity; ++arity) {
+      int returnLocation =
+          environment.getLoad(input, fieldNames.getReturnField(arity));
+      visitContravariant(node.returnType, returnLocation);
+    }
+  }
+}
diff --git a/pkg/kernel/lib/type_propagation/canonicalizer.dart b/pkg/kernel/lib/type_propagation/canonicalizer.dart
new file mode 100644
index 0000000..420bd01
--- /dev/null
+++ b/pkg/kernel/lib/type_propagation/canonicalizer.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.canonicalizer;
+
+import 'dart:collection';
+
+/// Generates unique consecutive integer IDs for tuples of variable length.
+class TupleCanonicalizer {
+  final HashMap<List<Object>, int> _table = new HashMap<List<Object>, int>(
+      equals: _contentEquals, hashCode: _contentHashCode);
+  final List<List<Object>> _canonicalList = <List<Object>>[];
+  List<Object> _buffer = [];
+
+  void _push(Object value) {
+    _buffer.add(value);
+  }
+
+  int _finish() {
+    int index = _table[_buffer];
+    if (index == null) {
+      index = _canonicalList.length;
+      _canonicalList.add(_buffer);
+      _table[_buffer] = index;
+      _buffer = [];
+    } else {
+      // The item already existed.  Reuse the buffer object for the next query.
+      _buffer.clear();
+    }
+    return index;
+  }
+
+  /// Generate or get the ID for a "unary tuple".
+  int get1(Object first) {
+    _push(first);
+    return _finish();
+  }
+
+  /// Generate or get the ID for a pair.
+  int get2(Object first, Object second) {
+    _push(first);
+    _push(second);
+    return _finish();
+  }
+
+  /// Generate or get the ID for a triple.
+  int get3(Object first, Object second, Object third) {
+    _push(first);
+    _push(second);
+    _push(third);
+    return _finish();
+  }
+
+  List<Object> getFromIndex(int index) {
+    return _canonicalList[index];
+  }
+
+  int get length => _canonicalList.length;
+
+  static bool _contentEquals(List<Object> first, List<Object> second) {
+    if (first.length != second.length) return false;
+    for (int i = 0; i < first.length; ++i) {
+      if (first[i] != second[i]) return false;
+    }
+    return true;
+  }
+
+  static int _contentHashCode(List<Object> list) {
+    int hash = 0;
+    for (int i = 0; i < list.length; ++i) {
+      hash = (hash * 31 + hash ^ list[i].hashCode) & 0x3fffffff;
+    }
+    return hash;
+  }
+}
+
+/// Maps uint31 pairs to values of type [T].
+class Uint31PairMap<T> {
+  final HashMap<int, T> _table = new HashMap<int, T>(hashCode: _bigintHash);
+  int _key;
+
+  /// Returns the value associated with the given pair, or `null` if no value
+  /// is associated with the pair.
+  ///
+  /// This association can be changed using a subsequent call to [put].
+  T lookup(int x, int y) {
+    assert(x >= 0 && x >> 31 == 0);
+    assert(y >= 0 && y >> 31 == 0);
+    int key = (x << 31) + y;
+    _key = key;
+    return _table[key];
+  }
+
+  /// Associates [value] with the pair previously queried using [lookup].
+  void put(T value) {
+    _table[_key] = value;
+  }
+
+  Iterable<T> get values => _table.values;
+
+  static int _bigintHash(int bigint) {
+  	int x = 0x3fffffff & (bigint >> 31);
+  	int y = 0x3fffffff & bigint;
+    int hash = 0x3fffffff & (x * 1367);
+    hash = 0x3fffffff & (y * 31 + hash ^ y);
+    hash = 0x3fffffff & ((x ^ y) * 31 + hash ^ y);
+    return hash;
+  }
+}
diff --git a/pkg/kernel/lib/type_propagation/constraints.dart b/pkg/kernel/lib/type_propagation/constraints.dart
new file mode 100644
index 0000000..412b43a
--- /dev/null
+++ b/pkg/kernel/lib/type_propagation/constraints.dart
@@ -0,0 +1,175 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.constraints;
+
+import 'canonicalizer.dart';
+
+/// A system of constraints representing dataflow in a Dart program.
+///
+/// The system consists of variables, values, and lattice points, as well as
+/// constraints that express the relationships between these.
+///
+/// Internally, variables, values, and lattice points are represented as
+/// integers starting at 0.  The namespaces for these are overlapping; there is
+/// no runtime tag to distinguish variables from values from lattice points, so
+/// great care must be taken not to mix them up.
+///
+/// Externally, the methods on [ConstraintSystem] apply a layer of sanity checks
+/// using the sign bit to distinguish values from variables and lattice points.
+/// Users should therefore access the constraint system using either its methods
+/// or its fields, but not both.
+///
+/// The constraint system has the traditional Andersen-style constraints:
+///
+///  Allocate: `x = value`
+///  Assign:   `x = y`
+///  Store:    `x.f = y`
+///  Load:     `x = y.f`
+///
+/// Additionally, there is a "sink" constraint which acts as an assignment but
+/// only after the fixed-point has been found.
+///
+/// Lattice points represent sets of values.  All values must belong to one
+/// particular lattice point and are implicitly contained in the value set of
+/// all lattice points above it.
+///
+/// A solution to the constraint system is an assignment from each variable to
+/// a lattice point containing all values that may flow into the variable.
+class ConstraintSystem {
+  int _numberOfVariables = 0;
+  final List<int> assignments = <int>[];
+  final List<int> sinks = <int>[];
+  final List<int> loads = <int>[];
+  final List<int> stores = <int>[];
+  final List<int> allocations = <int>[];
+  final List<int> latticePointOfValue = <int>[];
+  final Uint31PairMap<int> storeLocations = new Uint31PairMap<int>();
+  final Uint31PairMap<int> loadLocations = new Uint31PairMap<int>();
+
+  /// The same as [storeLocations], for traversal instead of fast lookup.
+  final List<int> storeLocationList = <int>[];
+
+  /// The same as [loadLocations], for traversal instead of fast lookup.
+  final List<int> loadLocationList = <int>[];
+  final List<List<int>> parentsOfLatticePoint = <List<int>>[];
+  final List<int> bitmaskInputs = <int>[];
+
+  int get numberOfVariables => _numberOfVariables;
+  int get numberOfValues => latticePointOfValue.length;
+  int get numberOfLatticePoints => parentsOfLatticePoint.length;
+
+  int newVariable() {
+    return _numberOfVariables++;
+  }
+
+  /// Creates a new lattice point, initially representing or containing no
+  /// values.
+  ///
+  /// Values can be added to the lattice point passing it to [newValue] or by
+  /// creating lattice points below it and adding values to those.
+  ///
+  /// The first lattice point created must be an ancestor of all lattice points.
+  int newLatticePoint(List<int> supers) {
+    assert(supers != null);
+    int id = parentsOfLatticePoint.length;
+    parentsOfLatticePoint.add(supers);
+    return id;
+  }
+
+  /// Creates a new value as a member of the given [latticePoint], with the
+  /// given mutable fields.
+  ///
+  /// The lattice point should be specific to this value or the solver will not
+  /// be able to distinguish it from other values in the same lattice point.
+  ///
+  /// To help debugging, this method returns the the negated ID for the value.
+  /// Every method on the constraint system checks that arguments representing
+  /// values are non-positive in order to catch accidental bugs where a
+  /// variable or lattice point was accidentally used in place of a value.
+  int newValue(int latticePoint) {
+    assert(0 <= latticePoint && latticePoint < numberOfLatticePoints);
+    int valueId = latticePointOfValue.length;
+    latticePointOfValue.add(latticePoint);
+    return -valueId;
+  }
+
+  /// Sets [variable] as the storage location for values dynamically stored
+  /// into [field] on [value].
+  ///
+  /// Any store constraint where [value] can reach the receiver will propagate
+  /// the stored value into [variable].
+  void setStoreLocation(int value, int field, int variable) {
+    assert(value <= 0);
+    assert(field >= 0);
+    assert(variable >= 0);
+    value = -value;
+    int location = storeLocations.lookup(value, field);
+    assert(location == null);
+    storeLocations.put(variable);
+    storeLocationList..add(value)..add(field)..add(variable);
+  }
+
+  /// Sets [variable] as the storage location for values dynamically loaded
+  /// from [field] on [value].
+  ///
+  /// Any load constraint where [value] can reach the receiver object will
+  /// propagate the value from [variable] into the result of the load.
+  void setLoadLocation(int value, int field, int variable) {
+    assert(value <= 0);
+    assert(field >= 0);
+    assert(variable >= 0);
+    value = -value;
+    int location = loadLocations.lookup(value, field);
+    assert(location == null);
+    loadLocations.put(variable);
+    loadLocationList..add(value)..add(field)..add(variable);
+  }
+
+  void addAllocation(int value, int destination) {
+    assert(value <= 0);
+    assert(destination >= 0);
+    value = -value;
+    allocations..add(value)..add(destination);
+  }
+
+  void addBitmaskInput(int bitmask, int destination) {
+    bitmaskInputs..add(bitmask)..add(destination);
+  }
+
+  void addAssign(int source, int destination) {
+    assert(source >= 0);
+    assert(destination >= 0);
+    assignments..add(source)..add(destination);
+  }
+
+  void addLoad(int object, int field, int destination) {
+    assert(object >= 0);
+    assert(field >= 0);
+    assert(destination >= 0);
+    loads..add(object)..add(field)..add(destination);
+  }
+
+  void addStore(int object, int field, int source) {
+    assert(object >= 0);
+    assert(field >= 0);
+    assert(source >= 0);
+    stores..add(object)..add(field)..add(source);
+  }
+
+  /// Like an assignment from [source] to [sink], but is only propagated once
+  /// after the fixed-point has been found.
+  ///
+  /// This is for storing the results of the analysis in the [sink] variable
+  /// without intefering with the solver's escape analysis.
+  void addSink(int source, int sink) {
+    assert(source >= 0);
+    assert(sink >= 0);
+    sinks..add(source)..add(sink);
+  }
+
+  int get numberOfAllocations => allocations.length ~/ 2;
+  int get numberOfAssignments => assignments.length ~/ 2;
+  int get numberOfLoads => loads.length ~/ 3;
+  int get numberOfStores => stores.length ~/ 3;
+}
diff --git a/pkg/kernel/lib/type_propagation/solver.dart b/pkg/kernel/lib/type_propagation/solver.dart
new file mode 100644
index 0000000..e0deeaf
--- /dev/null
+++ b/pkg/kernel/lib/type_propagation/solver.dart
@@ -0,0 +1,427 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.solver;
+
+import 'constraints.dart';
+import 'builder.dart';
+import '../class_hierarchy.dart';
+import 'visualizer.dart';
+import 'canonicalizer.dart';
+import 'type_propagation.dart';
+
+class ValueVector {
+  List<int> values;
+  List<int> bitmasks;
+
+  ValueVector(int length)
+      : values = new List<int>.filled(length, Solver.bottom),
+        bitmasks = new List<int>.filled(length, 0);
+}
+
+/// We adopt a Hungarian-like notation in this class to distinguish variables,
+/// values, and lattice points, since they are all integers.
+///
+/// The term "values" (plural) always refers to a lattice point.
+class Solver {
+  final Builder builder;
+  final ConstraintSystem constraints;
+  final FieldNames canonicalizer;
+  final ClassHierarchy hierarchy;
+
+  /// Maps a variable index to a values that may flow into it.
+  final ValueVector valuesInVariable;
+
+  /// Maps a field index to the values that may be stored in the given field on
+  /// any object that escaped into a mega union.
+  final ValueVector valuesStoredOnEscapingObject;
+
+  /// Maps a field index to a lattice point containing all values that may be
+  /// stored into the given field where the receiver is a mega union.
+  ///
+  /// This is a way to avoid propagating such stores into almost every entry
+  /// store location.
+  final ValueVector valuesStoredOnUnknownObject;
+
+  /// Maps a lattice point to a sorted list of its ancestors in the lattice
+  /// (i.e. all lattice points that lie above it, and thus represent less
+  /// precise information).
+  ///
+  /// For this purpose, a lattice point is considered an ancestor of itself and
+  /// occurs as the end of its own ancestor list.
+  ///
+  /// We omit the entry for the lattice top (representing "any value") from all
+  /// the ancestor listss.
+  final List<List<int>> ancestorsOfLatticePoint;
+
+  /// Maps a lattice point to the list of values it contains (i.e. whose leaves
+  /// lie below it in the lattice).
+  ///
+  /// The entries for the `Object` and `Function` lattice points are empty.
+  /// They are special-cased to avoid traversing a huge number of values.
+  final List<List<int>> valuesBelowLatticePoint;
+
+  /// Maps a value to the lowest-indexed lattice point into which it has escaped
+  /// through a join operation.
+  ///
+  /// As a value escapes further up the lattice, more and more stores and loads
+  /// will see it as a potential target.
+  final List<int> valueEscape;
+
+  /// Maps a lattice point to its lowest-indexed ancestor (possibly itself) into
+  /// which all of its members must escape.
+  ///
+  /// Escaping into a lattice point is transitive in the following sense:
+  ///
+  ///    If a value `x` escapes into a lattice point `u`,
+  ///    and `u` escapes into an ancestor lattice point `w`,
+  ///    then `x` also escapes into `w`.
+  ///
+  /// The above rule also applies if the value `x` is replaced with a lattice
+  /// point.
+  ///
+  /// Note that some values below a given lattice point may escape further out
+  /// than the lattice point's own escape level.
+  final List<int> latticePointEscape;
+
+  /// The lattice point containing all functions.
+  final int _functionLatticePoint;
+
+  static const int bottom = -1;
+  static const int rootClass = 0;
+
+  /// Lattice points with more than this number values below it are considered
+  /// "mega unions".
+  ///
+  /// Stores and loads are tracked less precisely on mega unions in order to
+  /// speed up the analysis.
+  ///
+  /// The `Object` and `Function` lattice points are always considered mega
+  /// unions.
+  static const int megaUnionLimit = 100;
+
+  int iterations = 0;
+  bool _changed = false;
+
+  static List<int> _makeIntList(int _) => <int>[];
+
+  Visualizer get visualizer => builder.visualizer;
+
+  Solver(Builder builder)
+      : this.builder = builder,
+        this.constraints = builder.constraints,
+        this.canonicalizer = builder.fieldNames,
+        this.hierarchy = builder.hierarchy,
+        this.valuesInVariable =
+            new ValueVector(builder.constraints.numberOfVariables),
+        this.ancestorsOfLatticePoint = new List<List<int>>.generate(
+            builder.constraints.numberOfLatticePoints, _makeIntList),
+        this.valuesBelowLatticePoint = new List<List<int>>.generate(
+            builder.constraints.numberOfLatticePoints, _makeIntList),
+        this._functionLatticePoint = builder.latticePointForAllFunctions,
+        this.valuesStoredOnEscapingObject =
+            new ValueVector(builder.fieldNames.length),
+        this.valuesStoredOnUnknownObject =
+            new ValueVector(builder.fieldNames.length),
+        this.latticePointEscape =
+            new List<int>.filled(builder.constraints.numberOfLatticePoints, 0),
+        this.valueEscape =
+            new List<int>.filled(builder.constraints.numberOfValues, 0) {
+    // Initialize the lattice and escape data.
+    for (int i = 1; i < constraints.numberOfLatticePoints; ++i) {
+      List<int> parents = constraints.parentsOfLatticePoint[i];
+      List<int> ancestors = ancestorsOfLatticePoint[i];
+      for (int j = 0; j < parents.length; ++j) {
+        ancestors.addAll(ancestorsOfLatticePoint[parents[j]]);
+      }
+      _sortAndRemoveDuplicates(ancestors);
+      ancestors.add(i);
+      latticePointEscape[i] = i;
+    }
+    // Initialize the set of values below in a given lattice point.
+    for (int value = 0; value < constraints.numberOfValues; ++value) {
+      int latticePoint = constraints.latticePointOfValue[value];
+      List<int> ancestors = ancestorsOfLatticePoint[latticePoint];
+      for (int j = 0; j < ancestors.length; ++j) {
+        int ancestor = ancestors[j];
+        if (ancestor == rootClass || ancestor == _functionLatticePoint) {
+          continue;
+        }
+        valuesBelowLatticePoint[ancestor].add(value);
+      }
+      valueEscape[value] = latticePoint;
+    }
+  }
+
+  static void _sortAndRemoveDuplicates(List<int> list) {
+    list.sort();
+    int deleted = 0;
+    for (int i = 1; i < list.length; ++i) {
+      if (list[i] == list[i - 1]) {
+        ++deleted;
+      } else if (deleted > 0) {
+        list[i - deleted] = list[i];
+      }
+    }
+    if (deleted > 0) {
+      list.length -= deleted;
+    }
+  }
+
+  /// Returns a lattice point lying above both of the given points, thus
+  /// guaranteed to over-approximate the set of values in both.
+  ///
+  /// If the lattice point represent classes, the upper bound is a supertype
+  /// that is implemented by both, and for which no more specific supertype
+  /// exists. If multiple such classes exist, an arbitrary but fixed choice is
+  /// made.
+  ///
+  /// The ambiguity means the join operator is not associative, and the analysis
+  /// result can therefore depend on iteration order.
+  //
+  // TODO(asgerf): I think we can fix this by introducing intersection types
+  //   for the class pairs that are ambiguous least upper bounds. This could be
+  //   done as a preprocessing of the constraint system.
+  int join(int point1, int point2) {
+    if (point1 == point2) return point1;
+    // Check if either is the bottom value (-1).
+    if (point1 < 0) return point2;
+    if (point2 < 0) return point1;
+    List<int> ancestorList1 = ancestorsOfLatticePoint[point1];
+    List<int> ancestorList2 = ancestorsOfLatticePoint[point2];
+    // Classes are topologically and numerically sorted, so the more specific
+    // supertypes always occur after the less specific ones.  Traverse both
+    // lists from the right until a common supertype is found.  Starting from
+    // the right ensures we can only find one of the most specific supertypes.
+    int i = ancestorList1.length - 1, j = ancestorList2.length - 1;
+    while (i >= 0 && j >= 0) {
+      int super1 = ancestorList1[i];
+      int super2 = ancestorList2[j];
+      if (super1 < super2) {
+        --j;
+      } else if (super1 > super2) {
+        --i;
+      } else {
+        // Both types have "escaped" into their common super type.
+        _updateEscapeIndex(point1, super1);
+        _updateEscapeIndex(point2, super1);
+        return super1;
+      }
+    }
+    // Both types have escaped into a completely dynamic context.
+    _updateEscapeIndex(point1, rootClass);
+    _updateEscapeIndex(point2, rootClass);
+    return rootClass;
+  }
+
+  void _updateEscapeIndex(int point, int escapeTarget) {
+    if (latticePointEscape[point] > escapeTarget) {
+      latticePointEscape[point] = escapeTarget;
+      _changed = true;
+    }
+  }
+
+  void _initializeAllocations() {
+    List<int> allocations = constraints.allocations;
+    for (int i = 0; i < allocations.length; i += 2) {
+      int destination = allocations[i + 1];
+      int valueId = allocations[i];
+      int point = constraints.latticePointOfValue[valueId];
+      valuesInVariable.values[destination] =
+          join(valuesInVariable.values[destination], point);
+    }
+    List<int> bitmaskInputs = constraints.bitmaskInputs;
+    for (int i = 0; i < bitmaskInputs.length; i += 2) {
+      int destination = bitmaskInputs[i + 1];
+      int bitmask = bitmaskInputs[i];
+      valuesInVariable.bitmasks[destination] |= bitmask;
+    }
+  }
+
+  bool _isMegaUnion(int latticePoint) {
+    return latticePoint == rootClass ||
+        latticePoint == _functionLatticePoint ||
+        valuesBelowLatticePoint[latticePoint].length > megaUnionLimit;
+  }
+
+  void solve() {
+    _initializeAllocations();
+    List<int> assignments = constraints.assignments;
+    List<int> loads = constraints.loads;
+    List<int> stores = constraints.stores;
+    List<int> latticePointOfValue = constraints.latticePointOfValue;
+    Uint31PairMap storeLocations = constraints.storeLocations;
+    Uint31PairMap loadLocations = constraints.loadLocations;
+    do {
+      ++iterations;
+      _changed = false;
+      for (int i = 0; i < assignments.length; i += 2) {
+        int destination = assignments[i + 1];
+        int source = assignments[i];
+        _update(valuesInVariable, destination, valuesInVariable, source);
+      }
+      for (int i = 0; i < stores.length; i += 3) {
+        int sourceVariable = stores[i + 2];
+        int field = stores[i + 1];
+        int objectVariable = stores[i];
+        int objectValues = valuesInVariable.values[objectVariable];
+        if (objectValues == bottom) continue;
+        if (_isMegaUnion(objectValues)) {
+          _update(valuesStoredOnUnknownObject, field, valuesInVariable,
+              sourceVariable);
+        } else {
+          // Store the value on all subtypes that can escape into this
+          // context or worse.
+          List<int> receivers = valuesBelowLatticePoint[objectValues];
+          for (int j = 0; j < receivers.length; ++j) {
+            int receiver = receivers[j];
+            int escape = valueEscape[receiver];
+            if (escape > objectValues) {
+              continue; // Skip receivers that have not escaped this far.
+            }
+            int location = storeLocations.lookup(receiver, field);
+            if (location == null) continue;
+            _update(
+                valuesInVariable, location, valuesInVariable, sourceVariable);
+          }
+        }
+      }
+      for (int i = 0; i < loads.length; i += 3) {
+        int destination = loads[i + 2];
+        int field = loads[i + 1];
+        int objectVariable = loads[i];
+        int objectValues = valuesInVariable.values[objectVariable];
+        if (objectValues == bottom) continue;
+        if (_isMegaUnion(objectValues)) {
+          // Receiver is unknown. Take the value out of the tarpit.
+          _update(valuesInVariable, destination, valuesStoredOnEscapingObject,
+              field);
+        } else {
+          // Load the values stored on all the subtypes that can escape into
+          // this context or worse.
+          List<int> receivers = valuesBelowLatticePoint[objectValues];
+          for (int j = 0; j < receivers.length; ++j) {
+            int receiver = receivers[j];
+            int escape = valueEscape[receiver];
+            if (escape > objectValues) {
+              continue; // Skip receivers that have not escaped this far.
+            }
+            int location = loadLocations.lookup(receiver, field);
+            if (location == null) continue;
+            _update(valuesInVariable, destination, valuesInVariable, location);
+          }
+        }
+      }
+      // Apply the transitive escape rule on the lattice.
+      for (int point = 0; point < latticePointEscape.length; ++point) {
+        int oldEscape = latticePointEscape[point];
+        if (oldEscape == point) continue;
+        List<int> ancestors = ancestorsOfLatticePoint[point];
+        int newEscape = oldEscape;
+        for (int j = 0; j < ancestors.length; ++j) {
+          int ancestor = ancestors[j];
+          if (ancestor < oldEscape) continue;
+          int superEscape = latticePointEscape[ancestor];
+          if (superEscape < newEscape) {
+            newEscape = superEscape;
+          }
+        }
+        if (oldEscape != newEscape) {
+          latticePointEscape[point] = newEscape;
+          _changed = true;
+        }
+      }
+      // Update the escape level of every value.
+      for (int i = 0; i < latticePointOfValue.length; ++i) {
+        int value = i;
+        int latticePoint = latticePointOfValue[value];
+        int oldEscape = valueEscape[value];
+        int newEscape = latticePointEscape[latticePoint];
+        if (newEscape < oldEscape) {
+          valueEscape[value] = newEscape;
+          _changed = true;
+        }
+      }
+      // Handle stores on escaping objects.
+      List<int> storeLocationList = constraints.storeLocationList;
+      for (int i = 0; i < storeLocationList.length; i += 3) {
+        int variable = storeLocationList[i + 2];
+        int field = storeLocationList[i + 1];
+        int objectValue = storeLocationList[i];
+        int escape = valueEscape[objectValue];
+        if (_isMegaUnion(escape)) {
+          _update(
+              valuesInVariable, variable, valuesStoredOnUnknownObject, field);
+        }
+      }
+      // Handle loads from escaping objects.
+      List<int> loadLocationList = constraints.loadLocationList;
+      for (int i = 0; i < loadLocationList.length; i += 3) {
+        int variable = loadLocationList[i + 2];
+        int field = loadLocationList[i + 1];
+        int objectValue = loadLocationList[i];
+        int escape = valueEscape[objectValue];
+        if (_isMegaUnion(escape)) {
+          _update(
+              valuesStoredOnEscapingObject, field, valuesInVariable, variable);
+        }
+      }
+    } while (_changed);
+
+    // Propagate to sinks.
+    // This is done outside the fixed-point iteration so the sink-join does
+    // not cause values to be considered escaping.
+    List<int> sinks = constraints.sinks;
+    for (int i = 0; i < sinks.length; i += 2) {
+      int destination = sinks[i + 1];
+      int source = sinks[i];
+      _update(valuesInVariable, destination, valuesInVariable, source);
+    }
+  }
+
+  void _update(ValueVector destinationVector, int destinationIndex,
+      ValueVector sourceVector, int sourceIndex) {
+    int oldValues = destinationVector.values[destinationIndex];
+    int inputValues = sourceVector.values[sourceIndex];
+    int newValues = join(inputValues, oldValues);
+    if (newValues != oldValues) {
+      destinationVector.values[destinationIndex] = newValues;
+      _changed = true;
+    }
+    int oldBits = destinationVector.bitmasks[destinationIndex];
+    int inputBits = sourceVector.bitmasks[sourceIndex];
+    int newBits = inputBits | oldBits;
+    if (newBits != oldBits) {
+      destinationVector.bitmasks[destinationIndex] = newBits;
+      _changed = true;
+    }
+  }
+
+  /// Returns the index of a lattice point containing all values that can flow
+  /// into the given variable, or [bottom] if nothing can flow into the
+  /// variable.
+  int getVariableValue(int variable) {
+    return valuesInVariable.values[variable];
+  }
+
+  int getVariableBitmask(int variable) {
+    return valuesInVariable.bitmasks[variable];
+  }
+
+  /// Returns the lowest-indexed lattice point into which the given value can
+  /// escape.
+  int getEscapeContext(int value) {
+    return valueEscape[value];
+  }
+
+  InferredValue getValueInferredForVariable(int variable) {
+    assert(variable != null);
+    int latticePoint = valuesInVariable.values[variable];
+    int bitmask = valuesInVariable.bitmasks[variable];
+    if (latticePoint == bottom) {
+      return new InferredValue(null, BaseClassKind.None, bitmask);
+    }
+    InferredValue value = builder.getBaseTypeOfLatticePoint(latticePoint);
+    return value.withBitmask(bitmask);
+  }
+}
diff --git a/pkg/kernel/lib/type_propagation/type_propagation.dart b/pkg/kernel/lib/type_propagation/type_propagation.dart
new file mode 100644
index 0000000..48305c2
--- /dev/null
+++ b/pkg/kernel/lib/type_propagation/type_propagation.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation;
+
+import '../ast.dart';
+import '../class_hierarchy.dart';
+import '../core_types.dart';
+import 'builder.dart';
+import 'solver.dart';
+
+/// High-level interface to type propagation.
+///
+/// This exposes inferred types as [InferredValue], context-insensitively at
+/// the level of function boundaries.  The internal analysis results may be
+/// more precise but their representation is private to the analysis, and
+/// except for diagnostics, clients should only depend on the results exposed
+/// by this interface.
+//
+// TODO(asgerf): Also expose return value of calls.
+// TODO(asgerf): Should we expose the value of all expressions?
+class TypePropagation {
+  final Builder builder;
+  final Solver solver;
+
+  TypePropagation(Program program,
+      {ClassHierarchy hierarchy, CoreTypes coreTypes})
+      : this.withBuilder(
+            new Builder(program, hierarchy: hierarchy, coreTypes: coreTypes));
+
+  TypePropagation.withBuilder(Builder builder)
+      : this.builder = builder,
+        this.solver = new Solver(builder)..solve();
+
+  InferredValue getFieldValue(Field node) {
+    int variable = builder.global.fields[node];
+    if (variable == null) return null;
+    return solver.getValueInferredForVariable(variable);
+  }
+
+  InferredValue getReturnValue(FunctionNode node) {
+    int variable = builder.global.returns[node];
+    if (variable == null) return null;
+    return solver.getValueInferredForVariable(variable);
+  }
+
+  InferredValue getParameterValue(VariableDeclaration node) {
+    int variable = builder.global.parameters[node];
+    if (variable == null) return null;
+    return solver.getValueInferredForVariable(variable);
+  }
+}
+
+enum BaseClassKind { None, Exact, Subclass, Subtype, }
+
+/// An abstract value inferred by type propagation.
+///
+/// Inferred values consist of two parts that each represent a set of values:
+/// its base class and its bitmask.  The InferredValue object represents the
+/// intersection of these two value sets.
+class InferredValue extends Node {
+  final Class baseClass;
+  final BaseClassKind baseClassKind;
+
+  /// A bitmask of the flags defined in [ValueBit], refining the set of values.
+  ///
+  /// These bits will always represent a subset of the values allowed by
+  /// the base class.  For example, if the base class is "subclass of List",
+  /// the bitmask cannot contain [ValueBit.string], as this would contradict the
+  /// base class.
+  ///
+  /// The main use of the bitmask is to track nullability, and to preserve some
+  /// particularly important bits of information in case the no useful base
+  /// class could be found.
+  final int valueBits;
+
+  InferredValue(this.baseClass, this.baseClassKind,
+      [this.valueBits = ValueBit.all]) {
+    assert(baseClass != null || baseClassKind == BaseClassKind.None);
+    assert(baseClass == null || baseClassKind != BaseClassKind.None);
+  }
+
+  InferredValue withBitmask(int newBitmask) {
+    if (newBitmask == valueBits) return this;
+    return new InferredValue(this.baseClass, this.baseClassKind, newBitmask);
+  }
+
+  static final InferredValue nothing =
+      new InferredValue(null, BaseClassKind.None, 0);
+
+  bool get canBeNull => valueBits & ValueBit.null_ != 0;
+  bool get isAlwaysNull => baseClass == null && valueBits == ValueBit.null_;
+
+  /// True if this represents no value at all.
+  ///
+  /// When this value is inferred for a variable, it implies that the
+  /// surrounding code is unreachable.
+  bool get isNothing => baseClass == null && valueBits == 0;
+
+  /// True if the value must be null or a concrete instance of [baseClass].
+  bool get isExact => baseClassKind == BaseClassKind.Exact;
+
+  /// True if the value must be null or a subclass of [baseClass].
+  bool get isSubclass => baseClassKind == BaseClassKind.Subclass;
+
+  /// True if the value must be null or a subtype of [baseClass].
+  bool get isSubtype => baseClassKind == BaseClassKind.Subtype;
+
+  accept(Visitor v) => v.visitInferredValue(this);
+
+  visitChildren(Visitor v) {
+    baseClass?.acceptReference(v);
+  }
+}
+
+/// Defines bits representing value sets for use in [InferredValue.valueBits].
+///
+/// The bitmask defines a partition of the entire value space, so every concrete
+/// value corresponds to exactly one value bit.
+class ValueBit {
+  static const int null_ = 1 << 0;
+  static const int integer = 1 << 1;
+  static const int double_ = 1 << 2;
+  static const int string = 1 << 3;
+
+  /// Bit representing all values other than those above.
+  ///
+  /// This bit ensures that the bitmask represents a complete partition of the
+  /// value space, allowing clients to reason about it as a closed union type.
+  ///
+  /// For example, if [integer] and [string] are the only bits that are set,
+  /// it is safe to conclude that the value can *only* be an integer or string
+  /// as all other potential values are ruled out.
+  static const int other = 1 << 4;
+
+  static const numberOfBits = 5;
+  static const int all = (1 << numberOfBits) - 1;
+
+  static const Map<int, String> names = const <int, String>{
+    null_: 'null',
+    integer: 'int',
+    double_: 'double',
+    string: 'string',
+    other: 'other',
+  };
+
+  static String format(int bitmask) {
+    if (bitmask == all) return '{*}';
+    List<String> list = <String>[];
+    for (int i = 0; i < numberOfBits; ++i) {
+      if (bitmask & (1 << i) != 0) {
+        list.add(names[1 << i] ?? '?');
+      }
+    }
+    return '{${list.join(",")}}';
+  }
+}
diff --git a/pkg/kernel/lib/type_propagation/visualizer.dart b/pkg/kernel/lib/type_propagation/visualizer.dart
new file mode 100644
index 0000000..8cfd86a
--- /dev/null
+++ b/pkg/kernel/lib/type_propagation/visualizer.dart
@@ -0,0 +1,395 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.visualizer;
+
+import 'constraints.dart';
+import 'builder.dart';
+import 'solver.dart';
+import '../ast.dart';
+import '../text/ast_to_text.dart';
+import '../class_hierarchy.dart';
+
+/// Visualizes the constraint system using a Graphviz dot graph.
+///
+/// Variables are visualized as nodes and constraints as labeled edges.
+class Visualizer {
+  final Program program;
+  final Map<int, GraphNode> variableNodes = <int, GraphNode>{};
+  final Map<int, FunctionNode> value2function = <int, FunctionNode>{};
+  final Map<FunctionNode, int> function2value = <FunctionNode, int>{};
+  final Map<int, Annotation> latticePointAnnotation = <int, Annotation>{};
+  final Map<int, Annotation> valueAnnotation = <int, Annotation>{};
+  FieldNames fieldNames;
+  ConstraintSystem constraints;
+  Solver solver;
+  Builder builder;
+
+  ClassHierarchy get hierarchy => builder.hierarchy;
+
+  final Map<Member, Set<GraphNode>> _graphNodesInMember =
+      <Member, Set<GraphNode>>{};
+
+  Visualizer(this.program);
+
+  static Set<GraphNode> _makeGraphNodeSet() => new Set<GraphNode>();
+
+  Annotator getTextAnnotator() {
+    return new TextAnnotator(this);
+  }
+
+  GraphNode getVariableNode(int variable) {
+    return variableNodes[variable] ??= new GraphNode(variable);
+  }
+
+  /// Called from the builder to associate information with a variable.
+  ///
+  /// The [node] has two purposes: it ensures that the variable will show
+  /// up in the graph for a the enclosing member, and the textual form of the
+  /// node will be part of its label.
+  ///
+  /// The optional [info] argument provides additional context beyond the AST
+  /// node.  When a constraint variable has no logical 1:1 corresondence with
+  /// an AST node, it is best to pick a nearby AST node and set the [info] to
+  /// clarify its relationship with the node.
+  void annotateVariable(int variable, TreeNode astNode, [String info]) {
+    if (astNode != null || info != null) {
+      if (astNode is VariableSet ||
+          astNode is PropertySet ||
+          astNode is StaticSet) {
+        // These will also be registered for the right-hand side, which makes
+        // for a better annotation.
+        return;
+      }
+      var node = getVariableNode(variable);
+      Member member = _getEnclosingMember(astNode);
+      node.addAnnotation(member, astNode, info);
+      _graphNodesInMember.putIfAbsent(member, _makeGraphNodeSet).add(node);
+    }
+  }
+
+  void annotateAssign(int source, int destination, TreeNode node) {
+    addEdge(source, destination, _getEnclosingMember(node), '');
+  }
+
+  void annotateSink(int source, int destination, TreeNode node) {
+    addEdge(source, destination, _getEnclosingMember(node), 'sink');
+  }
+
+  void annotateLoad(int object, int field, int destination, Member member) {
+    String fieldName = fieldNames.getDiagnosticNameOfField(field);
+    addEdge(object, destination, member, 'Load[$fieldName]');
+  }
+
+  void annotateStore(int object, int field, int source, Member member) {
+    String fieldName = fieldNames.getDiagnosticNameOfField(field);
+    addEdge(source, object, member, 'Store[$fieldName]');
+  }
+
+  void annotateDirectStore(int object, int field, int source, Member member) {
+    String fieldName = fieldNames.getDiagnosticNameOfField(field);
+    addEdge(source, object, member, 'Store![$fieldName]');
+  }
+
+  void annotateLatticePoint(int point, TreeNode node, [String info]) {
+    latticePointAnnotation[point] = new Annotation(node, info);
+  }
+
+  void annotateValue(int value, TreeNode node, [String info]) {
+    valueAnnotation[value] = new Annotation(node, info);
+  }
+
+  String getLatticePointName(int latticePoint) {
+    if (latticePoint < 0) return 'bottom';
+    return latticePointAnnotation[latticePoint].toLabel();
+  }
+
+  String getValueName(int value) {
+    return valueAnnotation[value].toLabel();
+  }
+
+  static Member _getEnclosingMember(TreeNode node) {
+    while (node != null) {
+      if (node is Member) return node;
+      node = node.parent;
+    }
+    return null;
+  }
+
+  void addEdge(int source, int destination, Member member, String label) {
+    var sourceNode = getVariableNode(source);
+    var destinationNode = getVariableNode(destination);
+    _graphNodesInMember.putIfAbsent(member, _makeGraphNodeSet)
+      ..add(sourceNode)
+      ..add(destinationNode);
+    sourceNode.addEdgeTo(destinationNode, member, label);
+  }
+
+  void annotateFunction(int value, FunctionNode function) {
+    value2function[value] = function;
+    function2value[function] = value;
+  }
+
+  FunctionNode getFunctionFromValue(int value) {
+    return value2function[value];
+  }
+
+  int getFunctionValue(FunctionNode node) {
+    return function2value[node];
+  }
+
+  Set<GraphNode> _getNodesInMember(Member member) {
+    return _graphNodesInMember.putIfAbsent(member, _makeGraphNodeSet);
+  }
+
+  String _getCodeAsLabel(Member member) {
+    String code = debugNodeToString(member);
+    code = escapeLabel(code);
+    // Replace line-breaks with left-aligned breaks.
+    code = code.replaceAll('\n', '\\l');
+    return code;
+  }
+
+  String _getValueLabel(GraphNode node) {
+    int latticePoint = solver.getVariableValue(node.variable);
+    if (latticePoint < 0) return 'bottom';
+    return escapeLabel(shorten(getLatticePointName(latticePoint)));
+  }
+
+  /// Returns the Graphviz Dot code a the subgraph relevant for [member].
+  String dumpMember(Member member) {
+    int freshIdCounter = 0;
+    StringBuffer buffer = new StringBuffer();
+    buffer.writeln('digraph {');
+    String source = _getCodeAsLabel(member);
+    buffer.writeln('source [shape=box,label="$source"]');
+    for (GraphNode node in _getNodesInMember(member)) {
+      int id = node.variable;
+      String label = node.getAnnotationInContextOf(member);
+      // Global nodes have a ton of edges that are visualized specially.
+      // If the global node has a local annotation, also print its annotated
+      // version somewhere, but omit all its edges.
+      if (node.isGlobal) {
+        if (label != '') {
+          label += '\n${node.globalAnnotation.toLabel()}';
+          buffer.writeln('$id [shape=record,label="$label"]');
+        }
+        continue;
+      }
+      String value = _getValueLabel(node);
+      buffer.writeln('$id [shape=record,label="{$label|$value}"]');
+      // Add outgoing edges.
+      // Keep track of all that edges leave the context of the current member
+      // ("external edges").  There can be a huge number of these, so we compact
+      // them into a single outgoing edge so as not to flood the graph.
+      Set<String> outgoingExternalEdgeLabels = new Set<String>();
+      for (Edge edge in node.outputs) {
+        if (edge.to.isLocal(member)) {
+          buffer.writeln('$id -> ${edge.to.variable} [label="${edge.label}"]');
+        } else if (outgoingExternalEdgeLabels.length < 3) {
+          String annotation = edge.to.externalLabel;
+          if (annotation != '') {
+            if (edge.label != '') {
+              annotation = '${edge.label} → $annotation';
+            }
+            outgoingExternalEdgeLabels.add(annotation);
+          }
+        } else if (outgoingExternalEdgeLabels.length == 3) {
+          outgoingExternalEdgeLabels.add('...');
+        }
+      }
+      // Emit the outgoing external edge.
+      if (outgoingExternalEdgeLabels.isNotEmpty) {
+        int freshId = ++freshIdCounter;
+        String outLabel = outgoingExternalEdgeLabels.join('\n');
+        buffer.writeln('x$freshId [shape=box,style=dotted,label="$outLabel"]');
+        buffer.writeln('$id -> x$freshId [style=dotted]');
+      }
+      // Show ingoing external edges. As before, avoid flooding the graph in
+      // case there are too many of them.
+      Set<String> ingoingExternalEdgeLabels = new Set<String>();
+      for (Edge edge in node.inputs) {
+        GraphNode source = edge.from;
+        if (source.isLocal(member)) continue;
+        String annotation = source.externalLabel;
+        if (annotation != '') {
+          if (ingoingExternalEdgeLabels.length < 3) {
+            if (edge.label != '') {
+              annotation = '$annotation → ${edge.label}';
+            }
+            ingoingExternalEdgeLabels.add(annotation);
+          } else {
+            ingoingExternalEdgeLabels.add('...');
+            break;
+          }
+        }
+      }
+      // Emit the ingoing external edge.
+      if (ingoingExternalEdgeLabels.isNotEmpty) {
+        int freshId = ++freshIdCounter;
+        String sourceLabel = ingoingExternalEdgeLabels.join('\n');
+        buffer.writeln('x$freshId '
+            '[shape=box,style=dotted,label="$sourceLabel"]');
+        buffer.writeln('x$freshId -> ${node.variable} [style=dotted]');
+      }
+    }
+    buffer.writeln('}');
+    return '$buffer';
+  }
+}
+
+class Annotation {
+  final TreeNode node;
+  final String info;
+
+  Annotation(this.node, this.info);
+
+  String toLabel() {
+    if (node == null && info == null) return '(missing annotation)';
+    if (node == null) return escapeLabel(info);
+    String label = node is NullLiteral
+        ? 'null literal'
+        : node is FunctionNode ? shorten('${node.parent}') : shorten('$node');
+    if (info != null) {
+      label = '$info: $label';
+    }
+    label = escapeLabel(label);
+    return label;
+  }
+
+  String toLabelWithContext(Member member) {
+    String label = toLabel();
+    if (node == member) {
+      return label;
+    } else {
+      return '$label in $member';
+    }
+  }
+}
+
+class GraphNode {
+  final int variable;
+  final List<Edge> inputs = <Edge>[];
+  final List<Edge> outputs = <Edge>[];
+  final List<Annotation> annotations = <Annotation>[];
+
+  /// The annotation to show when visualized in the context of a given member.
+  final Map<Member, Annotation> annotationForContext = <Member, Annotation>{};
+
+  GraphNode(this.variable);
+
+  bool get isGlobal => annotationForContext.containsKey(null);
+  Annotation get globalAnnotation => annotationForContext[null];
+  bool isInScope(Member member) => annotationForContext.containsKey(member);
+  bool isLocal(Member member) => !isGlobal && isInScope(member);
+
+  /// The label to show for the given node when seen from the context of
+  /// another member.
+  String get externalLabel {
+    if (isGlobal) return globalAnnotation.toLabel();
+    if (annotationForContext.isEmpty) return '$variable';
+    Member member = annotationForContext.keys.first;
+    Annotation annotation = annotationForContext[member];
+    return '$variable:' + annotation.toLabelWithContext(member);
+  }
+
+  String getAnnotationInContextOf(Member member) {
+    if (annotationForContext.isEmpty) return '';
+    Annotation annotation = annotationForContext[member];
+    if (annotation != null) return '$variable:' + annotation.toLabel();
+    annotation =
+        annotationForContext[null] ?? annotationForContext.values.first;
+    return '$variable:' + annotation.toLabelWithContext(member);
+  }
+
+  void addEdgeTo(GraphNode other, Member member, String label) {
+    Edge edge = new Edge(this, other, member, label);
+    outputs.add(edge);
+    other.inputs.add(edge);
+  }
+
+  void addAnnotation(Member member, TreeNode astNode, String info) {
+    var annotation = new Annotation(astNode, info);
+    annotations.add(annotation);
+    annotationForContext[member] = annotation;
+  }
+}
+
+class Edge {
+  final GraphNode from, to;
+  final Member member;
+  final String label;
+
+  Edge(this.from, this.to, this.member, this.label);
+}
+
+final RegExp escapeRegexp = new RegExp('["{}<>|]', multiLine: true);
+
+/// Escapes characters in [text] so it can be used as part of a label.
+String escapeLabel(String text) {
+  return text.replaceAllMapped(escapeRegexp, (m) => '\\${m.group(0)}');
+}
+
+String shorten(String text) {
+  text = text.replaceAll('\n  ', ' ').replaceAll('\n', ' ').trim();
+  if (text.length > 60) {
+    return text.substring(0, 30) + '...' + text.substring(text.length - 27);
+  }
+  return text;
+}
+
+class TextAnnotator extends Annotator {
+  final Visualizer visualizer;
+  final Map<VariableDeclaration, int> variables = <VariableDeclaration, int>{};
+  final Map<FunctionNode, int> functionReturns = <FunctionNode, int>{};
+
+  Builder get builder => visualizer.builder;
+
+  String getReference(Node node, Printer printer) {
+    if (node is Class) return printer.getClassReference(node);
+    if (node is Member) return printer.getMemberReference(node);
+    if (node is Library) return printer.getLibraryReference(node);
+    return debugNodeToString(node);
+  }
+
+  String getValueForVariable(Printer printer, int variable) {
+    if (variable == null) {
+      return '<missing type>';
+    }
+    var value = visualizer.solver.getValueInferredForVariable(variable);
+    return printer.getInferredValueString(value);
+  }
+
+  TextAnnotator(this.visualizer) {
+    // The correspondence between AST and constraint system is exposed by the
+    // builder, but only at the level of Members.
+    // To get to the correspondence at the statement/expression level, we use
+    // the annotation map from the visualizer API.
+    // TODO(asgerf): If we use these annotations for testing, the necessary
+    //   bindings should arguably be part of the API for the Builder.
+    visualizer.variableNodes.forEach((int variable, GraphNode node) {
+      for (Annotation annotation in node.annotations) {
+        if (annotation.node is VariableDeclaration && annotation.info == null) {
+          variables[annotation.node] = variable;
+        }
+        if (annotation.node is FunctionNode && annotation.info == 'return') {
+          functionReturns[annotation.node] = variable;
+        }
+      }
+    });
+  }
+
+  String annotateVariable(Printer printer, VariableDeclaration node) {
+    return getValueForVariable(
+        printer, builder.global.parameters[node] ?? variables[node]);
+  }
+
+  String annotateReturn(Printer printer, FunctionNode node) {
+    if (node.parent is Constructor) return null;
+    return getValueForVariable(printer, builder.global.returns[node]);
+  }
+
+  String annotateField(Printer printer, Field node) {
+    return getValueForVariable(printer, builder.global.fields[node]);
+  }
+}
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
new file mode 100644
index 0000000..27cc492
--- /dev/null
+++ b/pkg/kernel/lib/verifier.dart
@@ -0,0 +1,292 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.checks;
+
+import 'ast.dart';
+import 'transformations/flags.dart';
+
+void verifyProgram(Program program) {
+  VerifyingVisitor.check(program);
+}
+
+/// Checks that a kernel program is well-formed.
+///
+/// This does not include any kind of type checking.
+class VerifyingVisitor extends RecursiveVisitor {
+  final Set<Class> classes = new Set<Class>();
+  final Set<TypeParameter> typeParameters = new Set<TypeParameter>();
+  final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
+  bool classTypeParametersAreInScope = false;
+
+  Member currentMember;
+  Class currentClass;
+  TreeNode currentParent;
+
+  TreeNode get context => currentMember ?? currentClass;
+
+  static void check(Program program) {
+    program.accept(new VerifyingVisitor());
+  }
+
+  defaultTreeNode(TreeNode node) {
+    visitChildren(node);
+  }
+
+  TreeNode enterParent(TreeNode node) {
+    if (!identical(node.parent, currentParent)) {
+      throw 'Incorrect parent pointer on ${node.runtimeType} in $context. '
+          'Parent pointer is ${node.parent.runtimeType}, '
+          'actual parent is ${currentParent.runtimeType}.';
+    }
+    var oldParent = currentParent;
+    currentParent = node;
+    return oldParent;
+  }
+
+  void exitParent(TreeNode oldParent) {
+    currentParent = oldParent;
+  }
+
+  int enterLocalScope() => variableStack.length;
+
+  void exitLocalScope(int stackHeight) {
+    for (int i = stackHeight; i < variableStack.length; ++i) {
+      undeclareVariable(variableStack[i]);
+    }
+    variableStack.length = stackHeight;
+  }
+
+  void visitChildren(TreeNode node) {
+    var oldParent = enterParent(node);
+    node.visitChildren(this);
+    exitParent(oldParent);
+  }
+
+  void visitWithLocalScope(TreeNode node) {
+    int stackHeight = enterLocalScope();
+    visitChildren(node);
+    exitLocalScope(stackHeight);
+  }
+
+  void declareMember(Member member) {
+    if (member.transformerFlags & TransformerFlag.seenByVerifier != 0) {
+      throw '$member has been declared more than once (${member.location})';
+    }
+    member.transformerFlags |= TransformerFlag.seenByVerifier;
+  }
+
+  void undeclareMember(Member member) {
+    member.transformerFlags &= ~TransformerFlag.seenByVerifier;
+  }
+
+  void declareVariable(VariableDeclaration variable) {
+    if (variable.flags & VariableDeclaration.FlagInScope != 0) {
+      throw '$variable declared more than once (${variable.location})';
+    }
+    variable.flags |= VariableDeclaration.FlagInScope;
+    variableStack.add(variable);
+  }
+
+  void undeclareVariable(VariableDeclaration variable) {
+    variable.flags &= ~VariableDeclaration.FlagInScope;
+  }
+
+  void checkVariableInScope(VariableDeclaration variable, TreeNode where) {
+    if (variable.flags & VariableDeclaration.FlagInScope == 0) {
+      throw 'Variable $variable used out of scope in $context '
+          '(${where.location})';
+    }
+  }
+
+  visitProgram(Program program) {
+    for (var library in program.libraries) {
+      classes.addAll(library.classes);
+      library.members.forEach(declareMember);
+      for (var class_ in library.classes) {
+        class_.members.forEach(declareMember);
+      }
+    }
+    visitChildren(program);
+    for (var library in program.libraries) {
+      library.members.forEach(undeclareMember);
+      for (var class_ in library.classes) {
+        class_.members.forEach(undeclareMember);
+      }
+    }
+  }
+
+  visitField(Field node) {
+    currentMember = node;
+    var oldParent = enterParent(node);
+    classTypeParametersAreInScope = !node.isStatic;
+    node.initializer?.accept(this);
+    classTypeParametersAreInScope = false;
+    visitList(node.annotations, this);
+    exitParent(oldParent);
+    currentMember = null;
+  }
+
+  visitProcedure(Procedure node) {
+    currentMember = node;
+    var oldParent = enterParent(node);
+    classTypeParametersAreInScope = !node.isStatic;
+    node.function.accept(this);
+    classTypeParametersAreInScope = false;
+    visitList(node.annotations, this);
+    exitParent(oldParent);
+    currentMember = null;
+  }
+
+  visitConstructor(Constructor node) {
+    currentMember = node;
+    classTypeParametersAreInScope = true;
+    // The constructor member needs special treatment due to parameters being
+    // in scope in the initializer list.
+    var oldParent = enterParent(node);
+    int stackHeight = enterLocalScope();
+    visitChildren(node.function);
+    visitList(node.initializers, this);
+    exitLocalScope(stackHeight);
+    classTypeParametersAreInScope = false;
+    visitList(node.annotations, this);
+    exitParent(oldParent);
+    classTypeParametersAreInScope = false;
+    currentMember = null;
+  }
+
+  visitClass(Class node) {
+    currentClass = node;
+    typeParameters.addAll(node.typeParameters);
+    var oldParent = enterParent(node);
+    classTypeParametersAreInScope = false;
+    visitList(node.annotations, this);
+    classTypeParametersAreInScope = true;
+    visitList(node.typeParameters, this);
+    visitList(node.fields, this);
+    visitList(node.constructors, this);
+    visitList(node.procedures, this);
+    exitParent(oldParent);
+    typeParameters.removeAll(node.typeParameters);
+    currentClass = null;
+  }
+
+  visitFunctionNode(FunctionNode node) {
+    typeParameters.addAll(node.typeParameters);
+    visitWithLocalScope(node);
+    typeParameters.removeAll(node.typeParameters);
+  }
+
+  visitFunctionType(FunctionType node) {
+    for (int i = 1; i < node.namedParameters.length; ++i) {
+      if (node.namedParameters[i - 1].compareTo(node.namedParameters[i]) >= 0) {
+        throw 'Named parameters are not sorted on function type found in '
+            '$context';
+      }
+    }
+    typeParameters.addAll(node.typeParameters);
+    for (var typeParameter in node.typeParameters) {
+      typeParameter.bound?.accept(this);
+    }
+    visitList(node.positionalParameters, this);
+    visitList(node.namedParameters, this);
+    node.returnType.accept(this);
+    typeParameters.removeAll(node.typeParameters);
+  }
+
+  visitBlock(Block node) {
+    visitWithLocalScope(node);
+  }
+
+  visitForStatement(ForStatement node) {
+    visitWithLocalScope(node);
+  }
+
+  visitForInStatement(ForInStatement node) {
+    visitWithLocalScope(node);
+  }
+
+  visitLet(Let node) {
+    visitWithLocalScope(node);
+  }
+
+  visitCatch(Catch node) {
+    visitWithLocalScope(node);
+  }
+
+  visitVariableDeclaration(VariableDeclaration node) {
+    visitChildren(node);
+    declareVariable(node);
+  }
+
+  visitVariableGet(VariableGet node) {
+    checkVariableInScope(node.variable, node);
+  }
+
+  visitVariableSet(VariableSet node) {
+    checkVariableInScope(node.variable, node);
+    visitChildren(node);
+  }
+
+  @override
+  defaultMemberReference(Member node) {
+    if (node.transformerFlags & TransformerFlag.seenByVerifier == 0) {
+      throw 'Dangling reference to $node found in $context.\n'
+          'Parent pointer is set to ${node.parent}';
+    }
+  }
+
+  @override
+  visitClassReference(Class node) {
+    if (!classes.contains(node)) {
+      throw 'Dangling reference to $node found in $context.\n'
+          'Parent pointer is set to ${node.parent}';
+    }
+  }
+
+  @override
+  visitTypeParameterType(TypeParameterType node) {
+    var parameter = node.parameter;
+    if (!typeParameters.contains(parameter)) {
+      throw 'Type parameter $parameter referenced out of scope in $context.\n'
+          'Parent pointer is set to ${parameter.parent}';
+    }
+    if (parameter.parent is Class && !classTypeParametersAreInScope) {
+      throw 'Type parameter $parameter referenced from static context '
+          'in $context.\n'
+          'Parent pointer is set to ${parameter.parent}';
+    }
+  }
+
+  @override
+  visitInterfaceType(InterfaceType node) {
+    node.visitChildren(this);
+    if (node.typeArguments.length != node.classNode.typeParameters.length) {
+      throw 'Type $node provides ${node.typeArguments.length} type arguments '
+          'but the class declares ${node.classNode.typeParameters.length} '
+          'parameters. Found in $context.';
+    }
+  }
+}
+
+class CheckParentPointers extends Visitor {
+  static void check(TreeNode node) {
+    node.accept(new CheckParentPointers(node.parent));
+  }
+
+  TreeNode parent;
+
+  CheckParentPointers([this.parent]);
+
+  defaultTreeNode(TreeNode node) {
+    if (node.parent != parent) {
+      throw 'Parent pointer on ${node.runtimeType} '
+          'is ${node.parent.runtimeType} '
+          'but should be ${parent.runtimeType}';
+    }
+    var oldParent = parent;
+    parent = node;
+    node.visitChildren(this);
+    parent = oldParent;
+  }
+}
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
new file mode 100644
index 0000000..c48f0d4
--- /dev/null
+++ b/pkg/kernel/lib/visitor.dart
@@ -0,0 +1,315 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.ast.visitor;
+
+import 'ast.dart';
+
+abstract class ExpressionVisitor<R> {
+  R defaultExpression(Expression node) => null;
+  R defaultBasicLiteral(BasicLiteral node) => defaultExpression(node);
+
+  R visitInvalidExpression(InvalidExpression node) => defaultExpression(node);
+  R visitVariableGet(VariableGet node) => defaultExpression(node);
+  R visitVariableSet(VariableSet node) => defaultExpression(node);
+  R visitPropertyGet(PropertyGet node) => defaultExpression(node);
+  R visitPropertySet(PropertySet node) => defaultExpression(node);
+  R visitDirectPropertyGet(DirectPropertyGet node) => defaultExpression(node);
+  R visitDirectPropertySet(DirectPropertySet node) => defaultExpression(node);
+  R visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node);
+  R visitSuperPropertySet(SuperPropertySet node) => defaultExpression(node);
+  R visitStaticGet(StaticGet node) => defaultExpression(node);
+  R visitStaticSet(StaticSet node) => defaultExpression(node);
+  R visitMethodInvocation(MethodInvocation node) => defaultExpression(node);
+  R visitDirectMethodInvocation(DirectMethodInvocation node) =>
+      defaultExpression(node);
+  R visitSuperMethodInvocation(SuperMethodInvocation node) =>
+      defaultExpression(node);
+  R visitStaticInvocation(StaticInvocation node) => defaultExpression(node);
+  R visitConstructorInvocation(ConstructorInvocation node) =>
+      defaultExpression(node);
+  R visitNot(Not node) => defaultExpression(node);
+  R visitLogicalExpression(LogicalExpression node) => defaultExpression(node);
+  R visitConditionalExpression(ConditionalExpression node) =>
+      defaultExpression(node);
+  R visitStringConcatenation(StringConcatenation node) =>
+      defaultExpression(node);
+  R visitIsExpression(IsExpression node) => defaultExpression(node);
+  R visitAsExpression(AsExpression node) => defaultExpression(node);
+  R visitSymbolLiteral(SymbolLiteral node) => defaultExpression(node);
+  R visitTypeLiteral(TypeLiteral node) => defaultExpression(node);
+  R visitThisExpression(ThisExpression node) => defaultExpression(node);
+  R visitRethrow(Rethrow node) => defaultExpression(node);
+  R visitThrow(Throw node) => defaultExpression(node);
+  R visitListLiteral(ListLiteral node) => defaultExpression(node);
+  R visitMapLiteral(MapLiteral node) => defaultExpression(node);
+  R visitAwaitExpression(AwaitExpression node) => defaultExpression(node);
+  R visitFunctionExpression(FunctionExpression node) => defaultExpression(node);
+  R visitStringLiteral(StringLiteral node) => defaultBasicLiteral(node);
+  R visitIntLiteral(IntLiteral node) => defaultBasicLiteral(node);
+  R visitDoubleLiteral(DoubleLiteral node) => defaultBasicLiteral(node);
+  R visitBoolLiteral(BoolLiteral node) => defaultBasicLiteral(node);
+  R visitNullLiteral(NullLiteral node) => defaultBasicLiteral(node);
+  R visitLet(Let node) => defaultExpression(node);
+}
+
+abstract class StatementVisitor<R> {
+  R defaultStatement(Statement node) => null;
+
+  R visitInvalidStatement(InvalidStatement node) => defaultStatement(node);
+  R visitExpressionStatement(ExpressionStatement node) =>
+      defaultStatement(node);
+  R visitBlock(Block node) => defaultStatement(node);
+  R visitEmptyStatement(EmptyStatement node) => defaultStatement(node);
+  R visitAssertStatement(AssertStatement node) => defaultStatement(node);
+  R visitLabeledStatement(LabeledStatement node) => defaultStatement(node);
+  R visitBreakStatement(BreakStatement node) => defaultStatement(node);
+  R visitWhileStatement(WhileStatement node) => defaultStatement(node);
+  R visitDoStatement(DoStatement node) => defaultStatement(node);
+  R visitForStatement(ForStatement node) => defaultStatement(node);
+  R visitForInStatement(ForInStatement node) => defaultStatement(node);
+  R visitSwitchStatement(SwitchStatement node) => defaultStatement(node);
+  R visitContinueSwitchStatement(ContinueSwitchStatement node) =>
+      defaultStatement(node);
+  R visitIfStatement(IfStatement node) => defaultStatement(node);
+  R visitReturnStatement(ReturnStatement node) => defaultStatement(node);
+  R visitTryCatch(TryCatch node) => defaultStatement(node);
+  R visitTryFinally(TryFinally node) => defaultStatement(node);
+  R visitYieldStatement(YieldStatement node) => defaultStatement(node);
+  R visitVariableDeclaration(VariableDeclaration node) =>
+      defaultStatement(node);
+  R visitFunctionDeclaration(FunctionDeclaration node) =>
+      defaultStatement(node);
+}
+
+abstract class MemberVisitor<R> {
+  R defaultMember(Member node) => null;
+
+  R visitConstructor(Constructor node) => defaultMember(node);
+  R visitProcedure(Procedure node) => defaultMember(node);
+  R visitField(Field node) => defaultMember(node);
+}
+
+abstract class InitializerVisitor<R> {
+  R defaultInitializer(Initializer node) => null;
+
+  R visitInvalidInitializer(InvalidInitializer node) =>
+      defaultInitializer(node);
+  R visitFieldInitializer(FieldInitializer node) => defaultInitializer(node);
+  R visitSuperInitializer(SuperInitializer node) => defaultInitializer(node);
+  R visitRedirectingInitializer(RedirectingInitializer node) =>
+      defaultInitializer(node);
+  R visitLocalInitializer(LocalInitializer node) => defaultInitializer(node);
+}
+
+class TreeVisitor<R>
+    implements
+        ExpressionVisitor<R>,
+        StatementVisitor<R>,
+        MemberVisitor<R>,
+        InitializerVisitor<R> {
+  R defaultTreeNode(TreeNode node) => null;
+
+  // Expressions
+  R defaultExpression(Expression node) => defaultTreeNode(node);
+  R defaultBasicLiteral(BasicLiteral node) => defaultExpression(node);
+  R visitInvalidExpression(InvalidExpression node) => defaultExpression(node);
+  R visitVariableGet(VariableGet node) => defaultExpression(node);
+  R visitVariableSet(VariableSet node) => defaultExpression(node);
+  R visitPropertyGet(PropertyGet node) => defaultExpression(node);
+  R visitPropertySet(PropertySet node) => defaultExpression(node);
+  R visitDirectPropertyGet(DirectPropertyGet node) => defaultExpression(node);
+  R visitDirectPropertySet(DirectPropertySet node) => defaultExpression(node);
+  R visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node);
+  R visitSuperPropertySet(SuperPropertySet node) => defaultExpression(node);
+  R visitStaticGet(StaticGet node) => defaultExpression(node);
+  R visitStaticSet(StaticSet node) => defaultExpression(node);
+  R visitMethodInvocation(MethodInvocation node) => defaultExpression(node);
+  R visitDirectMethodInvocation(DirectMethodInvocation node) =>
+      defaultExpression(node);
+  R visitSuperMethodInvocation(SuperMethodInvocation node) =>
+      defaultExpression(node);
+  R visitStaticInvocation(StaticInvocation node) => defaultExpression(node);
+  R visitConstructorInvocation(ConstructorInvocation node) =>
+      defaultExpression(node);
+  R visitNot(Not node) => defaultExpression(node);
+  R visitLogicalExpression(LogicalExpression node) => defaultExpression(node);
+  R visitConditionalExpression(ConditionalExpression node) =>
+      defaultExpression(node);
+  R visitStringConcatenation(StringConcatenation node) =>
+      defaultExpression(node);
+  R visitIsExpression(IsExpression node) => defaultExpression(node);
+  R visitAsExpression(AsExpression node) => defaultExpression(node);
+  R visitSymbolLiteral(SymbolLiteral node) => defaultExpression(node);
+  R visitTypeLiteral(TypeLiteral node) => defaultExpression(node);
+  R visitThisExpression(ThisExpression node) => defaultExpression(node);
+  R visitRethrow(Rethrow node) => defaultExpression(node);
+  R visitThrow(Throw node) => defaultExpression(node);
+  R visitListLiteral(ListLiteral node) => defaultExpression(node);
+  R visitMapLiteral(MapLiteral node) => defaultExpression(node);
+  R visitAwaitExpression(AwaitExpression node) => defaultExpression(node);
+  R visitFunctionExpression(FunctionExpression node) => defaultExpression(node);
+  R visitStringLiteral(StringLiteral node) => defaultBasicLiteral(node);
+  R visitIntLiteral(IntLiteral node) => defaultBasicLiteral(node);
+  R visitDoubleLiteral(DoubleLiteral node) => defaultBasicLiteral(node);
+  R visitBoolLiteral(BoolLiteral node) => defaultBasicLiteral(node);
+  R visitNullLiteral(NullLiteral node) => defaultBasicLiteral(node);
+  R visitLet(Let node) => defaultExpression(node);
+
+  // Statements
+  R defaultStatement(Statement node) => defaultTreeNode(node);
+  R visitInvalidStatement(InvalidStatement node) => defaultStatement(node);
+  R visitExpressionStatement(ExpressionStatement node) =>
+      defaultStatement(node);
+  R visitBlock(Block node) => defaultStatement(node);
+  R visitEmptyStatement(EmptyStatement node) => defaultStatement(node);
+  R visitAssertStatement(AssertStatement node) => defaultStatement(node);
+  R visitLabeledStatement(LabeledStatement node) => defaultStatement(node);
+  R visitBreakStatement(BreakStatement node) => defaultStatement(node);
+  R visitWhileStatement(WhileStatement node) => defaultStatement(node);
+  R visitDoStatement(DoStatement node) => defaultStatement(node);
+  R visitForStatement(ForStatement node) => defaultStatement(node);
+  R visitForInStatement(ForInStatement node) => defaultStatement(node);
+  R visitSwitchStatement(SwitchStatement node) => defaultStatement(node);
+  R visitContinueSwitchStatement(ContinueSwitchStatement node) =>
+      defaultStatement(node);
+  R visitIfStatement(IfStatement node) => defaultStatement(node);
+  R visitReturnStatement(ReturnStatement node) => defaultStatement(node);
+  R visitTryCatch(TryCatch node) => defaultStatement(node);
+  R visitTryFinally(TryFinally node) => defaultStatement(node);
+  R visitYieldStatement(YieldStatement node) => defaultStatement(node);
+  R visitVariableDeclaration(VariableDeclaration node) =>
+      defaultStatement(node);
+  R visitFunctionDeclaration(FunctionDeclaration node) =>
+      defaultStatement(node);
+
+  // Members
+  R defaultMember(Member node) => defaultTreeNode(node);
+  R visitConstructor(Constructor node) => defaultMember(node);
+  R visitProcedure(Procedure node) => defaultMember(node);
+  R visitField(Field node) => defaultMember(node);
+
+  // Classes
+  R visitClass(Class node) => defaultTreeNode(node);
+
+  // Initializers
+  R defaultInitializer(Initializer node) => defaultTreeNode(node);
+  R visitInvalidInitializer(InvalidInitializer node) =>
+      defaultInitializer(node);
+  R visitFieldInitializer(FieldInitializer node) => defaultInitializer(node);
+  R visitSuperInitializer(SuperInitializer node) => defaultInitializer(node);
+  R visitRedirectingInitializer(RedirectingInitializer node) =>
+      defaultInitializer(node);
+  R visitLocalInitializer(LocalInitializer node) => defaultInitializer(node);
+
+  // Other tree nodes
+  R visitLibrary(Library node) => defaultTreeNode(node);
+  R visitTypeParameter(TypeParameter node) => defaultTreeNode(node);
+  R visitFunctionNode(FunctionNode node) => defaultTreeNode(node);
+  R visitArguments(Arguments node) => defaultTreeNode(node);
+  R visitNamedExpression(NamedExpression node) => defaultTreeNode(node);
+  R visitSwitchCase(SwitchCase node) => defaultTreeNode(node);
+  R visitCatch(Catch node) => defaultTreeNode(node);
+  R visitMapEntry(MapEntry node) => defaultTreeNode(node);
+  R visitProgram(Program node) => defaultTreeNode(node);
+}
+
+class DartTypeVisitor<R> {
+  R defaultDartType(DartType node) => null;
+
+  R visitInvalidType(InvalidType node) => defaultDartType(node);
+  R visitDynamicType(DynamicType node) => defaultDartType(node);
+  R visitVoidType(VoidType node) => defaultDartType(node);
+  R visitBottomType(BottomType node) => defaultDartType(node);
+  R visitInterfaceType(InterfaceType node) => defaultDartType(node);
+  R visitFunctionType(FunctionType node) => defaultDartType(node);
+  R visitTypeParameterType(TypeParameterType node) => defaultDartType(node);
+}
+
+class MemberReferenceVisitor<R> {
+  R defaultMemberReference(Member node) => null;
+
+  R visitFieldReference(Field node) => defaultMemberReference(node);
+  R visitConstructorReference(Constructor node) => defaultMemberReference(node);
+  R visitProcedureReference(Procedure node) => defaultMemberReference(node);
+}
+
+class Visitor<R> extends TreeVisitor<R>
+    implements
+        DartTypeVisitor<R>,
+        MemberReferenceVisitor<R> {
+  /// The catch-all case, except for references.
+  R defaultNode(Node node) => null;
+  R defaultTreeNode(TreeNode node) => defaultNode(node);
+
+  /// Inferred values
+  R visitInferredValue(InferredValue node) => defaultNode(node);
+
+  // DartTypes
+  R defaultDartType(DartType node) => defaultNode(node);
+  R visitInvalidType(InvalidType node) => defaultDartType(node);
+  R visitDynamicType(DynamicType node) => defaultDartType(node);
+  R visitVoidType(VoidType node) => defaultDartType(node);
+  R visitBottomType(BottomType node) => defaultDartType(node);
+  R visitInterfaceType(InterfaceType node) => defaultDartType(node);
+  R visitFunctionType(FunctionType node) => defaultDartType(node);
+  R visitTypeParameterType(TypeParameterType node) => defaultDartType(node);
+
+  // Class references
+  R visitClassReference(Class node) => null;
+
+  // Member references
+  R defaultMemberReference(Member node) => null;
+  R visitFieldReference(Field node) => defaultMemberReference(node);
+  R visitConstructorReference(Constructor node) => defaultMemberReference(node);
+  R visitProcedureReference(Procedure node) => defaultMemberReference(node);
+
+  R visitName(Name node) => defaultNode(node);
+  R visitSupertype(Supertype node) => defaultNode(node);
+  R visitNamedType(NamedType node) => defaultNode(node);
+}
+
+class RecursiveVisitor<R> extends Visitor<R> {
+  R defaultNode(Node node) {
+    node.visitChildren(this);
+    return null;
+  }
+}
+
+/// Visitor that recursively rewrites each node in tree.
+///
+/// Visit methods should return a new node, or the visited node (possibly
+/// mutated), or any node from the visited node's subtree.
+///
+/// Each subclass is responsible for ensuring that the AST remains a tree.
+///
+/// For example, the following transformer replaces every occurrence of
+/// `!(x && y)` with `(!x || !y)`:
+///
+///     class NegationSinker extends Transformer {
+///       @override
+///       Node visitNot(Not node) {
+///         var operand = node.operand.accept(this); // Remember to visit.
+///         if (operand is LogicalExpression && operand.operator == '&&') {
+///           return new LogicalExpression(
+///             new Not(operand.left),
+///             '||',
+///             new Not(operand.right));
+///         }
+///         return node;
+///       }
+///     }
+///
+class Transformer extends TreeVisitor<TreeNode> {
+  /// Replaces a use of a type.
+  ///
+  /// By default, recursion stops at this point.
+  DartType visitDartType(DartType node) => node;
+
+  Supertype visitSupertype(Supertype node) => node;
+
+  TreeNode defaultTreeNode(TreeNode node) {
+    node.transformChildren(this);
+    return node;
+  }
+}
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
new file mode 100644
index 0000000..d4f3420
--- /dev/null
+++ b/pkg/kernel/pubspec.yaml
@@ -0,0 +1,19 @@
+name: kernel
+version: 0.2.0
+author: Dart Team <misc@dartlang.org>
+description: Dart IR (Intermediate Representation)
+homepage: https://github.com/dart-lang/kernel
+environment:
+  sdk: ">=1.8.0"
+dependencies:
+  analyzer: ^0.29.0
+  path: ^1.3.9
+  args: ^0.13.4
+  logging: ^0.11.2
+  package_config: ^1.0.0
+dev_dependencies:
+  test: ^0.12.15+6
+  stack_trace: ^1.6.6
+  ansicolor: ^0.0.9
+dependency_overrides:
+  analyzer: {path: ../analyzer}
diff --git a/pkg/kernel/test/ast_membench.dart b/pkg/kernel/test/ast_membench.dart
new file mode 100644
index 0000000..47eda46
--- /dev/null
+++ b/pkg/kernel/test/ast_membench.dart
@@ -0,0 +1,34 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'dart:io';
+
+/// Builds N copies of the AST for the given program.
+/// Pass --print-metrics to the Dart VM to measure the memory use.
+main(List<String> args) {
+  if (args.length == 0) {
+    print('USAGE: ast_membench FILE.dill NUM_COPIES');
+    exit(1);
+  }
+  String filename = args[0];
+
+  const int defaultCopyCount = 10;
+  int copyCount = args.length == 2 ? int.parse(args[1]) : defaultCopyCount;
+  List<Program> keepAlive = <Program>[];
+  for (int i = 0; i < copyCount; ++i) {
+    keepAlive.add(loadProgramFromBinary(filename));
+  }
+
+  print('$copyCount copies built');
+
+  if (args.contains('-v')) {
+    // Use of the list for something to avoid premature GC.
+    int size = 0;
+    for (var program in keepAlive) {
+      size += program.libraries.length;
+    }
+    print(size);
+  }
+}
diff --git a/pkg/kernel/test/baseline_spec_mode_test_disabled.dart b/pkg/kernel/test/baseline_spec_mode_test_disabled.dart
new file mode 100644
index 0000000..f365d78
--- /dev/null
+++ b/pkg/kernel/test/baseline_spec_mode_test_disabled.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/transformations/mixin_full_resolution.dart';
+
+import 'baseline_tester.dart';
+
+class SpecModeTest extends TestTarget {
+  @override
+  List<String> get extraRequiredLibraries => [];
+
+  @override
+  String get name => 'spec-mode-test';
+
+  @override
+  bool get strongMode => false;
+
+  @override
+  List<String> transformProgram(Program program) {
+    new MixinFullResolution().transform(program);
+    return const <String>[];
+  }
+}
+
+void main() {
+  runBaselineTests('spec-mode', new SpecModeTest());
+}
diff --git a/pkg/kernel/test/baseline_strong_mode_test_disabled.dart b/pkg/kernel/test/baseline_strong_mode_test_disabled.dart
new file mode 100644
index 0000000..51d2a7c
--- /dev/null
+++ b/pkg/kernel/test/baseline_strong_mode_test_disabled.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/mixin_full_resolution.dart';
+import 'package:kernel/type_checker.dart';
+import 'package:path/path.dart' as pathlib;
+
+import 'baseline_tester.dart';
+
+class StrongModeTest extends TestTarget {
+  @override
+  List<String> get extraRequiredLibraries => [];
+
+  @override
+  String get name => 'strong-mode-test';
+
+  @override
+  bool get strongMode => true;
+
+  @override
+  List<String> transformProgram(Program program) {
+    List<String> errors = <String>[];
+    new MixinFullResolution().transform(program);
+    new TestTypeChecker(
+            errors, new CoreTypes(program), new ClassHierarchy(program))
+        .checkProgram(program);
+    return errors;
+  }
+}
+
+class TestTypeChecker extends TypeChecker {
+  final List<String> errors;
+
+  TestTypeChecker(this.errors, CoreTypes coreTypes, ClassHierarchy hierarchy)
+      : super(coreTypes, hierarchy);
+
+  @override
+  void checkAssignable(TreeNode where, DartType from, DartType to) {
+    if (!environment.isSubtypeOf(from, to)) {
+      fail(where, '$from is not a subtype of $to');
+    }
+  }
+
+  @override
+  void fail(TreeNode where, String message) {
+    var location = where.location;
+    var locationString;
+    if (location != null) {
+      var file = pathlib.basename(Uri.parse(location.file).path);
+      locationString = '($file:${location.line}:${location.column})';
+    } else {
+      locationString = '(no location)';
+    }
+    errors.add('$message $locationString');
+  }
+}
+
+void main() {
+  runBaselineTests('strong-mode', new StrongModeTest());
+}
diff --git a/pkg/kernel/test/baseline_tester.dart b/pkg/kernel/test/baseline_tester.dart
new file mode 100644
index 0000000..c2c47e5
--- /dev/null
+++ b/pkg/kernel/test/baseline_tester.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'dart:io';
+
+import 'package:kernel/analyzer/loader.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/text/ast_to_text.dart';
+import 'package:kernel/verifier.dart';
+import 'package:path/path.dart' as pathlib;
+import 'package:test/test.dart';
+
+final String testcaseDirectory = 'pkg/kernel/testcases';
+final String inputDirectory = 'pkg/kernel/testcases/input';
+final String sdkDirectory = 'sdk';
+
+/// A target to be used for testing.
+///
+/// To simplify testing dependencies, we avoid transformations that rely on
+/// a patched SDK or any SDK changes that have not landed in the main SDK.
+abstract class TestTarget extends Target {
+  /// Annotations to apply on the textual output.
+  Annotator get annotator => null;
+
+  List<String> transformProgram(Program program);
+}
+
+void runBaselineTests(String folderName, TestTarget target) {
+  String outputDirectory = '$testcaseDirectory/$folderName';
+  var batch = new DartLoaderBatch();
+  Directory directory = new Directory(inputDirectory);
+  for (FileSystemEntity file in directory.listSync()) {
+    if (file is File && file.path.endsWith('.dart')) {
+      String name = pathlib.basename(file.path);
+      test(name, () async {
+        String dartPath = file.path;
+        String shortName = pathlib.withoutExtension(name);
+        String filenameOfBaseline = '$outputDirectory/$shortName.baseline.txt';
+        String filenameOfCurrent = '$outputDirectory/$shortName.current.txt';
+
+        var repository = new Repository();
+        var loader = await batch.getLoader(
+            repository,
+            new DartOptions(
+                strongMode: target.strongMode,
+                sdk: sdkDirectory,
+                declaredVariables: target.extraDeclaredVariables));
+        var program = loader.loadProgram(dartPath, target: target);
+        verifyProgram(program);
+        var errors = target.transformProgram(program);
+        verifyProgram(program);
+
+        var buffer = new StringBuffer();
+        for (var error in errors) {
+          buffer.writeln('// $error');
+        }
+        new Printer(buffer, annotator: target.annotator)
+            .writeLibraryFile(program.mainMethod.enclosingLibrary);
+        String current = '$buffer';
+        new File(filenameOfCurrent).writeAsStringSync(current);
+
+        var baselineFile = new File(filenameOfBaseline);
+        if (!baselineFile.existsSync()) {
+          new File(filenameOfBaseline).writeAsStringSync(current);
+        } else {
+          var baseline = baselineFile.readAsStringSync();
+          if (baseline != current) {
+            fail('Output of `$name` changed for $folderName.\n'
+                'Command to reset the baseline:\n'
+                '  rm $filenameOfBaseline\n'
+                'Command to see the diff:\n'
+                '  diff -cd $outputDirectory/$shortName.{baseline,current}.txt'
+                '\n');
+          }
+        }
+      });
+    }
+  }
+}
diff --git a/pkg/kernel/test/baseline_type_propagation_test_disabled.dart b/pkg/kernel/test/baseline_type_propagation_test_disabled.dart
new file mode 100644
index 0000000..3911df3
--- /dev/null
+++ b/pkg/kernel/test/baseline_type_propagation_test_disabled.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/text/ast_to_text.dart';
+import 'package:kernel/transformations/mixin_full_resolution.dart';
+import 'package:kernel/type_propagation/builder.dart';
+import 'package:kernel/type_propagation/solver.dart';
+import 'package:kernel/type_propagation/visualizer.dart';
+
+import 'baseline_tester.dart';
+
+class TypePropagationTest extends TestTarget {
+  @override
+  Annotator annotator;
+
+  @override
+  List<String> get extraRequiredLibraries => [];
+
+  @override
+  String get name => 'type-propagation-test';
+
+  @override
+  bool get strongMode => false;
+
+  @override
+  List<String> transformProgram(Program program) {
+    new MixinFullResolution().transform(program);
+    var visualizer = new Visualizer(program);
+    var builder = new Builder(program, visualizer: visualizer);
+    var solver = new Solver(builder);
+    solver.solve();
+    visualizer.solver = solver;
+    annotator = new TextAnnotator(visualizer);
+    return const <String>[];
+  }
+}
+
+void main() {
+  runBaselineTests('type-propagation', new TypePropagationTest());
+}
diff --git a/pkg/kernel/test/batch_consistency.dart b/pkg/kernel/test/batch_consistency.dart
new file mode 100644
index 0000000..7a098df
--- /dev/null
+++ b/pkg/kernel/test/batch_consistency.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.batch_consistency;
+
+import 'dart:async';
+import 'dart:io';
+import '../bin/dartk.dart' as dartk;
+import '../bin/batch_util.dart';
+import 'package:path/path.dart' as pathlib;
+import 'package:test/test.dart';
+
+String usage = """
+Usage: batch_consistency [options] -- files...
+
+Run dartk on the given files, both separately and in a batch, and check that
+the output is identical for the two modes.
+""";
+
+const String outputDir = 'out/batch-consistency';
+
+main(List<String> args) async {
+  int separator = args.indexOf('--');
+  if (separator == -1) {
+    print(usage);
+    exit(1);
+  }
+
+  List<String> options = args.sublist(0, separator);
+  List<String> files = args.sublist(separator + 1);
+
+  await new Directory(outputDir).create(recursive: true);
+
+  testBatchModeConsistency(options, files);
+}
+
+Future<bool> areFilesEqual(String first, String second) async {
+  List<List<int>> bytes = await Future
+      .wait([new File(first).readAsBytes(), new File(second).readAsBytes()]);
+  if (bytes[0].length != bytes[1].length) return false;
+  for (int i = 0; i < bytes[0].length; ++i) {
+    if (bytes[0][i] != bytes[1][i]) return false;
+  }
+  return true;
+}
+
+testBatchModeConsistency(List<String> options, List<String> files) {
+  var sharedState = new dartk.BatchModeState();
+  for (String file in files) {
+    test(file, () async {
+      var name = pathlib.basename(file);
+      List<String> outputFiles = <String>[
+        '$outputDir/$name.batch.dill',
+        '$outputDir/$name.unbatch.dill'
+      ];
+      List results = [null, null];
+      bool failed = false;
+      for (int i = 0; i < 2; ++i) {
+        var args = <String>[]
+          ..addAll(options)
+          ..addAll(['--out', outputFiles[i], file]);
+        var state = (i == 0) ? sharedState : new dartk.BatchModeState();
+        try {
+          // We run the two executions in a loop to ensure any stack traces
+          // are identical in case they both crash at the same place.
+          // Crashing at the same place is acceptable for the purpose of
+          // this test, there are other tests that check for crashes.
+          results[i] = await dartk.batchMain(args, state);
+        } catch (e) {
+          results[i] = '$e';
+          failed = true;
+        }
+      }
+      if (results[0] != results[1]) {
+        fail('Batch mode returned ${results[0]}, expected ${results[1]}');
+        return;
+      }
+      if (results[0] == CompilerOutcome.Fail) {
+        failed = true;
+      }
+      if (!failed && !await areFilesEqual(outputFiles[0], outputFiles[1])) {
+        fail('Batch mode output differs for $file');
+      }
+    });
+  }
+}
diff --git a/pkg/kernel/test/class_hierarchy_basic.dart b/pkg/kernel/test/class_hierarchy_basic.dart
new file mode 100644
index 0000000..601bf04
--- /dev/null
+++ b/pkg/kernel/test/class_hierarchy_basic.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.class_hierarchy_basic;
+
+import 'package:kernel/type_algebra.dart';
+import 'package:kernel/ast.dart';
+
+/// A simple implementation of the class hierarchy interface using
+/// hash tables for everything.
+class BasicClassHierarchy {
+  final Map<Class, Set<Class>> superclasses = <Class, Set<Class>>{};
+  final Map<Class, Set<Class>> superMixtures = <Class, Set<Class>>{};
+  final Map<Class, Set<Class>> supertypes = <Class, Set<Class>>{};
+  final Map<Class, Map<Class, Supertype>> supertypeInstantiations =
+      <Class, Map<Class, Supertype>>{};
+  final Map<Class, Map<Name, Member>> gettersAndCalls =
+      <Class, Map<Name, Member>>{};
+  final Map<Class, Map<Name, Member>> setters = <Class, Map<Name, Member>>{};
+  final Map<Class, Map<Name, List<Member>>> interfaceGettersAndCalls =
+      <Class, Map<Name, List<Member>>>{};
+  final Map<Class, Map<Name, List<Member>>> interfaceSetters =
+      <Class, Map<Name, List<Member>>>{};
+  final List<Class> classes = <Class>[];
+  final Map<Class, int> classIndex = <Class, int>{};
+
+  BasicClassHierarchy(Program program) {
+    for (var library in program.libraries) {
+      for (var classNode in library.classes) {
+        buildSuperTypeSets(classNode);
+        buildSuperTypeInstantiations(classNode);
+        buildDispatchTable(classNode);
+        buildInterfaceTable(classNode);
+      }
+    }
+  }
+
+  void forEachOverridePair(
+      Class class_, callback(Member member, Member superMember, bool setter)) {
+    void report(Member member, Member superMember, bool setter) {
+      if (!identical(member, superMember)) {
+        callback(member, superMember, setter);
+      }
+    }
+    // Report declared members overriding inheritable members.
+    for (var member in class_.mixin.members) {
+      for (var supertype in class_.supers) {
+        if (member.hasGetter) {
+          for (var superMember
+              in getInterfaceMembersByName(supertype.classNode, member.name)) {
+            report(member, superMember, false);
+          }
+        }
+        if (member.hasSetter) {
+          for (var superMember in getInterfaceMembersByName(
+              supertype.classNode, member.name,
+              setter: true)) {
+            report(member, superMember, true);
+          }
+        }
+      }
+    }
+    // Report inherited non-abstract members overriding inheritable or
+    // declared members.
+    for (var setter in [true, false]) {
+      for (var member in getDispatchTargets(class_, setters: setter)) {
+        // Report overriding inheritable members.
+        for (var supertype in class_.supers) {
+          for (var superMember in getInterfaceMembersByName(
+              supertype.classNode, member.name,
+              setter: setter)) {
+            report(member, superMember, setter);
+          }
+        }
+        // Report overriding declared abstract members.
+        if (!class_.isAbstract && member.enclosingClass != class_.mixin) {
+          for (var declaredMember in getInterfaceMembersByName(
+              class_, member.name,
+              setter: setter)) {
+            report(member, declaredMember, setter);
+          }
+        }
+      }
+    }
+  }
+
+  void buildSuperTypeSets(Class node) {
+    if (superclasses.containsKey(node)) return;
+    superclasses[node] = new Set<Class>()..add(node);
+    superMixtures[node] = new Set<Class>()..add(node);
+    supertypes[node] = new Set<Class>()..add(node);
+    if (node.supertype != null) {
+      buildSuperTypeSets(node.supertype.classNode);
+      superclasses[node].addAll(superclasses[node.supertype.classNode]);
+      superMixtures[node].addAll(superMixtures[node.supertype.classNode]);
+      supertypes[node].addAll(supertypes[node.supertype.classNode]);
+    }
+    if (node.mixedInType != null) {
+      buildSuperTypeSets(node.mixedInType.classNode);
+      superMixtures[node].addAll(superMixtures[node.mixedInType.classNode]);
+      supertypes[node].addAll(supertypes[node.mixedInType.classNode]);
+    }
+    for (var supertype in node.implementedTypes) {
+      buildSuperTypeSets(supertype.classNode);
+      supertypes[node].addAll(supertypes[supertype.classNode]);
+    }
+    classes.add(node);
+    classIndex[node] = classes.length - 1;
+  }
+
+  void buildSuperTypeInstantiations(Class node) {
+    if (supertypeInstantiations.containsKey(node)) return;
+    supertypeInstantiations[node] = <Class, Supertype>{
+      node: node.asThisSupertype
+    };
+    for (var supertype in node.supers) {
+      var superclass = supertype.classNode;
+      buildSuperTypeInstantiations(superclass);
+      var substitution = Substitution.fromPairs(
+          superclass.typeParameters, supertype.typeArguments);
+      supertypeInstantiations[superclass].forEach((key, type) {
+        supertypeInstantiations[node][key] =
+            substitution.substituteSupertype(type);
+      });
+    }
+  }
+
+  void buildDispatchTable(Class node) {
+    if (gettersAndCalls.containsKey(node)) return;
+    gettersAndCalls[node] = <Name, Member>{};
+    setters[node] = <Name, Member>{};
+    if (node.supertype != null) {
+      buildDispatchTable(node.supertype.classNode);
+      gettersAndCalls[node].addAll(gettersAndCalls[node.supertype.classNode]);
+      setters[node].addAll(setters[node.supertype.classNode]);
+    }
+    // Overwrite map entries with declared members.
+    Class mixin = node.mixedInType?.classNode ?? node;
+    for (Procedure procedure in mixin.procedures) {
+      if (procedure.isStatic || procedure.isAbstract) continue;
+      if (procedure.kind == ProcedureKind.Setter) {
+        setters[node][procedure.name] = procedure;
+      } else {
+        gettersAndCalls[node][procedure.name] = procedure;
+      }
+    }
+    for (Field field in mixin.fields) {
+      if (field.isStatic) continue;
+      gettersAndCalls[node][field.name] = field;
+      if (!field.isFinal) {
+        setters[node][field.name] = field;
+      }
+    }
+  }
+
+  void mergeMaps(
+      Map<Name, List<Member>> source, Map<Name, List<Member>> destination) {
+    for (var name in source.keys) {
+      destination.putIfAbsent(name, () => <Member>[]).addAll(source[name]);
+    }
+  }
+
+  void buildInterfaceTable(Class node) {
+    if (interfaceGettersAndCalls.containsKey(node)) return;
+    interfaceGettersAndCalls[node] = <Name, List<Member>>{};
+    interfaceSetters[node] = <Name, List<Member>>{};
+    void inheritFrom(Supertype type) {
+      if (type == null) return;
+      buildInterfaceTable(type.classNode);
+      mergeMaps(interfaceGettersAndCalls[type.classNode],
+          interfaceGettersAndCalls[node]);
+      mergeMaps(interfaceSetters[type.classNode], interfaceSetters[node]);
+    }
+    inheritFrom(node.supertype);
+    inheritFrom(node.mixedInType);
+    node.implementedTypes.forEach(inheritFrom);
+    // Overwrite map entries with declared members.
+    for (Procedure procedure in node.mixin.procedures) {
+      if (procedure.isStatic) continue;
+      if (procedure.kind == ProcedureKind.Setter) {
+        interfaceSetters[node][procedure.name] = <Member>[procedure];
+      } else {
+        interfaceGettersAndCalls[node][procedure.name] = <Member>[procedure];
+      }
+    }
+    for (Field field in node.mixin.fields) {
+      if (field.isStatic) continue;
+      interfaceGettersAndCalls[node][field.name] = <Member>[field];
+      if (!field.isFinal) {
+        interfaceSetters[node][field.name] = <Member>[field];
+      }
+    }
+  }
+
+  bool isSubclassOf(Class subtype, Class supertype) {
+    return superclasses[subtype].contains(supertype);
+  }
+
+  bool isSubmixtureOf(Class subtype, Class supertype) {
+    return superMixtures[subtype].contains(supertype);
+  }
+
+  bool isSubtypeOf(Class subtype, Class supertype) {
+    return supertypes[subtype].contains(supertype);
+  }
+
+  Supertype getClassAsInstanceOf(Class type, Class supertype) {
+    return supertypeInstantiations[type][supertype];
+  }
+
+  Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
+    return setter ? setters[class_][name] : gettersAndCalls[class_][name];
+  }
+
+  Iterable<Member> getDispatchTargets(Class class_, {bool setters: false}) {
+    return setters
+        ? this.setters[class_].values
+        : gettersAndCalls[class_].values;
+  }
+
+  Member tryFirst(List<Member> members) {
+    return (members == null || members.isEmpty) ? null : members[0];
+  }
+
+  Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
+    return tryFirst(getInterfaceMembersByName(class_, name, setter: setter));
+  }
+
+  Iterable<Member> getInterfaceMembersByName(Class class_, Name name,
+      {bool setter: false}) {
+    var iterable = setter
+        ? interfaceSetters[class_][name]
+        : interfaceGettersAndCalls[class_][name];
+    return iterable == null ? const <Member>[] : iterable;
+  }
+
+  Iterable<Member> getInterfaceMembers(Class class_, {bool setters: false}) {
+    return setters
+        ? interfaceSetters[class_].values.expand((x) => x)
+        : interfaceGettersAndCalls[class_].values.expand((x) => x);
+  }
+
+  int getClassIndex(Class node) {
+    return classIndex[node];
+  }
+
+  List<int> getExpenseHistogram() => <int>[];
+  double getCompressionRatio() => 0.0;
+  int getSuperTypeHashTableSize() => 0;
+
+  noSuchMethod(inv) => super.noSuchMethod(inv);
+}
diff --git a/pkg/kernel/test/class_hierarchy_bench.dart b/pkg/kernel/test/class_hierarchy_bench.dart
new file mode 100644
index 0000000..11fdb7a
--- /dev/null
+++ b/pkg/kernel/test/class_hierarchy_bench.dart
@@ -0,0 +1,345 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:args/args.dart';
+import 'class_hierarchy_basic.dart';
+import 'dart:math';
+import 'dart:io';
+
+ArgParser argParser = new ArgParser()
+  ..addFlag('basic', help: 'Measure the basic implementation', negatable: false)
+  ..addOption('cycle',
+      abbr: 'c',
+      help: 'Build N copies of the class hierarchy and cycle queries '
+          'between them',
+      defaultsTo: '1');
+
+String usage = '''
+Usage: class_hierarchy_bench [options] FILE.dart
+
+Options:
+${argParser.usage}
+''';
+
+main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = argParser.parse(args);
+  if (options.rest.length != 1) {
+    print('Exactly one file must be given');
+    exit(1);
+  }
+  String filename = options.rest.single;
+
+  Program program = loadProgramFromBinary(filename);
+
+  ClassHierarchy buildHierarchy() {
+    return options['basic']
+        ? new BasicClassHierarchy(program)
+        : new ClassHierarchy(program);
+  }
+
+  var watch = new Stopwatch()..start();
+  buildHierarchy();
+  int coldBuildTime = watch.elapsedMilliseconds;
+  watch.reset();
+  const int numBuildTrials = 100;
+  for (int i = 0; i < numBuildTrials; i++) {
+    buildHierarchy();
+  }
+  int hotBuildTime = watch.elapsedMilliseconds ~/ numBuildTrials;
+
+  int hierarchyCount = int.parse(options['cycle']);
+  var hierarchies = <ClassHierarchy>[];
+  for (int i = 0; i < hierarchyCount; i++) {
+    hierarchies.add(buildHierarchy());
+  }
+
+  int currentHierarchy = 0;
+  ClassHierarchy getClassHierarchy() {
+    currentHierarchy = (currentHierarchy + 1) % hierarchies.length;
+    return hierarchies[currentHierarchy];
+  }
+
+  Random rnd = new Random(12345);
+  const int numQueryTrials = 100000;
+
+  // Measure isSubclassOf, isSubmixtureOf, isSubtypeOf, getClassAsInstanceOf.
+
+  // Warm-up run to ensure the JIT compiler does not favor the first query we
+  // test.
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int first = rnd.nextInt(classHierarchy.classes.length);
+    int second = rnd.nextInt(classHierarchy.classes.length);
+    Class firstClass = classHierarchy.classes[first];
+    Class secondClass = classHierarchy.classes[second];
+    classHierarchy.isSubclassOf(firstClass, secondClass);
+    classHierarchy.isSubmixtureOf(firstClass, secondClass);
+    classHierarchy.isSubtypeOf(firstClass, secondClass);
+    classHierarchy.getClassAsInstanceOf(firstClass, secondClass);
+  }
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int first = rnd.nextInt(classHierarchy.classes.length);
+    int second = rnd.nextInt(classHierarchy.classes.length);
+    Class firstClass = classHierarchy.classes[first];
+    Class secondClass = classHierarchy.classes[second];
+    classHierarchy.isSubclassOf(firstClass, secondClass);
+  }
+  int subclassQueryTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int first = rnd.nextInt(classHierarchy.classes.length);
+    int second = rnd.nextInt(classHierarchy.classes.length);
+    Class firstClass = classHierarchy.classes[first];
+    Class secondClass = classHierarchy.classes[second];
+    classHierarchy.isSubmixtureOf(firstClass, secondClass);
+  }
+  int submixtureQueryTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int first = rnd.nextInt(classHierarchy.classes.length);
+    int second = rnd.nextInt(classHierarchy.classes.length);
+    Class firstClass = classHierarchy.classes[first];
+    Class secondClass = classHierarchy.classes[second];
+    classHierarchy.isSubtypeOf(firstClass, secondClass);
+  }
+  int subtypeQueryTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int first = rnd.nextInt(classHierarchy.classes.length);
+    int second = rnd.nextInt(classHierarchy.classes.length);
+    Class firstClass = classHierarchy.classes[first];
+    Class secondClass = classHierarchy.classes[second];
+    classHierarchy.getClassAsInstanceOf(firstClass, secondClass);
+  }
+  int asInstanceOfQueryTime = watch.elapsedMicroseconds;
+
+  // Estimate the overhead from test case generation.
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int first = rnd.nextInt(classHierarchy.classes.length);
+    int second = rnd.nextInt(classHierarchy.classes.length);
+    classHierarchy.classes[first];
+    classHierarchy.classes[second];
+  }
+  int queryNoise = watch.elapsedMicroseconds;
+
+  subclassQueryTime -= queryNoise;
+  submixtureQueryTime -= queryNoise;
+  subtypeQueryTime -= queryNoise;
+  asInstanceOfQueryTime -= queryNoise;
+
+  String subclassPerSecond = perSecond(subclassQueryTime, numQueryTrials);
+  String submixturePerSecond = perSecond(submixtureQueryTime, numQueryTrials);
+  String subtypePerSecond = perSecond(subtypeQueryTime, numQueryTrials);
+  String asInstanceOfPerSecond =
+      perSecond(asInstanceOfQueryTime, numQueryTrials);
+
+  // Measure getDispatchTarget and getDispatchTargets.
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    Class classNode = classHierarchy.classes[classId];
+    classHierarchy.getDispatchTarget(classNode, new Name('toString'));
+  }
+  int dispatchToStringTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    Class classNode = classHierarchy.classes[classId];
+    classHierarchy.getDispatchTarget(classNode, new Name('getFloo'));
+  }
+  int dispatchGenericGetTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    Class classNode = classHierarchy.classes[classId];
+    for (var _ in classHierarchy.getDispatchTargets(classNode)) {}
+  }
+  int dispatchAllTargetsTime = watch.elapsedMicroseconds;
+
+  // Measure getInterfaceMember and getInterfaceMembers.
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    Class classNode = classHierarchy.classes[classId];
+    classHierarchy.getInterfaceMember(classNode, new Name('toString'));
+  }
+  int interfaceToStringTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    Class classNode = classHierarchy.classes[classId];
+    classHierarchy.getInterfaceMember(classNode, new Name('getFloo'));
+  }
+  int interfaceGenericGetTime = watch.elapsedMicroseconds;
+
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    Class classNode = classHierarchy.classes[classId];
+    for (var _ in classHierarchy.getInterfaceMembers(classNode)) {}
+  }
+  int interfaceAllTargetsTime = watch.elapsedMicroseconds;
+
+  // Estimate overhead from test case generation.
+  watch.reset();
+  for (int i = 0; i < numQueryTrials; i++) {
+    var classHierarchy = getClassHierarchy();
+    int classId = rnd.nextInt(classHierarchy.classes.length);
+    classHierarchy.classes[classId];
+  }
+  int dispatchTargetNoise = watch.elapsedMicroseconds;
+
+  dispatchToStringTime -= dispatchTargetNoise;
+  dispatchGenericGetTime -= dispatchTargetNoise;
+  dispatchAllTargetsTime -= dispatchTargetNoise;
+  interfaceToStringTime -= dispatchTargetNoise;
+  interfaceGenericGetTime -= dispatchTargetNoise;
+  interfaceAllTargetsTime -= dispatchTargetNoise;
+
+  String dispatchToStringPerSecond =
+      perSecond(dispatchToStringTime, numQueryTrials);
+  String dispatchGetPerSecond =
+      perSecond(dispatchGenericGetTime, numQueryTrials);
+  String dispatchAllTargetsPerSecond =
+      perSecond(dispatchAllTargetsTime, numQueryTrials);
+
+  String interfaceToStringPerSecond =
+      perSecond(interfaceToStringTime, numQueryTrials);
+  String interfaceGetPerSecond =
+      perSecond(interfaceGenericGetTime, numQueryTrials);
+  String interfaceAllTargetsPerSecond =
+      perSecond(interfaceAllTargetsTime, numQueryTrials);
+
+  watch.reset();
+  var classHierarchy = getClassHierarchy();
+  int numberOfOverridePairs = 0;
+  for (var class_ in classHierarchy.classes) {
+    classHierarchy.forEachOverridePair(class_, (member, supermember, isSetter) {
+      ++numberOfOverridePairs;
+    });
+  }
+  int overrideTime = watch.elapsedMicroseconds;
+
+  String overridePairsPerSecond =
+      perSecond(overrideTime, numberOfOverridePairs);
+
+  List<int> depth = new List(classHierarchy.classes.length);
+  for (int i = 0; i < depth.length; ++i) {
+    int parentDepth = 0;
+    var classNode = classHierarchy.classes[i];
+    for (var supertype in classNode.supers) {
+      var superclass = supertype.classNode;
+      int index = classHierarchy.getClassIndex(superclass);
+      if (!(index < i)) {
+        throw '${classNode.name}($i) extends ${superclass.name}($index)';
+      }
+      assert(index < i);
+      parentDepth = max(parentDepth, depth[index]);
+    }
+    depth[i] = parentDepth + 1;
+  }
+  List<int> depthHistogram = getHistogramOf(depth);
+  double averageDepth = average(depth);
+  double medianDepth = median(depth);
+  int totalDepth = sum(depth);
+
+  int numberOfClasses = classHierarchy.classes.length;
+  String expenseHistogram =
+      classHierarchy.getExpenseHistogram().skip(1).join(' ');
+
+  print('''
+classes: $numberOfClasses
+build.cold: $coldBuildTime ms
+build.hot:  $hotBuildTime ms
+query.isSubclassOf:                 $subclassPerSecond
+query.isSubmixtureOf:               $submixturePerSecond
+query.isSubtypeOf:                  $subtypePerSecond
+query.getClassAsInstanceOf:         $asInstanceOfPerSecond
+query.getDispatchTarget(toString):  $dispatchToStringPerSecond
+query.getDispatchTarget(getFloo):   $dispatchGetPerSecond
+query.getDispatchTargets.iterate:   $dispatchAllTargetsPerSecond
+query.getInterfaceMember(toString): $interfaceToStringPerSecond
+query.getInterfaceMember(getFloo):  $interfaceGetPerSecond
+query.getInterfaceMembers.iterate:  $interfaceAllTargetsPerSecond
+isSubtypeOf.expense-histogram: $expenseHistogram
+isSubtypeOf.compression-ratio: ${classHierarchy.getCompressionRatio()}
+asInstanceOf.table-size: ${classHierarchy.getSuperTypeHashTableSize()}
+depth.histogram: ${depthHistogram.skip(1).join(' ')}
+depth.average: $averageDepth
+depth.median:  $medianDepth
+depth.total:   $totalDepth
+overrides.total:   $numberOfOverridePairs
+overrides.iterate: ${overrideTime ~/ 1000} ms ($overridePairsPerSecond)
+''');
+}
+
+String perSecond(int microseconds, int trials) {
+  double millionsPerSecond = trials / microseconds;
+  return '${millionsPerSecond.toStringAsFixed(1)} M/s';
+}
+
+List<int> getHistogramOf(Iterable<int> values) {
+  List<int> result = <int>[];
+  for (int value in values) {
+    while (result.length <= value) {
+      result.add(0);
+    }
+    ++result[value];
+  }
+  return result;
+}
+
+double average(Iterable<num> values) {
+  double sum = 0.0;
+  int length = 0;
+  for (num x in values) {
+    sum += x;
+    ++length;
+  }
+  return length == 0 ? 0.0 : sum / length;
+}
+
+double median(Iterable<num> values) {
+  List<num> list = values.toList(growable: false)..sort();
+  if (list.isEmpty) return 0.0;
+  int mid = list.length ~/ 2;
+  return list.length % 2 == 0
+      ? ((list[mid] + list[mid + 1]) / 2)
+      : list[mid].toDouble();
+}
+
+num sum(Iterable<num> values) {
+  num result = 0;
+  for (var x in values) {
+    result += x;
+  }
+  return result;
+}
diff --git a/pkg/kernel/test/class_hierarchy_membench.dart b/pkg/kernel/test/class_hierarchy_membench.dart
new file mode 100644
index 0000000..e8f6886
--- /dev/null
+++ b/pkg/kernel/test/class_hierarchy_membench.dart
@@ -0,0 +1,63 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:args/args.dart';
+import 'class_hierarchy_basic.dart';
+import 'dart:io';
+
+ArgParser argParser = new ArgParser()
+  ..addFlag('basic', help: 'Measure the basic implementation', negatable: false)
+  ..addOption('count', abbr: 'c',
+      help: 'Build N copies of the class hierarchy',
+      defaultsTo: '300');
+
+String usage = """
+Usage: class_hierarchy_membench [options] FILE.dart
+
+Options:
+${argParser.usage}
+""";
+
+/// Builds N copies of the class hierarchy for the given program.
+/// Pass --print-metrics to the Dart VM to measure the memory use.
+main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = argParser.parse(args);
+  if (options.rest.length != 1) {
+    print('Exactly one file should be given');
+    exit(1);
+  }
+  String filename = options.rest.single;
+
+  Program program = loadProgramFromBinary(filename);
+
+  int copyCount = int.parse(options['count']);
+
+  ClassHierarchy buildHierarchy() {
+    return options['basic']
+        ? new BasicClassHierarchy(program)
+        : new ClassHierarchy(program);
+  }
+
+  List<ClassHierarchy> keepAlive = <ClassHierarchy>[];
+  for (int i = 0; i < copyCount; ++i) {
+    keepAlive.add(buildHierarchy());
+  }
+
+  print('$copyCount copies built');
+
+  if (args.contains('-v')) {
+    // Use of the list for something to avoid premature GC.
+    int size = 0;
+    for (var classHierarchy in keepAlive) {
+      size += classHierarchy.getSuperTypeHashTableSize();
+    }
+    print(size);
+  }
+}
diff --git a/pkg/kernel/test/class_hierarchy_test_disabled.dart b/pkg/kernel/test/class_hierarchy_test_disabled.dart
new file mode 100644
index 0000000..89e1d7d
--- /dev/null
+++ b/pkg/kernel/test/class_hierarchy_test_disabled.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:test/test.dart';
+import 'class_hierarchy_tester.dart';
+
+main() {
+  test('All-pairs class hierarchy tests on dart2js', () {
+    testClassHierarchyOnProgram(
+        loadProgramFromBinary('test/data/dart2js.dill'));
+  });
+}
diff --git a/pkg/kernel/test/class_hierarchy_tester.dart b/pkg/kernel/test/class_hierarchy_tester.dart
new file mode 100644
index 0000000..d4e04ad
--- /dev/null
+++ b/pkg/kernel/test/class_hierarchy_tester.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:test/test.dart';
+import 'class_hierarchy_basic.dart';
+import 'dart:io';
+import 'dart:math';
+
+void testClassHierarchyOnProgram(Program program, {bool verbose: false}) {
+  BasicClassHierarchy basic = new BasicClassHierarchy(program);
+  ClassHierarchy classHierarchy = new ClassHierarchy(program);
+  int total = classHierarchy.classes.length;
+  int progress = 0;
+  for (var class1 in classHierarchy.classes) {
+    for (var class2 in classHierarchy.classes) {
+      bool isSubclass = classHierarchy.isSubclassOf(class1, class2);
+      bool isSubmixture = classHierarchy.isSubmixtureOf(class1, class2);
+      bool isSubtype = classHierarchy.isSubtypeOf(class1, class2);
+      var asInstance = classHierarchy.getClassAsInstanceOf(class1, class2);
+      if (isSubclass != basic.isSubclassOf(class1, class2)) {
+        fail('isSubclassOf(${class1.name}, ${class2.name}) returned '
+            '$isSubclass but should be ${!isSubclass}');
+      }
+      if (isSubmixture != basic.isSubmixtureOf(class1, class2)) {
+        fail('isSubmixtureOf(${class1.name}, ${class2.name}) returned '
+            '$isSubclass but should be ${!isSubclass}');
+      }
+      if (isSubtype != basic.isSubtypeOf(class1, class2)) {
+        fail('isSubtypeOf(${class1.name}, ${class2.name}) returned '
+            '$isSubtype but should be ${!isSubtype}');
+      }
+      if (asInstance != basic.getClassAsInstanceOf(class1, class2)) {
+        fail('asInstanceOf(${class1.name}, ${class2.name}) returned '
+            '$asInstance but should be '
+            '${basic.getClassAsInstanceOf(class1, class2)}');
+      }
+    }
+    ++progress;
+    if (verbose) {
+      stdout.write('\rSubclass queries ${100 * progress ~/ total}%');
+    }
+  }
+  Set<Name> names = new Set<Name>();
+  for (var classNode in classHierarchy.classes) {
+    for (var member in classNode.members) {
+      names.add(member.name);
+    }
+  }
+  List<Name> nameList = names.toList();
+  progress = 0;
+  for (var classNode in classHierarchy.classes) {
+    Iterable<Name> candidateNames = <Iterable<Name>>[
+      basic.gettersAndCalls[classNode].keys,
+      basic.setters[classNode].keys,
+      pickRandom(nameList, 100)
+    ].expand((x) => x);
+    for (Name name in candidateNames) {
+      Member expectedGetter =
+          basic.getDispatchTarget(classNode, name, setter: false);
+      Member expectedSetter =
+          basic.getDispatchTarget(classNode, name, setter: true);
+      Member actualGetter =
+          classHierarchy.getDispatchTarget(classNode, name, setter: false);
+      Member actualSetter =
+          classHierarchy.getDispatchTarget(classNode, name, setter: true);
+      if (actualGetter != expectedGetter) {
+        fail('lookupGetter($classNode, $name) returned '
+            '$actualGetter but should be $expectedGetter');
+      }
+      if (actualSetter != expectedSetter) {
+        fail('lookupSetter($classNode, $name) returned '
+            '$actualSetter but should be $expectedSetter');
+      }
+    }
+    ++progress;
+    if (verbose) {
+      stdout.write('\rDispatch queries ${100 * progress ~/ total}%');
+    }
+  }
+  progress = 0;
+  for (var classNode in classHierarchy.classes) {
+    Iterable<Name> candidateNames = [
+      basic.interfaceGettersAndCalls[classNode].keys,
+      basic.interfaceSetters[classNode].keys,
+      pickRandom(nameList, 100)
+    ].expand((x) => x);
+    for (Name name in candidateNames) {
+      Member expectedGetter =
+          basic.getInterfaceMember(classNode, name, setter: false);
+      Member expectedSetter =
+          basic.getInterfaceMember(classNode, name, setter: true);
+      Member actualGetter =
+          classHierarchy.getInterfaceMember(classNode, name, setter: false);
+      Member actualSetter =
+          classHierarchy.getInterfaceMember(classNode, name, setter: true);
+      if (actualGetter != expectedGetter) {
+        fail('getInterfaceMember($classNode, $name) returned '
+            '$actualGetter but should be $expectedGetter');
+      }
+      if (actualSetter != expectedSetter) {
+        fail('getInterfaceMember($classNode, $name, setter: true) '
+            'returned $actualSetter but should be $expectedSetter');
+      }
+    }
+    ++progress;
+    if (verbose) {
+      stdout.write('\rInterface queries ${100 * progress ~/ total}%');
+    }
+  }
+  for (var classNode in classHierarchy.classes) {
+    String getHash(member, superMember, setter) {
+      String eq = setter ? '=' : '';
+      return '$member$eq overrides $superMember$eq';
+    }
+    Set<String> expectedOverrides = new Set<String>();
+    basic.forEachOverridePair(classNode, (member, superMember, setter) {
+      expectedOverrides.add(getHash(member, superMember, setter));
+    });
+    Set<String> actualOverrides = new Set<String>();
+    classHierarchy.forEachOverridePair(classNode, (member, superMember, setter) {
+      actualOverrides.add(getHash(member, superMember, setter));
+    });
+    for (var actual in actualOverrides) {
+      if (!expectedOverrides.contains(actual)) {
+        fail("forEachOverridePair($classNode) should not report that $actual");
+      }
+    }
+    for (var expected in expectedOverrides) {
+      if (!actualOverrides.contains(expected)) {
+        fail("forEachOverridePair($classNode) did not report that $expected");
+      }
+    }
+  }
+  if (verbose) {
+    print('\rProgress 100%. Done.');
+  }
+}
+
+var random = new Random(12345);
+
+List/*<T>*/ pickRandom/*<T>*/(List/*<T>*/ items, int n) {
+  var result = /*<T>*/[];
+  for (int i = 0; i < n; ++i) {
+    result.add(items[random.nextInt(items.length)]);
+  }
+  return result;
+}
diff --git a/pkg/kernel/test/frontend_bench.dart b/pkg/kernel/test/frontend_bench.dart
new file mode 100644
index 0000000..796d064
--- /dev/null
+++ b/pkg/kernel/test/frontend_bench.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:args/args.dart';
+import 'package:kernel/analyzer/loader.dart';
+import 'package:kernel/kernel.dart';
+import 'package:package_config/discovery.dart';
+
+ArgParser parser = new ArgParser()
+  ..addOption('sdk',
+      help: 'Path to Dart SDK', valueHelp: 'path', defaultsTo: '/usr/lib/dart')
+  ..addOption('packages',
+      abbr: 'p',
+      help: 'Path to the packages folder or .packages file',
+      valueHelp: 'path')
+  ..addFlag('strong', help: 'Use strong mode');
+
+String get usage => '''
+Usage: frontend_bench [options] FILE.dart
+
+Benchmark the analyzer-based frontend.
+
+Options:
+${parser.options}
+''';
+
+main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = parser.parse(args);
+
+  if (options.rest.length != 1) {
+    print('Exactly one file must be given');
+    exit(1);
+  }
+
+  String sdk = options['sdk'];
+  String packagePath = options['packages'];
+  bool strongMode = options['strong'];
+
+  String path = options.rest.single;
+  var packages =
+      getPackagesDirectory(new Uri(scheme: 'file', path: packagePath));
+  Repository repository = new Repository();
+
+  new DartLoader(
+          repository,
+          new DartOptions(
+              strongMode: strongMode, sdk: sdk, packagePath: packagePath),
+          packages)
+      .loadProgram(path);
+
+  CacheEntry.recomputedCounts.forEach((key, value) {
+    print('Recomputed $key $value times');
+  });
+
+  AnalysisTask.stopwatchMap.forEach((key, Stopwatch watch) {
+    print('$key took ${watch.elapsedMilliseconds} ms');
+  });
+}
diff --git a/pkg/kernel/test/parent_pointer_test_disabled.dart b/pkg/kernel/test/parent_pointer_test_disabled.dart
new file mode 100644
index 0000000..2920227
--- /dev/null
+++ b/pkg/kernel/test/parent_pointer_test_disabled.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/verifier.dart';
+
+main() {
+  Program program = loadProgramFromBinary('test/data/dart2js.dill');
+  CheckParentPointers.check(program);
+}
diff --git a/pkg/kernel/test/round_trip.dart b/pkg/kernel/test/round_trip.dart
new file mode 100644
index 0000000..6ca417a
--- /dev/null
+++ b/pkg/kernel/test/round_trip.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.round_trip;
+
+import 'dart:async';
+import 'dart:io';
+import 'package:kernel/binary/ast_from_binary.dart';
+import 'package:kernel/binary/ast_to_binary.dart';
+import 'package:kernel/binary/loader.dart';
+import 'package:kernel/kernel.dart';
+
+const String usage = '''
+Usage: round_trip.dart FILE.dill
+
+Deserialize and serialize the given program and check that the resulting byte
+sequence is identical to the original.
+''';
+
+void main(List<String> args) {
+  if (args.length != 1) {
+    print(usage);
+    exit(1);
+  }
+  testRoundTrip(new File(args[0]).readAsBytesSync());
+}
+
+void testRoundTrip(List<int> bytes) {
+  var loader = new BinaryLoader(new Repository());
+  var program = new BinaryBuilder(loader, bytes).readProgramFile();
+  new BinaryPrinterWithExpectedOutput(bytes).writeProgramFile(program);
+}
+
+class DummyStreamConsumer extends StreamConsumer<List<int>> {
+  @override
+  Future addStream(Stream<List<int>> stream) async => null;
+
+  @override
+  Future close() async => null;
+}
+
+/// Variant of the binary serializer that compares the output against an
+/// existing buffer.
+///
+/// As opposed to comparing binary files directly, when this fails, the stack
+/// trace shows what the serializer was doing when the output started to differ.
+class BinaryPrinterWithExpectedOutput extends BinaryPrinter {
+  final List<int> expectedBytes;
+  int offset = 0;
+
+  static const int eof = -1;
+
+  BinaryPrinterWithExpectedOutput(this.expectedBytes)
+      : super(new IOSink(new DummyStreamConsumer()));
+
+
+  String show(int byte) {
+    if (byte == eof) return 'EOF';
+    return '$byte (0x${byte.toRadixString(16).padLeft(2, "0")})';
+  }
+
+  @override
+  void writeByte(int byte) {
+    if (offset == expectedBytes.length || expectedBytes[offset] != byte) {
+      int expected =
+          (offset >= expectedBytes.length) ? eof : expectedBytes[offset];
+      throw 'At offset $offset: '
+          'Expected ${show(expected)} but found ${show(byte)}';
+    }
+    ++offset;
+  }
+
+  @override
+  void writeBytes(List<int> bytes) {
+    bytes.forEach(writeByte);
+  }
+}
diff --git a/pkg/kernel/test/round_trip_test_disabled.dart b/pkg/kernel/test/round_trip_test_disabled.dart
new file mode 100644
index 0000000..946f252
--- /dev/null
+++ b/pkg/kernel/test/round_trip_test_disabled.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.round_trip_test;
+
+import 'package:test/test.dart';
+import 'round_trip.dart' as cmd;
+
+void main() {
+  test('dart2js', () {
+    cmd.main(['test/data/dart2js.dill']);
+  });
+  test('dart2js-strong', () {
+    cmd.main(['test/data/dart2js-strong.dill']);
+  });
+  test('boms', () {
+    cmd.main(['test/data/boms.dill']);
+  });
+}
diff --git a/pkg/kernel/test/serialize_bench.dart b/pkg/kernel/test/serialize_bench.dart
new file mode 100644
index 0000000..f19e1af
--- /dev/null
+++ b/pkg/kernel/test/serialize_bench.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'dart:io';
+
+final String usage = '''
+Usage: serialize_bench INPUT.dill OUTPUT.dill
+
+Deserialize INPUT and write it back to OUTPUT several times, measuring
+the time it takes, including I/O time.
+''';
+
+main(List<String> args) async {
+  if (args.length != 2) {
+    print(usage);
+    exit(1);
+  }
+  Program program = loadProgramFromBinary(args[0]);
+
+  String destination = args[1];
+  var watch = new Stopwatch()..start();
+  await writeProgramToBinary(program, destination);
+  int coldTime = watch.elapsedMilliseconds;
+
+  watch.reset();
+  int numTrials = 10;
+  for (int i = 0; i < numTrials; ++i) {
+    await writeProgramToBinary(program, destination);
+  }
+  double hotTime = watch.elapsedMilliseconds / numTrials;
+
+  print('Cold time: $coldTime ms');
+  print('Hot time:  $hotTime ms');
+}
diff --git a/pkg/kernel/test/treeshaker_bench.dart b/pkg/kernel/test/treeshaker_bench.dart
new file mode 100644
index 0000000..3096f99
--- /dev/null
+++ b/pkg/kernel/test/treeshaker_bench.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.treeshaker_bench;
+
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/treeshaker.dart';
+
+import 'class_hierarchy_basic.dart';
+
+ArgParser argParser = new ArgParser()
+  ..addFlag('basic',
+      help: 'Use the basic class hierarchy implementation', negatable: false)
+  ..addFlag('from-scratch',
+      help: 'Rebuild class hierarchy for each tree shaking', negatable: false)
+  ..addFlag('diagnose',
+      abbr: 'd', help: 'Print internal diagnostics', negatable: false);
+
+String usage = '''
+Usage: treeshaker_bench [options] FILE.dart
+
+Benchmark the tree shaker and the class hierarchy it depends on.
+
+Options:
+${argParser.usage}
+''';
+
+void main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = argParser.parse(args);
+  if (options.rest.length != 1) {
+    print('Exactly one file must be given');
+    exit(1);
+  }
+  String filename = options.rest.single;
+
+  Program program = loadProgramFromBinary(filename);
+
+  ClassHierarchy buildClassHierarchy() {
+    return options['basic']
+        ? new BasicClassHierarchy(program)
+        : new ClassHierarchy(program);
+  }
+
+  CoreTypes coreTypes = new CoreTypes(program);
+
+  var watch = new Stopwatch()..start();
+  ClassHierarchy sharedClassHierarchy = buildClassHierarchy();
+  int coldHierarchyTime = watch.elapsedMicroseconds;
+  var shaker = new TreeShaker(program,
+      hierarchy: sharedClassHierarchy, coreTypes: coreTypes);
+  if (options['diagnose']) {
+    print(shaker.getDiagnosticString());
+  }
+  shaker = null;
+  int coldTreeShakingTime = watch.elapsedMicroseconds;
+
+  ClassHierarchy getClassHierarchy() {
+    return options['from-scratch']
+        ? buildClassHierarchy()
+        : sharedClassHierarchy;
+  }
+
+  const int numberOfTrials = 50;
+  int hotHierarchyTime = 0;
+  int hotTreeShakingTime = 0;
+  watch.reset();
+  for (int i = 0; i < numberOfTrials; i++) {
+    watch.reset();
+    var hierarchy = getClassHierarchy();
+    hotHierarchyTime += watch.elapsedMicroseconds;
+    new TreeShaker(program, hierarchy: hierarchy, coreTypes: coreTypes);
+    hotTreeShakingTime += watch.elapsedMicroseconds;
+  }
+  hotHierarchyTime ~/= numberOfTrials;
+  hotTreeShakingTime ~/= numberOfTrials;
+
+  var coldShakingMs = coldTreeShakingTime ~/ 1000;
+  var coldHierarchyMs = coldHierarchyTime ~/ 1000;
+  var hotShakingMs = hotTreeShakingTime ~/ 1000;
+  var hotHierarchyMs = hotHierarchyTime ~/ 1000;
+
+  print('''
+build.cold $coldShakingMs ms ($coldHierarchyMs ms from hierarchy)
+build.hot  $hotShakingMs ms ($hotHierarchyMs ms from hierarchy)''');
+}
diff --git a/pkg/kernel/test/treeshaker_check.dart b/pkg/kernel/test/treeshaker_check.dart
new file mode 100644
index 0000000..8abb640
--- /dev/null
+++ b/pkg/kernel/test/treeshaker_check.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.treeshaker_check;
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/treeshaker.dart';
+import 'dart:io';
+
+String usage = '''
+Usage: treeshaker_check FILE.dill
+
+Run the tree shaker on FILE.dill and perform some internal sanity checks.
+''';
+
+main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  var program = loadProgramFromBinary(args[0]);
+  var shaker = new TreeShaker(program);
+  shaker.transform(program);
+  new TreeShakingSanityCheck(shaker).visit(program);
+}
+
+class TreeShakingSanityCheck extends RecursiveVisitor {
+  final TreeShaker shaker;
+  bool isInCoreLibrary = false;
+
+  TreeShakingSanityCheck(this.shaker);
+
+  void visit(Node node) {
+    node.accept(this);
+  }
+
+  visitLibrary(Library node) {
+    isInCoreLibrary = (node.importUri.scheme == 'dart');
+    super.visitLibrary(node);
+  }
+
+  defaultMember(Member member) {
+    if (!isInCoreLibrary &&
+        member is! Constructor &&
+        !shaker.isMemberUsed(member)) {
+      throw 'Unused member $member was not removed';
+    }
+  }
+
+  defaultMemberReference(Member target) {
+    if (!shaker.isMemberUsed(target)) {
+      throw 'Found reference to $target';
+    }
+  }
+}
diff --git a/pkg/kernel/test/treeshaker_dump.dart b/pkg/kernel/test/treeshaker_dump.dart
new file mode 100644
index 0000000..8d1c7f4
--- /dev/null
+++ b/pkg/kernel/test/treeshaker_dump.dart
@@ -0,0 +1,141 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.treeshaker_dump;
+
+import 'dart:io';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/treeshaker.dart';
+import 'package:args/args.dart';
+import 'package:path/path.dart' as pathlib;
+import 'package:kernel/text/ast_to_text.dart';
+
+ArgParser parser = new ArgParser(allowTrailingOptions: true)
+  ..addFlag('used', help: 'Print used members', negatable: false)
+  ..addFlag('unused', help: 'Print unused members', negatable: false)
+  ..addFlag('instantiated',
+      help: 'Print instantiated classes', negatable: false)
+  ..addFlag('types', help: 'Print classes used as a type', negatable: false)
+  ..addFlag('summary',
+      help: 'Print short summary of tree shaking results', defaultsTo: true)
+  ..addFlag('diff',
+      help: 'Print textual output before and after tree shaking.\n'
+          'Files are written to FILE.before.txt and FILE.after.txt',
+      negatable: false)
+  ..addOption('output',
+      help: 'The --diff files are written to the given directory instead of '
+          'the working directory');
+
+String usage = '''
+Usage: treeshaker_dump [options] FILE.dill
+
+Runs tree shaking on the given program and prints information about the results.
+
+Example:
+  treeshaker_dump --instantiated foo.dill
+
+Example:
+    treeshaker_dump --diff foo.dill
+    diff -cd foo.{before,after}.txt > diff.txt
+    # open diff.txt in an editor
+
+Options:
+${parser.usage}
+''';
+
+main(List<String> args) {
+  if (args.isEmpty) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = parser.parse(args);
+  if (options.rest.length != 1) {
+    print('Exactly one file should be given.');
+    exit(1);
+  }
+  String filename = options.rest.single;
+
+  if (options['output'] != null && !options['diff']) {
+    print('--output must be used with --diff');
+    exit(1);
+  }
+
+  Program program = loadProgramFromBinary(filename);
+  TreeShaker shaker = new TreeShaker(program);
+  int totalClasses = 0;
+  int totalInstantiationCandidates = 0;
+  int totalMembers = 0;
+  int usedClasses = 0;
+  int instantiatedClasses = 0;
+  int usedMembers = 0;
+
+  void visitMember(Member member) {
+    if (member.isAbstract) return; // Abstract members are not relevant.
+    ++totalMembers;
+    bool isUsed = shaker.isMemberUsed(member);
+    if (isUsed) {
+      ++usedMembers;
+    }
+    if (isUsed && options['used'] || !isUsed && options['unused']) {
+      String prefix = (options['used'] && options['unused'])
+          ? (isUsed ? 'USED   ' : 'UNUSED ')
+          : '';
+      print('$prefix$member');
+    }
+  }
+
+  for (var library in program.libraries) {
+    library.members.forEach(visitMember);
+    for (Class classNode in library.classes) {
+      ++totalClasses;
+      if (shaker.isInstantiated(classNode)) {
+        ++instantiatedClasses;
+        ++totalInstantiationCandidates;
+      } else if (!classNode.isAbstract &&
+          classNode.members.any((m) => m.isInstanceMember)) {
+        ++totalInstantiationCandidates;
+      }
+      if (shaker.isHierarchyUsed(classNode)) {
+        ++usedClasses;
+      }
+      classNode.members.forEach(visitMember);
+      if (options['instantiated'] && shaker.isInstantiated(classNode)) {
+        print(classNode);
+      }
+      if (options['types'] && shaker.isHierarchyUsed(classNode)) {
+        print(classNode);
+      }
+    }
+  }
+
+  if (options['summary']) {
+    print('Classes used:         ${ratio(usedClasses, totalClasses)}');
+    print('Classes instantiated: '
+        '${ratio(instantiatedClasses, totalInstantiationCandidates)}');
+    print('Members used:         ${ratio(usedMembers, totalMembers)}');
+  }
+
+  if (options['diff']) {
+    String name = pathlib.basenameWithoutExtension(filename);
+    String outputDir = options['output'] ?? '';
+    String beforeFile = pathlib.join(outputDir, '$name.before.txt');
+    String afterFile = pathlib.join(outputDir, '$name.after.txt');
+    NameSystem names = new NameSystem();
+    StringBuffer before = new StringBuffer();
+    new Printer(before, syntheticNames: names).writeProgramFile(program);
+    new File(beforeFile).writeAsStringSync('$before');
+    new TreeShaker(program).transform(program);
+    StringBuffer after = new StringBuffer();
+    new Printer(after, syntheticNames: names).writeProgramFile(program);
+    new File(afterFile).writeAsStringSync('$after');
+    print('Text written to $beforeFile and $afterFile');
+  }
+}
+
+String ratio(num x, num total) {
+  return '$x / $total (${percent(x, total)})';
+}
+
+String percent(num x, num total) {
+  return total == 0 ? '0%' : ((100 * x / total).toStringAsFixed(0) + '%');
+}
diff --git a/pkg/kernel/test/treeshaker_membench.dart b/pkg/kernel/test/treeshaker_membench.dart
new file mode 100644
index 0000000..318ba74
--- /dev/null
+++ b/pkg/kernel/test/treeshaker_membench.dart
@@ -0,0 +1,63 @@
+#!/usr/bin/env dart
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.treeshaker_membench;
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/treeshaker.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:args/args.dart';
+import 'dart:io';
+
+ArgParser argParser = new ArgParser()
+  ..addOption('count', abbr: 'c',
+      help: 'Build N copies of the tree shaker',
+      defaultsTo: '100');
+
+String usage = """
+Usage: treeshaker_membench [options] FILE.dart
+
+Options:
+${argParser.usage}
+""";
+
+/// Builds N copies of the tree shaker data structure for the given program.
+/// Pass --print-metrics to the Dart VM to measure the memory use.
+main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = argParser.parse(args);
+  if (options.rest.length != 1) {
+    print('Exactly one file should be given');
+    exit(1);
+  }
+  String filename = options.rest.single;
+
+  Program program = loadProgramFromBinary(filename);
+  ClassHierarchy hierarchy = new ClassHierarchy(program);
+  CoreTypes coreTypes = new CoreTypes(program);
+
+  int copyCount = int.parse(options['count']);
+
+  TreeShaker buildTreeShaker() {
+    return new TreeShaker(program, hierarchy: hierarchy, coreTypes: coreTypes);
+  }
+
+  List<TreeShaker> keepAlive = <TreeShaker>[];
+  for (int i = 0; i < copyCount; ++i) {
+    keepAlive.add(buildTreeShaker());
+  }
+
+  print('$copyCount copies built');
+
+  if (args.contains('-v')) {
+    // Use of the list for something to avoid premature GC.
+    for (var treeShaker in keepAlive) {
+      treeShaker.getClassRetention(hierarchy.rootClass);
+    }
+  }
+}
diff --git a/pkg/kernel/test/type_hashcode_quality.dart b/pkg/kernel/test/type_hashcode_quality.dart
new file mode 100644
index 0000000..53a2b70
--- /dev/null
+++ b/pkg/kernel/test/type_hashcode_quality.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'dart:io';
+
+String usage = '''
+Usage: type_hashcode_quality FILE.dill
+
+Counts the number of hash collisions between DartTypes in the given file.
+''';
+
+void main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  Program program = loadProgramFromBinary(args[0]);
+  var visitor = new DartTypeCollector();
+  program.accept(visitor);
+  print('''
+Types:      ${visitor.numberOfTypes}
+Collisions: ${visitor.numberOfCollisions}''');
+}
+
+class DartTypeCollector extends RecursiveVisitor {
+  final Set<DartType> seenTypes = new Set<DartType>();
+  final Map<int, DartType> table = <int, DartType>{};
+  int numberOfCollisions = 0;
+  int numberOfTypes = 0;
+
+  @override
+  defaultDartType(DartType node) {
+    if (!seenTypes.add(node)) return;
+    ++numberOfTypes;
+    int hash = node.hashCode;
+    if (hash == 0) {
+      print('Type has a hash code of zero: $node');
+    }
+    DartType existing = table[hash];
+    if (existing == null) {
+      table[hash] = node;
+    } else if (existing != node) {
+      print('Collision between $existing and $node');
+      ++numberOfCollisions;
+    }
+  }
+}
diff --git a/pkg/kernel/test/type_hashcode_test_disabled.dart b/pkg/kernel/test/type_hashcode_test_disabled.dart
new file mode 100644
index 0000000..aa7f2d4
--- /dev/null
+++ b/pkg/kernel/test/type_hashcode_test_disabled.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'type_parser.dart';
+import 'type_unification_test_disabled.dart' show testCases;
+import 'package:test/test.dart';
+
+void checkHashCodeEquality(DartType type1, DartType type2) {
+  if (type1 == type2 && type1.hashCode != type2.hashCode) {
+    fail('Equal types with different hash codes: $type1 and $type2');
+  }
+}
+
+const int MinimumSmi = -(1 << 30);
+const int MaximumSmi = (1 << 30) - 1;
+
+bool isSmallInteger(int hash) {
+  return MinimumSmi <= hash && hash <= MaximumSmi;
+}
+
+void checkHashCodeRange(DartType type) {
+  int hash = type.hashCode;
+  if (!isSmallInteger(hash)) {
+    fail('Hash code for $type is not a SMI: $hash');
+  }
+}
+
+void main() {
+  for (var testCase in testCases) {
+    test('$testCase', () {
+      var env = new LazyTypeEnvironment();
+      var type1 = env.parse(testCase.type1);
+      var type2 = env.parse(testCase.type2);
+      checkHashCodeEquality(type1, type2);
+      checkHashCodeRange(type1);
+      checkHashCodeRange(type2);
+    });
+  }
+}
diff --git a/pkg/kernel/test/type_parser.dart b/pkg/kernel/test/type_parser.dart
new file mode 100644
index 0000000..d2e1b4d
--- /dev/null
+++ b/pkg/kernel/test/type_parser.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 very simple parser for a subset of DartTypes for use in testing type
+// algebra.
+library kernel.test.type_parser;
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/text/ast_to_text.dart';
+
+typedef TreeNode TypeEnvironment(String name);
+
+/// [lookupType] should return a [Class] or [TypeParameter].
+DartType parseDartType(String type, TreeNode lookupType(String name)) {
+  return new DartTypeParser(type, lookupType).parseType();
+}
+
+class Token {
+  static const int Eof = 0;
+  static const int Name = 1;
+  static const int Comma = 2;
+  static const int LeftAngle = 3; // '<'
+  static const int RightAngle = 4; // '>'
+  static const int LeftParen = 5;
+  static const int RightParen = 6;
+  static const int LeftBracket = 7;
+  static const int RightBracket = 8;
+  static const int LeftBrace = 9;
+  static const int RightBrace = 10;
+  static const int Arrow = 11; // '=>'
+  static const int Colon = 12;
+  static const int Invalid = 100;
+}
+
+class DartTypeParser {
+  final String string;
+  int index = 0;
+  String tokenText;
+  final TypeEnvironment environment;
+  final Map<String, TypeParameter> localTypeParameters =
+      <String, TypeParameter>{};
+
+  DartTypeParser(this.string, this.environment);
+
+  TreeNode lookupType(String name) {
+    return localTypeParameters[name] ?? environment(name);
+  }
+
+  bool isIdentifierChar(int charCode) {
+    return 65 <= charCode && charCode <= 90 ||
+        97 <= charCode && charCode <= 122 ||
+        charCode == 95 || // '_'
+        charCode == 36; // '$'
+  }
+
+  bool isWhitespaceChar(int charCode) {
+    return charCode == 32;
+  }
+
+  int next() => string.codeUnitAt(index++);
+  int peek() => index < string.length ? string.codeUnitAt(index) : 0;
+
+  void skipWhitespace() {
+    while (isWhitespaceChar(peek())) {
+      next();
+    }
+  }
+
+  int scanToken() {
+    skipWhitespace();
+    if (index >= string.length) return Token.Eof;
+    int startIndex = index;
+    int x = next();
+    if (isIdentifierChar(x)) {
+      while (isIdentifierChar(peek())) {
+        x = next();
+      }
+      tokenText = string.substring(startIndex, index);
+      return Token.Name;
+    } else {
+      tokenText = string[index - 1];
+      int type = getTokenType(x);
+      return type;
+    }
+  }
+
+  int peekToken() {
+    skipWhitespace();
+    if (index >= string.length) return Token.Eof;
+    return getTokenType(peek());
+  }
+
+  int getTokenType(int character) {
+    switch (character) {
+      case 44:
+        return Token.Comma;
+      case 60:
+        return Token.LeftAngle;
+      case 62:
+        return Token.RightAngle;
+      case 40:
+        return Token.LeftParen;
+      case 41:
+        return Token.RightParen;
+      case 91:
+        return Token.LeftBracket;
+      case 92:
+        return Token.RightBracket;
+      case 123:
+        return Token.LeftBrace;
+      case 125:
+        return Token.RightBrace;
+      case 58:
+        return Token.Colon;
+      default:
+        if (isIdentifierChar(character)) return Token.Name;
+        return Token.Invalid;
+    }
+  }
+
+  void consumeString(String text) {
+    skipWhitespace();
+    if (string.startsWith(text, index)) {
+      index += text.length;
+    } else {
+      return fail('Expected token $text');
+    }
+  }
+
+  DartType parseType() {
+    int token = peekToken();
+    switch (token) {
+      case Token.Name:
+        scanToken();
+        String name = this.tokenText;
+        if (name == '_') return const BottomType();
+        if (name == 'void') return const VoidType();
+        if (name == 'dynamic') return const DynamicType();
+        var target = lookupType(name);
+        if (target == null) {
+          return fail('Unresolved type $name');
+        } else if (target is Class) {
+          return new InterfaceType(target, parseOptionalTypeArgumentList());
+        } else if (target is TypeParameter) {
+          if (peekToken() == Token.LeftAngle) {
+            return fail('Attempt to apply type arguments to a type variable');
+          }
+          return new TypeParameterType(target);
+        }
+        return fail("Unexpected lookup result for $name: $target");
+
+      case Token.LeftParen:
+        List<DartType> parameters = <DartType>[];
+        List<NamedType> namedParameters = <NamedType>[];
+        parseParameterList(parameters, namedParameters);
+        consumeString('=>');
+        var returnType = parseType();
+        return new FunctionType(parameters, returnType,
+            namedParameters: namedParameters);
+
+      case Token.LeftAngle:
+        var typeParameters = parseAndPushTypeParameterList();
+        List<DartType> parameters = <DartType>[];
+        List<NamedType> namedParameters = <NamedType>[];
+        parseParameterList(parameters, namedParameters);
+        consumeString('=>');
+        var returnType = parseType();
+        popTypeParameters(typeParameters);
+        return new FunctionType(parameters, returnType,
+            typeParameters: typeParameters, namedParameters: namedParameters);
+
+      default:
+        return fail('Unexpected token: $tokenText');
+    }
+  }
+
+  void parseParameterList(List<DartType> positional, List<NamedType> named) {
+    int token = scanToken();
+    assert(token == Token.LeftParen);
+    token = peekToken();
+    while (token != Token.RightParen) {
+      var type = parseType(); // Could be a named parameter name.
+      token = scanToken();
+      if (token == Token.Colon) {
+        String name = convertTypeToParameterName(type);
+        named.add(new NamedType(name, parseType()));
+        token = scanToken();
+      } else {
+        positional.add(type);
+      }
+      if (token != Token.Comma && token != Token.RightParen) {
+        return fail('Unterminated parameter list');
+      }
+    }
+    named.sort();
+  }
+
+  String convertTypeToParameterName(DartType type) {
+    if (type is InterfaceType && type.typeArguments.isEmpty) {
+      return type.classNode.name;
+    } else if (type is TypeParameterType) {
+      return type.parameter.name;
+    } else {
+      return fail('Unexpected colon after $type');
+    }
+  }
+
+  List<DartType> parseTypeList(int open, int close) {
+    int token = scanToken();
+    assert(token == open);
+    List<DartType> types = <DartType>[];
+    token = peekToken();
+    while (token != close) {
+      types.add(parseType());
+      token = scanToken();
+      if (token != Token.Comma && token != close) {
+        throw fail('Unterminated list');
+      }
+    }
+    return types;
+  }
+
+  List<DartType> parseOptionalList(int open, int close) {
+    if (peekToken() != open) return null;
+    return parseTypeList(open, close);
+  }
+
+  List<DartType> parseOptionalTypeArgumentList() {
+    return parseOptionalList(Token.LeftAngle, Token.RightAngle);
+  }
+
+  void popTypeParameters(List<TypeParameter> typeParameters) {
+    typeParameters.forEach(localTypeParameters.remove);
+  }
+
+  List<TypeParameter> parseAndPushTypeParameterList() {
+    int token = scanToken();
+    assert(token == Token.LeftAngle);
+    List<TypeParameter> typeParameters = <TypeParameter>[];
+    token = peekToken();
+    while (token != Token.RightAngle) {
+      typeParameters.add(parseAndPushTypeParameter());
+      token = scanToken();
+      if (token != Token.Comma && token != Token.RightAngle) {
+        throw fail('Unterminated type parameter list');
+      }
+    }
+    return typeParameters;
+  }
+
+  TypeParameter parseAndPushTypeParameter() {
+    var nameTok = scanToken();
+    if (nameTok != Token.Name) return fail('Expected a name');
+    var typeParameter = new TypeParameter(tokenText);
+    if (localTypeParameters.containsKey(typeParameter.name)) {
+      return fail('Shadowing a type parameter is not allowed');
+    }
+    localTypeParameters[typeParameter.name] = typeParameter;
+    var next = peekToken();
+    if (next == Token.Colon) {
+      scanToken();
+      typeParameter.bound = parseType();
+    } else {
+      typeParameter.bound = new InterfaceType(lookupType('Object'));
+    }
+    return typeParameter;
+  }
+
+  dynamic fail(String message) {
+    throw '$message at index $index';
+  }
+}
+
+class LazyTypeEnvironment {
+  final Map<String, Class> classes = <String, Class>{};
+  final Map<String, TypeParameter> typeParameters = <String, TypeParameter>{};
+  final Library dummyLibrary =
+      new Library(new Uri(path: 'dummy.dart'), name: 'lib');
+
+  TreeNode lookup(String name) {
+    return name.length == 1
+        ? typeParameters.putIfAbsent(name, () => new TypeParameter(name))
+        : classes.putIfAbsent(name, () => makeClass(name));
+  }
+
+  Class makeClass(String name) {
+    var class_ = new Class(name: name);
+    dummyLibrary.addClass(class_);
+    return class_;
+  }
+
+  void clearTypeParameters() {
+    typeParameters.clear();
+  }
+
+  DartType parse(String type) => parseDartType(type, lookup);
+
+  Supertype parseSuper(String type) {
+    InterfaceType interfaceType = parse(type);
+    return new Supertype(interfaceType.classNode, interfaceType.typeArguments);
+  }
+
+  DartType parseFresh(String type) {
+    clearTypeParameters();
+    return parse(type);
+  }
+
+  TypeParameter getTypeParameter(String name) {
+    if (name.length != 1) throw 'Type parameter names must have length 1';
+    return lookup(name);
+  }
+}
+
+void main(List<String> args) {
+  if (args.length != 1) {
+    print('Usage: type_parser TYPE');
+  }
+  var environment = new LazyTypeEnvironment();
+  var type = parseDartType(args[0], environment.lookup);
+  var buffer = new StringBuffer();
+  new Printer(buffer).writeType(type);
+  print(buffer);
+}
diff --git a/pkg/kernel/test/type_propagation_dump.dart b/pkg/kernel/test/type_propagation_dump.dart
new file mode 100644
index 0000000..6de0872
--- /dev/null
+++ b/pkg/kernel/test/type_propagation_dump.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.dump;
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/text/ast_to_text.dart';
+import 'package:kernel/type_propagation/builder.dart';
+import 'package:kernel/type_propagation/solver.dart';
+import 'package:kernel/type_propagation/visualizer.dart';
+import 'package:kernel/type_propagation/constraints.dart';
+import 'package:kernel/type_propagation/type_propagation.dart';
+import 'package:args/args.dart';
+import 'dart:io';
+
+ArgParser parser = new ArgParser()
+  ..addFlag('graph', help: 'Generate graphviz dot files')
+  ..addOption('graph-filter',
+      valueHelp: 'name',
+      help: 'Only print graph for members whose name contains the given string')
+  ..addFlag('text', help: 'Generate annotated kernel text files')
+  ..addFlag('escape', help: 'Dump information from escape analysis')
+  ..addFlag('stats',
+      help: 'Print times and constraint system size', defaultsTo: true)
+  ..addFlag('solve', help: 'Solve the constraint system', defaultsTo: true);
+
+String get usage => """
+Usage: dump [options] FILE.dill
+
+Options:
+${parser.usage}
+""";
+
+const String outputDir = 'typegraph';
+
+main(List<String> args) {
+  if (args.length == 0) {
+    print(usage);
+    exit(1);
+  }
+  ArgResults options = parser.parse(args);
+  if (options.rest.length != 1) {
+    print('Exactly one file must be given');
+    exit(1);
+  }
+  String path = options.rest.single;
+
+  bool printGraphviz = options['graph'];
+  bool printText = options['text'];
+  bool printEscape = options['escape'];
+  bool useVisualizer = printGraphviz || printText || printEscape;
+
+  Program program = loadProgramFromBinary(path);
+  Stopwatch watch = new Stopwatch()..start();
+  Visualizer visualizer = useVisualizer ? new Visualizer(program) : null;
+  Builder builder = new Builder(program, visualizer: visualizer, verbose: true);
+  int buildTime = watch.elapsedMilliseconds;
+
+  watch.reset();
+  var solver = new Solver(builder);
+  if (options['solve']) {
+    solver.solve();
+  }
+  int solveTime = watch.elapsedMilliseconds;
+  visualizer?.solver = solver;
+  ConstraintSystem constraints = builder.constraints;
+
+  if (printEscape) {
+    for (int value = 0; value <= constraints.numberOfValues; ++value) {
+      TreeNode node;
+      if (value < builder.hierarchy.classes.length) {
+        node = builder.hierarchy.classes[value];
+      } else {
+        FunctionNode function = visualizer.getFunctionFromValue(value);
+        if (function == null || function.parent is! Member) continue;
+        node = function.parent;
+      }
+      int escape = solver.getEscapeContext(value);
+      String escapeString = (escape == constraints.latticePointOfValue[value])
+          ? 'no escape'
+          : visualizer.getLatticePointName(escape);
+      print('$node -> $escapeString');
+    }
+  }
+
+  if (printText) {
+    print('Printing kernel text files...');
+    new Directory(outputDir).createSync();
+    StringBuffer buffer = new StringBuffer();
+    Printer printer =
+        new Printer(buffer, annotator: visualizer.getTextAnnotator());
+    printer.writeProgramFile(program);
+    String path = '$outputDir/program.txt';
+    new File(path).writeAsStringSync('$buffer');
+  }
+
+  if (printGraphviz) {
+    print('Printing graphviz dot files...');
+    String filter = options['graph-filter'];
+    new Directory(outputDir).createSync();
+    void dumpMember(Member member) {
+      if (filter != null && !'$member'.contains(filter)) return;
+      String name = sanitizeFilename('$member');
+      String path = '$outputDir/$name.dot';
+      String dotCode = visualizer.dumpMember(member);
+      new File(path).writeAsStringSync(dotCode);
+    }
+    for (var library in program.libraries) {
+      library.members.forEach(dumpMember);
+      for (var class_ in library.classes) {
+        class_.members.forEach(dumpMember);
+      }
+    }
+  }
+
+  if (options['stats']) {
+    var constraints = solver.constraints;
+    int numberOfConstraints = constraints.numberOfAssignments +
+        constraints.numberOfLoads +
+        constraints.numberOfStores;
+    int numberOfTransfers = numberOfConstraints * solver.iterations;
+    double transfersPerSecond =
+        (numberOfConstraints * solver.iterations) / (solveTime / 1000);
+    Iterable<int> outputVariables = [
+      builder.global.fields.values,
+      builder.global.returns.values,
+      builder.global.parameters.values
+    ].expand((x) => x);
+    int outputCount = outputVariables.length;
+    int inferredUnknown = 0;
+    int inferredNothing = 0;
+    int inferredNullable = 0;
+    int inferredNonNullable = 0;
+    int inferredOnlyNull = 0;
+    for (int variable in outputVariables) {
+      int values = solver.getVariableValue(variable);
+      int bitmask = solver.getVariableBitmask(variable);
+      if (values == Solver.bottom && bitmask == 0) {
+        ++inferredNothing;
+      } else if (values == Solver.bottom && bitmask == ValueBit.null_) {
+        ++inferredOnlyNull;
+      } else if (values == Solver.rootClass && bitmask == ValueBit.all) {
+        ++inferredUnknown;
+      } else if (bitmask & ValueBit.null_ != 0) {
+        ++inferredNullable;
+      } else {
+        ++inferredNonNullable;
+      }
+    }
+    print("""
+Build time:  $buildTime ms
+Solve time:  $solveTime ms
+Iterations:  ${solver.iterations}
+
+Classes:     ${builder.hierarchy.classes.length}
+Values:      ${constraints.numberOfValues}
+Unions:      ${constraints.numberOfLatticePoints}
+Variables:   ${constraints.numberOfVariables}
+Fields:      ${builder.fieldNames.length}
+Assignments: ${constraints.numberOfAssignments}
+Loads:       ${constraints.numberOfLoads}
+Stores:      ${constraints.numberOfStores}
+
+Transfers:   $numberOfTransfers (${(transfersPerSecond / 1000000).toStringAsFixed(1)} M/s)
+
+Outputs:      $outputCount
+Unknown:      $inferredUnknown (${percent(inferredUnknown, outputCount)})
+Nullable:     $inferredNullable (${percent(inferredNullable, outputCount)})
+Non-nullable: $inferredNonNullable (${percent(inferredNonNullable, outputCount)})
+Only null:    $inferredOnlyNull (${percent(inferredOnlyNull, outputCount)})
+Nothing:      $inferredNothing (${percent(inferredNothing, outputCount)})
+  """);
+  }
+}
+
+String percent(int amount, int total) {
+  if (total == 0) return '0%';
+  return (amount / total * 100).toStringAsFixed(1) + '%';
+}
+
+String sanitizeFilename(String name) {
+  return name
+      .replaceAll('::', '.')
+      .replaceAll('/', r'$div')
+      .replaceAll('(', '')
+      .replaceAll(')', '');
+}
diff --git a/pkg/kernel/test/type_propagation_selfcheck.dart b/pkg/kernel/test/type_propagation_selfcheck.dart
new file mode 100644
index 0000000..f5ce293
--- /dev/null
+++ b/pkg/kernel/test/type_propagation_selfcheck.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_propagation.selfcheck;
+
+import 'dart:io';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/type_propagation/type_propagation.dart';
+
+const String usage = '''
+Usage: selfcheck input.dill output.dill
+
+Runs type propagation on the given program and inserts dynamic checks
+to verify that all the propagated types are correct.
+''';
+
+main(List<String> args) {
+  if (args.length != 2) {
+    print(usage);
+    exit(1);
+  }
+  var program = loadProgramFromBinary(args[0]);
+  var typePropagation = new TypePropagation(program);
+  new SelfCheckTransformer(typePropagation).transform(program);
+  writeProgramToBinary(program, args[1]);
+}
+
+class SelfCheckTransformer {
+  final TypePropagation typePropagation;
+  Member currentMember;
+
+  CoreTypes get coreTypes => typePropagation.builder.coreTypes;
+
+  SelfCheckTransformer(this.typePropagation);
+
+  void transform(Program program) {
+    for (var library in program.libraries) {
+      library.procedures.forEach(transformProcedure);
+      library.fields.forEach(transformField);
+      for (var class_ in library.classes) {
+        class_.procedures.forEach(transformProcedure);
+        class_.fields.forEach(transformField);
+        class_.constructors.forEach(transformConstructor);
+      }
+    }
+  }
+
+  void transformProcedure(Procedure node) {
+    currentMember = node;
+    transformFunction(node.function, checkReturn: true);
+  }
+
+  void transformConstructor(Constructor node) {
+    currentMember = node;
+    transformFunction(node.function, checkReturn: false);
+  }
+
+  void transformField(Field node) {
+    // TODO(asgerf): To check this, we could wrap with a getter/setter pair
+    //   and instrument constructor initializers.  But for now we don't do
+    //   anything for fields.
+  }
+
+  void transformFunction(FunctionNode node, {bool checkReturn}) {
+    if (node.body == null) return; // Nothing to check if there is no body.
+    List<Statement> newStatements = <Statement>[];
+    for (VariableDeclaration parameter in node.positionalParameters) {
+      InferredValue value = typePropagation.getParameterValue(parameter);
+      newStatements.add(makeCheck(parameter, value));
+    }
+    for (VariableDeclaration parameter in node.namedParameters) {
+      InferredValue value = typePropagation.getParameterValue(parameter);
+      newStatements.add(makeCheck(parameter, value));
+    }
+    newStatements.add(node.body);
+    node.body = new Block(newStatements)..parent = node;
+    // TODO(asgerf): Also check return value.
+  }
+
+  /// Make a statement that throws if the value in [variable] is not in the
+  /// value set implied by [expected].
+  Statement makeCheck(VariableDeclaration variable, InferredValue expected) {
+    Expression condition = new LogicalExpression(
+        makeBaseClassCheck(variable, expected),
+        '&&',
+        makeBitmaskCheck(variable, expected));
+    return new IfStatement(
+        new Not(condition),
+        new ExpressionStatement(new Throw(new StringConcatenation([
+          new StringLiteral(
+              'Unexpected value in $currentMember::${variable.name}: '),
+          new VariableGet(variable)
+        ]))),
+        null);
+  }
+
+  /// Makes an expression that returns `false` if the base class relation or
+  /// nullability is not satisfied by the value in [variable],
+  Expression makeBaseClassCheck(
+      VariableDeclaration variable, InferredValue expected) {
+    Expression condition;
+    switch (expected.baseClassKind) {
+      case BaseClassKind.None:
+        condition = new BoolLiteral(false);
+        break;
+
+      case BaseClassKind.Exact:
+        if (expected.baseClass.typeParameters.isNotEmpty) {
+          // TODO(asgerf): For this we need a way to get the raw concrete type
+          //   of an object.  For now, just emit the less accurate subtype
+          //   check.
+          condition = new IsExpression(
+              new VariableGet(variable), expected.baseClass.rawType);
+        } else {
+          // Check `value.runtimeType == C`.
+          var runtimeType = new PropertyGet(
+              new VariableGet(variable), new Name('runtimeType'));
+          condition = new MethodInvocation(runtimeType, new Name('=='),
+              new Arguments([new TypeLiteral(expected.baseClass.rawType)]));
+        }
+        break;
+
+      case BaseClassKind.Subclass:
+      case BaseClassKind.Subtype:
+        // TODO(asgerf): For subclass checks, we should check more precisely
+        //   that is it a subclass, but for now just emit a subtype check.
+        condition = new IsExpression(
+            new VariableGet(variable), expected.baseClass.rawType);
+        break;
+    }
+    // Always allow 'null'.  The base class relation should always permit 'null'
+    // as a possible value, but the checks generated above disallow it.
+    var nullCheck = makeIsNull(new VariableGet(variable));
+    return new LogicalExpression(nullCheck, '||', condition);
+  }
+
+  Expression makeIsNull(Expression value) {
+    return new MethodInvocation(
+        value, new Name('=='), new Arguments([new NullLiteral()]));
+  }
+
+  /// Makes an expression that returns `false` if the value bits other than
+  /// [ValueBit.null_] are not satisfied by the value in [variable],
+  Expression makeBitmaskCheck(
+      VariableDeclaration variable, InferredValue expected) {
+    if (expected.valueBits == 0) return new BoolLiteral(false);
+
+    // List of conditions that all must hold.  For each zero bit we know that
+    // type of value is not allowed to occur.
+    List<Expression> allChecks = <Expression>[];
+
+    // List of condition of which one must hold.  This is used for checking the
+    // [ValueBit.other] bit.  For each one bit, we know that type of value
+    // is allowed to occur.  We use this because it is hard to check directly
+    // that a value is of the 'other' type.
+    bool disallowOtherValues = expected.valueBits & ValueBit.other == 0;
+    List<Expression> anyChecks = disallowOtherValues
+        ? <Expression>[]
+        : null;
+
+    void checkType(int bit, DartType type) {
+      if (expected.valueBits & bit == 0) {
+        allChecks
+            .add(new Not(new IsExpression(new VariableGet(variable), type)));
+      } else if (disallowOtherValues) {
+        anyChecks.add(new IsExpression(new VariableGet(variable), type));
+      }
+    }
+
+    checkType(ValueBit.integer, coreTypes.intClass.rawType);
+    checkType(ValueBit.double_, coreTypes.doubleClass.rawType);
+    checkType(ValueBit.string, coreTypes.stringClass.rawType);
+    checkType(ValueBit.null_, coreTypes.nullClass.rawType);
+
+    if (disallowOtherValues) {
+      Expression any =
+          anyChecks.reduce((e1, e2) => new LogicalExpression(e1, '||', e2));
+      allChecks.add(any);
+    }
+    return allChecks.isEmpty
+        ? new BoolLiteral(true)
+        : allChecks.reduce((e1, e2) => new LogicalExpression(e1, '&&', e2));
+  }
+}
diff --git a/pkg/kernel/test/type_substitute_bounds_test_disabled.dart b/pkg/kernel/test/type_substitute_bounds_test_disabled.dart
new file mode 100644
index 0000000..bddd7bd
--- /dev/null
+++ b/pkg/kernel/test/type_substitute_bounds_test_disabled.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.type_substitute_bounds_test;
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/type_algebra.dart';
+import 'package:test/test.dart';
+import 'type_parser.dart';
+
+final List<TestCase> testCases = <TestCase>[
+  testCase('T', {'T': bound('_', 'String')}, 'String'),
+  testCase('List<T>', {'T': bound('_', 'String')}, 'List<String>'),
+  testCase('List<List<T>>', {'T': bound('_', 'String')}, 'List<List<String>>'),
+  testCase('(T) => T', {'T': bound('_', 'String')}, '(_) => String'),
+  testCase('<G>(G,T) => T', {'T': bound('_', 'String')}, '<G>(G,_) => String'),
+  testCase(
+      '<G>(G,x:T) => T', {'T': bound('_', 'String')}, '<G>(G,x:_) => String'),
+  testCase('<G:T>(G) => G', {'T': bound('_', 'String')}, '<G:_>(G) => G'),
+  testCase('<G:T>(G) => G', {'T': bound('int', 'num')}, '<G:int>(G) => G'),
+  testCase('<G>(T,G) => void', {'T': bound('_', 'String')}, '<G>(_,G) => void'),
+  testCase('(T) => void', {'T': bound('_', 'String')}, '(_) => void'),
+  testCase('(int) => T', {'T': bound('_', 'String')}, '(int) => String'),
+  testCase('(int) => int', {'T': bound('_', 'String')}, '(int) => int'),
+  testCase('((T) => int) => int', {'T': bound('_', 'String')},
+      '((String) => int) => int'),
+  testCase('<E>(<F>(T) => int) => int', {'T': bound('_', 'String')},
+      '<E>(<F>(String) => int) => int'),
+  testCase('(<F>(T) => int) => int', {'T': bound('_', 'String')},
+      '(<F>(String) => int) => int'),
+  testCase('<E>((T) => int) => int', {'T': bound('_', 'String')},
+      '<E>((String) => int) => int'),
+];
+
+class TestCase {
+  final String type;
+  final Map<String, TypeBound> bounds;
+  final String expected;
+
+  TestCase(this.type, this.bounds, this.expected);
+
+  String toString() {
+    var substitution = bounds.keys.map((key) {
+      var bound = bounds[key];
+      return '${bound.lower} <: $key <: ${bound.upper}';
+    }).join(',');
+    return '$type [$substitution] <: $expected';
+  }
+}
+
+class TypeBound {
+  final String lower, upper;
+
+  TypeBound(this.lower, this.upper);
+}
+
+TypeBound bound(String lower, String upper) => new TypeBound(lower, upper);
+
+TestCase testCase(String type, Map<String, TypeBound> bounds, String expected) {
+  return new TestCase(type, bounds, expected);
+}
+
+main() {
+  for (var testCase in testCases) {
+    test('$testCase', () {
+      var environment = new LazyTypeEnvironment();
+      var type = environment.parse(testCase.type);
+      var upperBounds = <TypeParameter, DartType>{};
+      var lowerBounds = <TypeParameter, DartType>{};
+      testCase.bounds.forEach((String name, TypeBound bounds) {
+        var parameter = environment.getTypeParameter(name);
+        upperBounds[parameter] = environment.parse(bounds.upper);
+        lowerBounds[parameter] = environment.parse(bounds.lower);
+      });
+      var substituted = Substitution
+          .fromUpperAndLowerBounds(upperBounds, lowerBounds)
+          .substituteType(type);
+      var expected = environment.parse(testCase.expected);
+      if (substituted != expected) {
+        fail('Expected `$expected` but got `$substituted`');
+      }
+    });
+  }
+}
diff --git a/pkg/kernel/test/type_substitution_identity_test_disabled.dart b/pkg/kernel/test/type_substitution_identity_test_disabled.dart
new file mode 100644
index 0000000..2e6c263
--- /dev/null
+++ b/pkg/kernel/test/type_substitution_identity_test_disabled.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/type_algebra.dart';
+import 'type_parser.dart';
+import 'type_unification_test_disabled.dart' show testCases;
+import 'package:test/test.dart';
+
+checkType(DartType type) {
+  var map = {new TypeParameter(): const DynamicType()};
+  var other = substitute(type, map);
+  if (!identical(type, other)) {
+    fail('Identity substitution test failed for $type');
+  }
+  other = Substitution.fromUpperAndLowerBounds(map, map).substituteType(type);
+  if (!identical(type, other)) {
+    fail('Identity bounded substitution test failed for $type');
+  }
+}
+
+main() {
+  for (var testCase in testCases) {
+    test('$testCase', () {
+      var env = new LazyTypeEnvironment();
+      checkType(env.parse(testCase.type1));
+      checkType(env.parse(testCase.type2));
+    });
+  }
+}
diff --git a/pkg/kernel/test/type_subtype_test_disabled.dart b/pkg/kernel/test/type_subtype_test_disabled.dart
new file mode 100644
index 0000000..56b2339
--- /dev/null
+++ b/pkg/kernel/test/type_subtype_test_disabled.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:test/test.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/type_environment.dart';
+import 'type_parser.dart';
+
+/// Description of a small class hierarchy for use in subtype tests.
+var classEnvironment = <String, List<String>>{
+  'Comparable<T>': ['Object'],
+  'num': ['Object', 'Comparable<num>'],
+  'int': ['num'],
+  'double': ['num'],
+  'Iterable<T>': ['Object'],
+  'List<T>': ['Iterable<T>'],
+};
+
+List<TestCase> testCases = <TestCase>[
+  subtype('int', 'num'),
+  subtype('int', 'Comparable<num>'),
+  subtype('int', 'Comparable<Object>'),
+  subtype('int', 'Object'),
+  subtype('double', 'num'),
+
+  notSubtype('int', 'double'),
+  notSubtype('int', 'Comparable<int>'),
+  notSubtype('int', 'Iterable<int>'),
+  notSubtype('Comparable<int>', 'Iterable<int>'),
+
+  subtype('List<int>', 'List<int>'),
+  subtype('List<int>', 'Iterable<int>'),
+  subtype('List<int>', 'List<num>'),
+  subtype('List<int>', 'Iterable<num>'),
+  subtype('List<int>', 'List<Object>'),
+  subtype('List<int>', 'Iterable<Object>'),
+  subtype('List<int>', 'Object'),
+  subtype('List<int>', 'List<Comparable<Object>>'),
+  subtype('List<int>', 'List<Comparable<num>>'),
+  subtype('List<int>', 'List<Comparable<Comparable<num>>>'),
+
+  notSubtype('List<int>', 'List<double>'),
+  notSubtype('List<int>', 'Iterable<double>'),
+  notSubtype('List<int>', 'Comparable<int>'),
+  notSubtype('List<int>', 'List<Comparable<int>>'),
+  notSubtype('List<int>', 'List<Comparable<Comparable<int>>>'),
+
+  subtype('(num) => num', '(int) => num'),
+  subtype('(num) => int', '(num) => num'),
+  subtype('(num) => int', '(int) => num'),
+  notSubtype('(int) => int', '(num) => num'),
+
+  subtype('(num) => (num) => num', '(num) => (int) => num'),
+  notSubtype('(num) => (int) => int', '(num) => (num) => num'),
+
+  subtype('(x:num) => num', '(x:int) => num'), // named parameters
+  subtype('(num,x:num) => num', '(int,x:int) => num'),
+  subtype('(x:num) => int', '(x:num) => num'),
+  notSubtype('(x:int) => int', '(x:num) => num'),
+
+  subtype('<E>(E) => int', '<E>(E) => num'), // type parameters
+  subtype('<E>(num) => E', '<E>(int) => E'),
+  subtype('<E>(E,num) => E', '<E>(E,int) => E'),
+  notSubtype('<E>(E,num) => E', '<E>(E,E) => E'),
+
+  subtype('<E>(E) => (E) => E', '<F>(F) => (F) => F'),
+  subtype('<E>(E, (int,E) => E) => E', '<E>(E, (int,E) => E) => E'),
+  subtype('<E>(E, (int,E) => E) => E', '<E>(E, (num,E) => E) => E'),
+  notSubtype('<E,F>(E) => (F) => E', '<E>(E) => <F>(F) => E'),
+  notSubtype('<E,F>(E) => (F) => E', '<F,E>(E) => (F) => E'),
+
+  subtype('<E>(E,num) => E', '<E:num>(E,E) => E'),
+  subtype('<E:num>(E) => int', '<E:int>(E) => int'),
+  subtype('<E:num>(E) => E', '<E:int>(E) => E'),
+  subtype('<E:num>(int) => E', '<E:int>(int) => E'),
+  notSubtype('<E>(int) => int', '(int) => int'),
+  notSubtype('<E,F>(int) => int', '<E>(int) => int'),
+
+  subtype('<E:List<E>>(E) => E', '<F:List<F>>(F) => F'),
+  subtype('<E:Iterable<E>>(E) => E', '<F:List<F>>(F) => F'),
+  subtype('<E>(E,List<Object>) => E', '<F:List<F>>(F,F) => F'),
+  notSubtype('<E>(E,List<Object>) => List<E>', '<F:List<F>>(F,F) => F'),
+  notSubtype('<E>(E,List<Object>) => int', '<F:List<F>>(F,F) => F'),
+  subtype('<E>(E,List<Object>) => E', '<F:List<F>>(F,F) => void'),
+];
+
+/// Assert that [subtype] is a subtype of [supertype], and that [supertype]
+/// is not a subtype of [subtype] (unless the two strings are equal).
+TestCase subtype(String subtype_, String supertype) {
+  return new TestCase(subtype_, supertype, isSubtype: true);
+}
+
+/// Assert that neither type is a subtype of the other.
+TestCase notSubtype(String subtype_, String supertype) {
+  return new TestCase(subtype_, supertype, isSubtype: false);
+}
+
+class TestCase {
+  String subtype;
+  String supertype;
+  bool isSubtype;
+  TestCase(this.subtype, this.supertype, {this.isSubtype});
+
+  String toString() =>
+      isSubtype ? '$subtype <: $supertype' : '$subtype </: $supertype';
+}
+
+class MockSubtypeTester extends SubtypeTester {
+  ClassHierarchy hierarchy;
+  InterfaceType objectType;
+  InterfaceType rawFunctionType;
+  LazyTypeEnvironment environment;
+
+  MockSubtypeTester(
+      this.hierarchy, this.objectType, this.rawFunctionType, this.environment);
+}
+
+MockSubtypeTester makeSubtypeTester(Map<String, List<String>> testcase) {
+  LazyTypeEnvironment environment = new LazyTypeEnvironment();
+  Class objectClass = environment.lookup('Object');
+  Class functionClass = environment.lookup('Function');
+  functionClass.supertype = objectClass.asRawSupertype;
+  for (var typeString in testcase.keys) {
+    InterfaceType type = environment.parseFresh(typeString);
+    Class class_ = type.classNode;
+    for (TypeParameterType typeArg in type.typeArguments) {
+      class_.typeParameters.add(typeArg.parameter);
+    }
+    for (var supertypeString in testcase[typeString]) {
+      if (class_.supertype == null) {
+        class_.supertype = environment.parseSuper(supertypeString);
+      } else {
+        class_.implementedTypes.add(environment.parseSuper(supertypeString));
+      }
+    }
+  }
+  var program = new Program([environment.dummyLibrary]);
+  var hierarchy = new ClassHierarchy(program);
+  return new MockSubtypeTester(
+      hierarchy, objectClass.rawType, functionClass.rawType, environment);
+}
+
+main() {
+  var tester = makeSubtypeTester(classEnvironment);
+  var environment = tester.environment;
+  for (var testCase in testCases) {
+    test('$testCase', () {
+      var subtype = environment.parseFresh(testCase.subtype);
+      var supertype = environment.parseFresh(testCase.supertype);
+      if (tester.isSubtypeOf(subtype, supertype) != testCase.isSubtype) {
+        fail('isSubtypeOf(${testCase.subtype}, ${testCase.supertype}) returned '
+            '${!testCase.isSubtype} but should return ${testCase.isSubtype}');
+      }
+      if (subtype != supertype && tester.isSubtypeOf(supertype, subtype)) {
+        fail('isSubtypeOf(${testCase.supertype}, ${testCase.subtype}) returned '
+            'true but should return false');
+      }
+    });
+  }
+}
diff --git a/pkg/kernel/test/type_unification_test_disabled.dart b/pkg/kernel/test/type_unification_test_disabled.dart
new file mode 100644
index 0000000..ed75d26
--- /dev/null
+++ b/pkg/kernel/test/type_unification_test_disabled.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/type_algebra.dart';
+import 'package:test/test.dart';
+import 'type_parser.dart';
+import 'dart:io';
+
+final List<TestCase> testCases = <TestCase>[
+  successCase('List<T>', 'List<String>', {'T': 'String'}),
+  successCase('List<String>', 'List<T>', {'T': 'String'}),
+  successCase('List<T>', 'List<T>', {'T': null}),
+  successCase('List<S>', 'List<T>', {'S': 'T'}),
+  successCase('List<S>', 'List<T>', {'T': 'S'}),
+  successCase(
+      'List<S>', 'List<T>', {'S': 'T', 'T': null}), // Require left bias.
+  failureCase('List<S>', 'List<T>', []),
+
+  failureCase('List<T>', 'T', ['T']),
+  failureCase('List<List<T>>', 'List<T>', ['T']),
+  failureCase('Map<S, T>', 'Map<List<T>, List<S>>', ['T', 'S']),
+
+  failureCase('Map<Map<S,String>, Map<int,S>>',
+      'Map<Map<int, S>, Map<S, String>>', ['S']),
+  successCase('Map<Map<S, int>, Map<int, S>>', 'Map<Map<int, S>, Map<S, int>>',
+      {'S': 'int'}),
+  successCase('Map<Map<S, String>, Map<int, T>>',
+      'Map<Map<int, T>, Map<S, String>>', {'S': 'int', 'T': 'String'}),
+
+  successCase('Map<S, List<T>>', 'Map<T, List<S>>', {'S': 'T'}),
+  successCase('Map<S, T>', 'Map<S, List<S>>', {'T': 'List<S>'}),
+  successCase('Map<S, T>', 'Map<S, List<S>>', {'T': 'List<S>', 'S': null}),
+  successCase('Map<List<S>, T>', 'Map<T, List<S>>', {'T': 'List<S>'}),
+  successCase(
+      'Map<List<S>, T>', 'Map<T, List<S>>', {'T': 'List<S>', 'S': null}),
+
+  successCase('<E>(E) => E', '<T>(T) => T', {}),
+  successCase('<E>(E, S) => E', '<T>(T, int) => T', {'S': 'int'}),
+  failureCase('<E>(E, S) => E', '<T>(T, T) => T', ['S']),
+  successCase(
+      '<E>(E) => <T>(T) => Map<E,T>', '<E>(E) => <T>(T) => Map<E,T>', {}),
+  successCase('<E>(E,_) => E', '<T>(T,_) => T', {}),
+
+  successCase('(x:int,y:String) => int', '(y:String,x:int) => int', {}),
+  successCase('<S,T>(x:S,y:T) => S', '<S,T>(y:T,x:S) => S', {}),
+  successCase('(x:<T>(T)=>T,y:<S>(S)=>S) => int', '(y:<S>(S)=>S,x:<T>(T)=>T) => int', {}),
+  successCase('(x:<T>(T)=>T,y:<S>(S,S,S)=>S) => int', '(y:<S>(S,S,S)=>S,x:<T>(T)=>T) => int', {}),
+];
+
+class TestCase {
+  String type1;
+  String type2;
+  Iterable<String> quantifiedVariables;
+  Map<String, String> expectedSubstitution; // Null if unification should fail.
+
+  TestCase.success(this.type1, this.type2, this.expectedSubstitution) {
+    quantifiedVariables = expectedSubstitution.keys;
+  }
+
+  TestCase.fail(this.type1, this.type2, this.quantifiedVariables);
+
+  bool get shouldSucceed => expectedSubstitution != null;
+
+  String toString() => '∃ ${quantifiedVariables.join(',')}. $type1 = $type2';
+}
+
+TestCase successCase(String type1, String type2, Map<String, String> expected,
+    {bool debug: false}) {
+  return new TestCase.success(type1, type2, expected);
+}
+
+TestCase failureCase(
+    String type1, String type2, List<String> quantifiedVariables,
+    {bool debug: false}) {
+  return new TestCase.fail(type1, type2, quantifiedVariables);
+}
+
+int numFailures = 0;
+
+void reportFailure(TestCase testCase, String message) {
+  ++numFailures;
+  fail('$message in `$testCase`');
+}
+
+main() {
+  for (TestCase testCase in testCases) {
+    test('$testCase', () {
+      var env = new LazyTypeEnvironment();
+      var type1 = env.parse(testCase.type1);
+      var type2 = env.parse(testCase.type2);
+      var quantifiedVariables =
+          testCase.quantifiedVariables.map(env.getTypeParameter).toSet();
+      var substitution = unifyTypes(type1, type2, quantifiedVariables);
+      if (testCase.shouldSucceed) {
+        if (substitution == null) {
+          reportFailure(testCase, 'Unification failed');
+        } else {
+          for (var key in testCase.expectedSubstitution.keys) {
+            var typeParameter = env.getTypeParameter(key);
+            if (testCase.expectedSubstitution[key] == null) {
+              if (substitution.containsKey(key)) {
+                var actualType = substitution[typeParameter];
+                reportFailure(
+                    testCase,
+                    'Incorrect substitution '
+                    '`$key = $actualType` should be unbound');
+              }
+            } else {
+              var expectedType = env.parse(testCase.expectedSubstitution[key]);
+              var actualType = substitution[typeParameter];
+              if (actualType != expectedType) {
+                reportFailure(
+                    testCase,
+                    'Incorrect substitution '
+                    '`$key = $actualType` should be `$key = $expectedType`');
+              }
+            }
+          }
+          var boundTypeVariables = testCase.expectedSubstitution.keys
+              .where((name) => testCase.expectedSubstitution[name] != null);
+          if (substitution.length != boundTypeVariables.length) {
+            reportFailure(
+                testCase,
+                'Substituted `${substitution.keys.join(',')}` '
+                'but should only substitute `${boundTypeVariables.join(',')}`');
+          }
+        }
+      } else {
+        if (substitution != null) {
+          reportFailure(testCase, 'Unification was supposed to fail');
+        }
+      }
+    });
+  }
+  if (numFailures > 0) {
+    exit(1);
+  }
+}
diff --git a/pkg/kernel/test/typecheck.dart b/pkg/kernel/test/typecheck.dart
new file mode 100644
index 0000000..a02815a
--- /dev/null
+++ b/pkg/kernel/test/typecheck.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/kernel.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_checker.dart';
+import 'dart:io';
+
+final String usage = '''
+Usage: typecheck FILE.dill
+
+Runs the strong mode type checker on the given program.
+''';
+
+main(List<String> args) {
+  if (args.length != 1) {
+    print(usage);
+    exit(1);
+  }
+  var program = loadProgramFromBinary(args[0]);
+  var coreTypes = new CoreTypes(program);
+  var hierarchy = new ClassHierarchy(program);
+  new TestTypeChecker(coreTypes, hierarchy).checkProgram(program);
+}
+
+class TestTypeChecker extends TypeChecker {
+  TestTypeChecker(CoreTypes coreTypes, ClassHierarchy hierarchy)
+      : super(coreTypes, hierarchy);
+
+  @override
+  void checkAssignable(TreeNode where, DartType from, DartType to) {
+    if (!environment.isSubtypeOf(from, to)) {
+      fail(where, '$from is not a subtype of $to');
+    }
+  }
+
+  @override
+  void fail(TreeNode where, String message) {
+    Location location = where.location;
+    String locationString = location == null ? '' : '($location)';
+    print('[error] $message $locationString');
+  }
+}
diff --git a/pkg/kernel/test/uint31_pair_map_bench.dart b/pkg/kernel/test/uint31_pair_map_bench.dart
new file mode 100644
index 0000000..1e6d5b0
--- /dev/null
+++ b/pkg/kernel/test/uint31_pair_map_bench.dart
@@ -0,0 +1,65 @@
+import 'package:kernel/type_propagation/canonicalizer.dart';
+
+main() {
+  Stopwatch watch = new Stopwatch()..start();
+
+  const int lowBiasKeys = 100;
+  const int highBiasKeys = 10000;
+  const int noBiasKeys = 1000;
+
+  Uint31PairMap map;
+
+  // Warm up.
+  map = new Uint31PairMap();
+  for (int i = 0; i < noBiasKeys; ++i) {
+    for (int j = 0; j < noBiasKeys; ++j) {
+      map.lookup(i, j);
+      map.put(i + j);
+    }
+  }
+
+  // Even distributed tuple components.
+  watch.reset();
+  map = new Uint31PairMap();
+  for (int i = 0; i < noBiasKeys; ++i) {
+    for (int j = 0; j < noBiasKeys; ++j) {
+      map.lookup(i, j);
+      map.put(i + j);
+    }
+  }
+  int noBiasTime = watch.elapsedMicroseconds;
+
+  // Left-bias: more unique keys in the first component.
+  watch.reset();
+  map = new Uint31PairMap();
+  for (int i = 0; i < highBiasKeys; ++i) {
+    for (int j = 0; j < lowBiasKeys; ++j) {
+      map.lookup(i, j);
+      map.put(i + j);
+    }
+  }
+  int leftBiasTime = watch.elapsedMicroseconds;
+
+  // Right-bias: more unique keys in the second component.
+  watch.reset();
+  map = new Uint31PairMap();
+  for (int i = 0; i < lowBiasKeys; ++i) {
+    for (int j = 0; j < highBiasKeys; ++j) {
+      map.lookup(i, j);
+      map.put(i + j);
+    }
+  }
+  int rightBiasTime = watch.elapsedMicroseconds;
+
+  print('''
+bias.none:  ${formatTime(noBiasTime)}
+bias.left:  ${formatTime(leftBiasTime)}
+bias.right: ${formatTime(rightBiasTime)}
+''');
+}
+
+
+String formatTime(int microseconds) {
+  double seconds = microseconds / 1000000.0;
+  return '$seconds s';
+}
diff --git a/pkg/kernel/test/uint31_pair_map_test_disabled.dart b/pkg/kernel/test/uint31_pair_map_test_disabled.dart
new file mode 100644
index 0000000..316f971
--- /dev/null
+++ b/pkg/kernel/test/uint31_pair_map_test_disabled.dart
@@ -0,0 +1,33 @@
+import 'dart:math';
+import 'package:kernel/type_propagation/canonicalizer.dart';
+import 'package:test/test.dart';
+
+Random random = new Random(12345);
+
+main() {
+  test('Uint31PairMap randomized tests', runTest);
+}
+
+runTest() {
+  const int trials = 1000;
+  const int insertions = 1000;
+  const int uniqueKeys = 900;
+  for (int trial = 0; trial < trials; ++trial) {
+    int nextValue = 1;
+    Map<Point<int>, int> trusted = <Point<int>, int>{};
+    Uint31PairMap candidate = new Uint31PairMap();
+    for (int i = 0; i < insertions; ++i) {
+      int x = random.nextInt(uniqueKeys);
+      int y = random.nextInt(uniqueKeys);
+      Point key = new Point(x, y);
+      int trustedValue = trusted[key];
+      int candidateValue = candidate.lookup(x, y);
+      expect(candidateValue, equals(trustedValue));
+      if (trustedValue == null) {
+        int newValue = nextValue++;
+        trusted[key] = newValue;
+        candidate.put(newValue);
+      }
+    }
+  }
+}
diff --git a/pkg/kernel/test/verify_bench.dart b/pkg/kernel/test/verify_bench.dart
new file mode 100644
index 0000000..17fd65d
--- /dev/null
+++ b/pkg/kernel/test/verify_bench.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:kernel/kernel.dart';
+import 'package:kernel/verifier.dart';
+
+final String usage = '''
+Usage: verify_bench FILE.dill
+
+Measures the time it takes to run kernel verifier on the given program.
+''';
+
+main(List<String> args) {
+  if (args.length != 1) {
+    print(usage);
+    exit(1);
+  }
+  var program = loadProgramFromBinary(args[0]);
+  var watch = new Stopwatch()..start();
+  verifyProgram(program);
+  print('Cold: ${watch.elapsedMilliseconds} ms');
+  const int warmUpTrials = 20;
+  for (int i = 0; i < warmUpTrials; ++i) {
+    verifyProgram(program);
+  }
+  watch.reset();
+  const int numberOfTrials = 100;
+  for (int i = 0; i < numberOfTrials; ++i) {
+    verifyProgram(program);
+  }
+  double millisecondsPerRun = watch.elapsedMilliseconds / numberOfTrials;
+  print('Hot:  $millisecondsPerRun ms');
+}
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
new file mode 100644
index 0000000..67a7e96
--- /dev/null
+++ b/pkg/kernel/test/verify_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:kernel/ast.dart';
+import 'package:kernel/text/ast_to_text.dart';
+import 'package:kernel/verifier.dart';
+import 'package:test/test.dart';
+
+/// Checks that the sanity checks correctly find errors in invalid programs.
+///
+/// The frontend should never generate invalid programs, so we have to test
+/// these by manually constructing invalid ASTs.
+///
+/// We only test negative cases here, as we get plenty of positive cases by
+/// compiling the Dart test suite with sanity checks enabled.
+main() {
+  negativeTest('VariableGet out of scope', () {
+    return new VariableGet(makeVariable());
+  });
+  negativeTest('VariableSet out of scope', () {
+    return new VariableSet(makeVariable(), new NullLiteral());
+  });
+  negativeTest('Variable block scope', () {
+    VariableDeclaration variable = makeVariable();
+    return new Block([
+      new Block([variable]),
+      new ReturnStatement(new VariableGet(variable))
+    ]);
+  });
+  negativeTest('Variable let scope', () {
+    VariableDeclaration variable = makeVariable();
+    return new LogicalExpression(new Let(variable, new VariableGet(variable)),
+        '&&', new VariableGet(variable));
+  });
+  negativeTest('Variable redeclared', () {
+    VariableDeclaration variable = makeVariable();
+    return new Block([variable, variable]);
+  });
+  negativeTest('Member redeclared', () {
+    Field field = new Field(new Name('field'), initializer: new NullLiteral());
+    return new Class(
+        name: 'Test',
+        supertype: objectClass.asRawSupertype,
+        fields: [field, field]);
+  });
+  negativeTest('Type parameter out of scope', () {
+    var parameter = makeTypeParameter();
+    return new ListLiteral([], typeArgument: new TypeParameterType(parameter));
+  });
+  negativeTest('Class type parameter from another class', () {
+    return new TypeLiteral(new TypeParameterType(otherClass.typeParameters[0]));
+  });
+  negativeTest('Class type parameter in static method', () {
+    return new Procedure(
+        new Name('test'),
+        ProcedureKind.Method,
+        new FunctionNode(new ReturnStatement(
+            new TypeLiteral(new TypeParameterType(classTypeParameter)))),
+        isStatic: true);
+  });
+  negativeTest('Class type parameter in static field', () {
+    return new Field(new Name('field'),
+        initializer: new TypeLiteral(new TypeParameterType(classTypeParameter)),
+        isStatic: true);
+  });
+  negativeTest('Method type parameter out of scope', () {
+    var parameter = makeTypeParameter();
+    return new Class(
+        name: 'Test',
+        supertype: objectClass.asRawSupertype,
+        procedures: [
+          new Procedure(
+              new Name('generic'),
+              ProcedureKind.Method,
+              new FunctionNode(new EmptyStatement(),
+                  typeParameters: [parameter])),
+          new Procedure(
+              new Name('use'),
+              ProcedureKind.Method,
+              new FunctionNode(new ReturnStatement(
+                  new TypeLiteral(new TypeParameterType(parameter)))))
+        ]);
+  });
+  negativeTest('Interface type arity too low', () {
+    return new TypeLiteral(new InterfaceType(otherClass, []));
+  });
+  negativeTest('Interface type arity too high', () {
+    return new TypeLiteral(
+        new InterfaceType(otherClass, [new DynamicType(), new DynamicType()]));
+  });
+  negativeTest('Dangling interface type', () {
+    return new TypeLiteral(new InterfaceType(new Class()));
+  });
+  negativeTest('Dangling field get', () {
+    return new DirectPropertyGet(new NullLiteral(), new Field(new Name('foo')));
+  });
+  negativeTest('Missing block parent pointer', () {
+    var block = new Block([]);
+    block.statements.add(new ReturnStatement());
+    return block;
+  });
+  negativeTest('Missing function parent pointer', () {
+    var procedure = new Procedure(new Name('test'), ProcedureKind.Method, null);
+    procedure.function = new FunctionNode(new EmptyStatement());
+    return procedure;
+  });
+}
+
+checkHasError(Program program) {
+  bool passed = false;
+  try {
+    verifyProgram(program);
+    passed = true;
+  } catch (e) {}
+  if (passed) {
+    fail('Failed to reject invalid program:\n${programToString(program)}');
+  }
+}
+
+Class objectClass = new Class(name: 'Object');
+
+Library stubLibrary = new Library(Uri.parse('dart:core'))
+  ..addClass(objectClass);
+
+TypeParameter classTypeParameter = makeTypeParameter('T');
+
+Class otherClass = new Class(
+    name: 'OtherClass',
+    typeParameters: [makeTypeParameter('OtherT')],
+    supertype: objectClass.asRawSupertype);
+
+negativeTest(String name, TreeNode makeBody()) {
+  test(name, () {
+    var node = makeBody();
+    if (node is Expression) {
+      node = new ReturnStatement(node);
+    }
+    if (node is Statement) {
+      node = new FunctionNode(node);
+    }
+    if (node is FunctionNode) {
+      node = new Procedure(new Name('test'), ProcedureKind.Method, node);
+    }
+    if (node is Member) {
+      node = new Class(
+          name: 'Test',
+          typeParameters: [classTypeParameter],
+          supertype: objectClass.asRawSupertype)..addMember(node);
+    }
+    if (node is Class) {
+      node = new Library(Uri.parse('test.dart'),
+          classes: <Class>[node, otherClass]);
+    }
+    if (node is Library) {
+      node = new Program(<Library>[node, stubLibrary]);
+    }
+    assert(node is Program);
+    checkHasError(node);
+  });
+}
+
+VariableDeclaration makeVariable() => new VariableDeclaration(null);
+
+TypeParameter makeTypeParameter([String name]) {
+  return new TypeParameter(name, new InterfaceType(objectClass));
+}
diff --git a/pkg/kernel/testcases/.gitignore b/pkg/kernel/testcases/.gitignore
new file mode 100644
index 0000000..8958632
--- /dev/null
+++ b/pkg/kernel/testcases/.gitignore
@@ -0,0 +1 @@
+*.current.txt
diff --git a/pkg/kernel/testcases/input/DeltaBlue.dart b/pkg/kernel/testcases/input/DeltaBlue.dart
new file mode 100644
index 0000000..cb606f8
--- /dev/null
+++ b/pkg/kernel/testcases/input/DeltaBlue.dart
@@ -0,0 +1,722 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Copyright 1996 John Maloney and Mario Wolczko
+//
+// This file is part of GNU Smalltalk.
+//
+// GNU Smalltalk is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2, or (at your option) any later version.
+//
+// GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+// details.
+//
+// You should have received a copy of the GNU General Public License along with
+// GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
+// Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// Translated first from Smalltalk to JavaScript, and finally to
+// Dart by Google 2008-2010.
+
+/**
+ * A Dart implementation of the DeltaBlue constraint-solving
+ * algorithm, as described in:
+ *
+ * "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
+ *   Bjorn N. Freeman-Benson and John Maloney
+ *   January 1990 Communications of the ACM,
+ *   also available as University of Washington TR 89-08-06.
+ *
+ * Beware: this benchmark is written in a grotesque style where
+ * the constraint model is built by side-effects from constructors.
+ * I've kept it this way to avoid deviating too much from the original
+ * implementation.
+ */
+
+main() {
+  new DeltaBlue().run();
+}
+
+/// Benchmark class required to report results.
+class DeltaBlue {
+  void run() {
+    chainTest(100);
+    projectionTest(100);
+  }
+}
+
+
+/**
+ * Strengths are used to measure the relative importance of constraints.
+ * New strengths may be inserted in the strength hierarchy without
+ * disrupting current constraints.  Strengths cannot be created outside
+ * this class, so == can be used for value comparison.
+ */
+class Strength {
+
+  final int value;
+  final String name;
+
+  const Strength(this.value, this.name);
+
+  Strength nextWeaker() =>
+     const <Strength>[STRONG_PREFERRED, PREFERRED, STRONG_DEFAULT, NORMAL,
+                      WEAK_DEFAULT, WEAKEST][value];
+
+  static bool stronger(Strength s1, Strength s2) {
+    return s1.value < s2.value;
+  }
+
+  static bool weaker(Strength s1, Strength s2) {
+    return s1.value > s2.value;
+  }
+
+  static Strength weakest(Strength s1, Strength s2) {
+    return weaker(s1, s2) ? s1 : s2;
+  }
+
+  static Strength strongest(Strength s1, Strength s2) {
+    return stronger(s1, s2) ? s1 : s2;
+  }
+}
+
+
+// Compile time computed constants.
+const REQUIRED         = const Strength(0, "required");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const PREFERRED        = const Strength(2, "preferred");
+const STRONG_DEFAULT   = const Strength(3, "strongDefault");
+const NORMAL           = const Strength(4, "normal");
+const WEAK_DEFAULT     = const Strength(5, "weakDefault");
+const WEAKEST          = const Strength(6, "weakest");
+
+
+abstract class Constraint {
+
+  final Strength strength;
+
+  const Constraint(this.strength);
+
+  bool isSatisfied();
+  void markUnsatisfied();
+  void addToGraph();
+  void removeFromGraph();
+  void chooseMethod(int mark);
+  void markInputs(int mark);
+  bool inputsKnown(int mark);
+  Variable output();
+  void execute();
+  void recalculate();
+
+  /// Activate this constraint and attempt to satisfy it.
+  void addConstraint() {
+    addToGraph();
+    planner.incrementalAdd(this);
+  }
+
+  /**
+   * Attempt to find a way to enforce this constraint. If successful,
+   * record the solution, perhaps modifying the current dataflow
+   * graph. Answer the constraint that this constraint overrides, if
+   * there is one, or nil, if there isn't.
+   * Assume: I am not already satisfied.
+   */
+  Constraint satisfy(mark) {
+    chooseMethod(mark);
+    if (!isSatisfied()) {
+      if (strength == REQUIRED) {
+        print("Could not satisfy a required constraint!");
+      }
+      return null;
+    }
+    markInputs(mark);
+    Variable out = output();
+    Constraint overridden = out.determinedBy;
+    if (overridden != null) overridden.markUnsatisfied();
+    out.determinedBy = this;
+    if (!planner.addPropagate(this, mark)) print("Cycle encountered");
+    out.mark = mark;
+    return overridden;
+  }
+
+  void destroyConstraint() {
+    if (isSatisfied()) planner.incrementalRemove(this);
+    removeFromGraph();
+  }
+
+  /**
+   * Normal constraints are not input constraints.  An input constraint
+   * is one that depends on external state, such as the mouse, the
+   * keybord, a clock, or some arbitraty piece of imperative code.
+   */
+  bool isInput() => false;
+}
+
+/**
+ * Abstract superclass for constraints having a single possible output variable.
+ */
+abstract class UnaryConstraint extends Constraint {
+
+  final Variable myOutput;
+  bool satisfied = false;
+
+  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {
+    addConstraint();
+  }
+
+  /// Adds this constraint to the constraint graph
+  void addToGraph() {
+    myOutput.addConstraint(this);
+    satisfied = false;
+  }
+
+  /// Decides if this constraint can be satisfied and records that decision.
+  void chooseMethod(int mark) {
+    satisfied = (myOutput.mark != mark)
+      && Strength.stronger(strength, myOutput.walkStrength);
+  }
+
+  /// Returns true if this constraint is satisfied in the current solution.
+  bool isSatisfied() => satisfied;
+
+  void markInputs(int mark) {
+    // has no inputs.
+  }
+
+  /// Returns the current output variable.
+  Variable output() => myOutput;
+
+  /**
+   * Calculate the walkabout strength, the stay flag, and, if it is
+   * 'stay', the value for the current output of this constraint. Assume
+   * this constraint is satisfied.
+   */
+  void recalculate() {
+    myOutput.walkStrength = strength;
+    myOutput.stay = !isInput();
+    if (myOutput.stay) execute(); // Stay optimization.
+  }
+
+  /// Records that this constraint is unsatisfied.
+  void markUnsatisfied() {
+    satisfied = false;
+  }
+
+  bool inputsKnown(int mark) => true;
+
+  void removeFromGraph() {
+    if (myOutput != null) myOutput.removeConstraint(this);
+    satisfied = false;
+  }
+}
+
+
+/**
+ * Variables that should, with some level of preference, stay the same.
+ * Planners may exploit the fact that instances, if satisfied, will not
+ * change their output during plan execution.  This is called "stay
+ * optimization".
+ */
+class StayConstraint extends UnaryConstraint {
+
+  StayConstraint(Variable v, Strength str) : super(v, str);
+
+  void execute() {
+    // Stay constraints do nothing.
+  }
+}
+
+
+/**
+ * A unary input constraint used to mark a variable that the client
+ * wishes to change.
+ */
+class EditConstraint extends UnaryConstraint {
+
+  EditConstraint(Variable v, Strength str) : super(v, str);
+
+  /// Edits indicate that a variable is to be changed by imperative code.
+  bool isInput() => true;
+
+  void execute() {
+    // Edit constraints do nothing.
+  }
+}
+
+
+// Directions.
+const int NONE = 1;
+const int FORWARD = 2;
+const int BACKWARD = 0;
+
+
+/**
+ * Abstract superclass for constraints having two possible output
+ * variables.
+ */
+abstract class BinaryConstraint extends Constraint {
+
+  Variable v1;
+  Variable v2;
+  int direction = NONE;
+
+  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {
+    addConstraint();
+  }
+
+  /**
+   * Decides if this constraint can be satisfied and which way it
+   * should flow based on the relative strength of the variables related,
+   * and record that decision.
+   */
+  void chooseMethod(int mark) {
+    if (v1.mark == mark) {
+      direction = (v2.mark != mark &&
+                   Strength.stronger(strength, v2.walkStrength))
+        ? FORWARD : NONE;
+    }
+    if (v2.mark == mark) {
+      direction = (v1.mark != mark &&
+                   Strength.stronger(strength, v1.walkStrength))
+        ? BACKWARD : NONE;
+    }
+    if (Strength.weaker(v1.walkStrength, v2.walkStrength)) {
+      direction = Strength.stronger(strength, v1.walkStrength)
+        ? BACKWARD : NONE;
+    } else {
+      direction = Strength.stronger(strength, v2.walkStrength)
+        ? FORWARD : BACKWARD;
+    }
+  }
+
+  /// Add this constraint to the constraint graph.
+  void addToGraph() {
+    v1.addConstraint(this);
+    v2.addConstraint(this);
+    direction = NONE;
+  }
+
+  /// Answer true if this constraint is satisfied in the current solution.
+  bool isSatisfied() => direction != NONE;
+
+  /// Mark the input variable with the given mark.
+  void markInputs(int mark) {
+    input().mark = mark;
+  }
+
+  /// Returns the current input variable
+  Variable input() => direction == FORWARD ? v1 : v2;
+
+  /// Returns the current output variable.
+  Variable output() => direction == FORWARD ? v2 : v1;
+
+  /**
+   * Calculate the walkabout strength, the stay flag, and, if it is
+   * 'stay', the value for the current output of this
+   * constraint. Assume this constraint is satisfied.
+   */
+  void recalculate() {
+    Variable ihn = input(), out = output();
+    out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
+    out.stay = ihn.stay;
+    if (out.stay) execute();
+  }
+
+  /// Record the fact that this constraint is unsatisfied.
+  void markUnsatisfied() {
+    direction = NONE;
+  }
+
+  bool inputsKnown(int mark) {
+    Variable i = input();
+    return i.mark == mark || i.stay || i.determinedBy == null;
+  }
+
+  void removeFromGraph() {
+    if (v1 != null) v1.removeConstraint(this);
+    if (v2 != null) v2.removeConstraint(this);
+    direction = NONE;
+  }
+}
+
+
+/**
+ * Relates two variables by the linear scaling relationship: "v2 =
+ * (v1 * scale) + offset". Either v1 or v2 may be changed to maintain
+ * this relationship but the scale factor and offset are considered
+ * read-only.
+ */
+
+class ScaleConstraint extends BinaryConstraint {
+
+  final Variable scale;
+  final Variable offset;
+
+  ScaleConstraint(Variable src, this.scale, this.offset,
+                  Variable dest, Strength strength)
+    : super(src, dest, strength);
+
+  /// Adds this constraint to the constraint graph.
+  void addToGraph() {
+    super.addToGraph();
+    scale.addConstraint(this);
+    offset.addConstraint(this);
+  }
+
+  void removeFromGraph() {
+    super.removeFromGraph();
+    if (scale != null) scale.removeConstraint(this);
+    if (offset != null) offset.removeConstraint(this);
+  }
+
+  void markInputs(int mark) {
+    super.markInputs(mark);
+    scale.mark = offset.mark = mark;
+  }
+
+  /// Enforce this constraint. Assume that it is satisfied.
+  void execute() {
+    if (direction == FORWARD) {
+      v2.value = v1.value * scale.value + offset.value;
+    } else {
+      v1.value = (v2.value - offset.value) ~/ scale.value;
+    }
+  }
+
+  /**
+   * Calculate the walkabout strength, the stay flag, and, if it is
+   * 'stay', the value for the current output of this constraint. Assume
+   * this constraint is satisfied.
+   */
+  void recalculate() {
+    Variable ihn = input(), out = output();
+    out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
+    out.stay = ihn.stay && scale.stay && offset.stay;
+    if (out.stay) execute();
+  }
+
+}
+
+
+/**
+ * Constrains two variables to have the same value.
+ */
+class EqualityConstraint extends BinaryConstraint {
+
+  EqualityConstraint(Variable v1, Variable v2, Strength strength)
+    : super(v1, v2, strength);
+
+  /// Enforce this constraint. Assume that it is satisfied.
+  void execute() {
+    output().value = input().value;
+  }
+}
+
+
+/**
+ * A constrained variable. In addition to its value, it maintain the
+ * structure of the constraint graph, the current dataflow graph, and
+ * various parameters of interest to the DeltaBlue incremental
+ * constraint solver.
+ **/
+class Variable {
+
+  List<Constraint> constraints = <Constraint>[];
+  Constraint determinedBy;
+  int mark = 0;
+  Strength walkStrength = WEAKEST;
+  bool stay = true;
+  int value;
+  final String name;
+
+  Variable(this.name, this.value);
+
+  /**
+   * Add the given constraint to the set of all constraints that refer
+   * this variable.
+   */
+  void addConstraint(Constraint c) {
+    constraints.add(c);
+  }
+
+  /// Removes all traces of c from this variable.
+  void removeConstraint(Constraint c) {
+    constraints.remove(c);
+    if (determinedBy == c) determinedBy = null;
+  }
+}
+
+
+class Planner {
+
+  int currentMark = 0;
+
+  /**
+   * Attempt to satisfy the given constraint and, if successful,
+   * incrementally update the dataflow graph.  Details: If satifying
+   * the constraint is successful, it may override a weaker constraint
+   * on its output. The algorithm attempts to resatisfy that
+   * constraint using some other method. This process is repeated
+   * until either a) it reaches a variable that was not previously
+   * determined by any constraint or b) it reaches a constraint that
+   * is too weak to be satisfied using any of its methods. The
+   * variables of constraints that have been processed are marked with
+   * a unique mark value so that we know where we've been. This allows
+   * the algorithm to avoid getting into an infinite loop even if the
+   * constraint graph has an inadvertent cycle.
+   */
+  void incrementalAdd(Constraint c) {
+    int mark = newMark();
+    for(Constraint overridden = c.satisfy(mark);
+        overridden != null;
+        overridden = overridden.satisfy(mark));
+  }
+
+  /**
+   * Entry point for retracting a constraint. Remove the given
+   * constraint and incrementally update the dataflow graph.
+   * Details: Retracting the given constraint may allow some currently
+   * unsatisfiable downstream constraint to be satisfied. We therefore collect
+   * a list of unsatisfied downstream constraints and attempt to
+   * satisfy each one in turn. This list is traversed by constraint
+   * strength, strongest first, as a heuristic for avoiding
+   * unnecessarily adding and then overriding weak constraints.
+   * Assume: [c] is satisfied.
+   */
+  void incrementalRemove(Constraint c) {
+    Variable out = c.output();
+    c.markUnsatisfied();
+    c.removeFromGraph();
+    List<Constraint> unsatisfied = removePropagateFrom(out);
+    Strength strength = REQUIRED;
+    do {
+      for (int i = 0; i < unsatisfied.length; i++) {
+        Constraint u = unsatisfied[i];
+        if (u.strength == strength) incrementalAdd(u);
+      }
+      strength = strength.nextWeaker();
+    } while (strength != WEAKEST);
+  }
+
+  /// Select a previously unused mark value.
+  int newMark() => ++currentMark;
+
+  /**
+   * Extract a plan for resatisfaction starting from the given source
+   * constraints, usually a set of input constraints. This method
+   * assumes that stay optimization is desired; the plan will contain
+   * only constraints whose output variables are not stay. Constraints
+   * that do no computation, such as stay and edit constraints, are
+   * not included in the plan.
+   * Details: The outputs of a constraint are marked when it is added
+   * to the plan under construction. A constraint may be appended to
+   * the plan when all its input variables are known. A variable is
+   * known if either a) the variable is marked (indicating that has
+   * been computed by a constraint appearing earlier in the plan), b)
+   * the variable is 'stay' (i.e. it is a constant at plan execution
+   * time), or c) the variable is not determined by any
+   * constraint. The last provision is for past states of history
+   * variables, which are not stay but which are also not computed by
+   * any constraint.
+   * Assume: [sources] are all satisfied.
+   */
+  Plan makePlan(List<Constraint> sources) {
+    int mark = newMark();
+    Plan plan = new Plan();
+    List<Constraint> todo = sources;
+    while (todo.length > 0) {
+      Constraint c = todo.removeLast();
+      if (c.output().mark != mark && c.inputsKnown(mark)) {
+        plan.addConstraint(c);
+        c.output().mark = mark;
+        addConstraintsConsumingTo(c.output(), todo);
+      }
+    }
+    return plan;
+  }
+
+  /**
+   * Extract a plan for resatisfying starting from the output of the
+   * given [constraints], usually a set of input constraints.
+   */
+  Plan extractPlanFromConstraints(List<Constraint> constraints) {
+    List<Constraint> sources = <Constraint>[];
+    for (int i = 0; i < constraints.length; i++) {
+      Constraint c = constraints[i];
+      // if not in plan already and eligible for inclusion.
+      if (c.isInput() && c.isSatisfied()) sources.add(c);
+    }
+    return makePlan(sources);
+  }
+
+  /**
+   * Recompute the walkabout strengths and stay flags of all variables
+   * downstream of the given constraint and recompute the actual
+   * values of all variables whose stay flag is true. If a cycle is
+   * detected, remove the given constraint and answer
+   * false. Otherwise, answer true.
+   * Details: Cycles are detected when a marked variable is
+   * encountered downstream of the given constraint. The sender is
+   * assumed to have marked the inputs of the given constraint with
+   * the given mark. Thus, encountering a marked node downstream of
+   * the output constraint means that there is a path from the
+   * constraint's output to one of its inputs.
+   */
+  bool addPropagate(Constraint c, int mark) {
+    List<Constraint> todo = <Constraint>[c];
+    while (todo.length > 0) {
+      Constraint d = todo.removeLast();
+      if (d.output().mark == mark) {
+        incrementalRemove(c);
+        return false;
+      }
+      d.recalculate();
+      addConstraintsConsumingTo(d.output(), todo);
+    }
+    return true;
+  }
+
+  /**
+   * Update the walkabout strengths and stay flags of all variables
+   * downstream of the given constraint. Answer a collection of
+   * unsatisfied constraints sorted in order of decreasing strength.
+   */
+  List<Constraint> removePropagateFrom(Variable out) {
+    out.determinedBy = null;
+    out.walkStrength = WEAKEST;
+    out.stay = true;
+    List<Constraint> unsatisfied = <Constraint>[];
+    List<Variable> todo = <Variable>[out];
+    while (todo.length > 0) {
+      Variable v = todo.removeLast();
+      for (int i = 0; i < v.constraints.length; i++) {
+        Constraint c = v.constraints[i];
+        if (!c.isSatisfied()) unsatisfied.add(c);
+      }
+      Constraint determining = v.determinedBy;
+      for (int i = 0; i < v.constraints.length; i++) {
+        Constraint next = v.constraints[i];
+        if (next != determining && next.isSatisfied()) {
+          next.recalculate();
+          todo.add(next.output());
+        }
+      }
+    }
+    return unsatisfied;
+  }
+
+  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {
+    Constraint determining = v.determinedBy;
+    for (int i = 0; i < v.constraints.length; i++) {
+      Constraint c = v.constraints[i];
+      if (c != determining && c.isSatisfied()) coll.add(c);
+    }
+  }
+}
+
+
+/**
+ * A Plan is an ordered list of constraints to be executed in sequence
+ * to resatisfy all currently satisfiable constraints in the face of
+ * one or more changing inputs.
+ */
+class Plan {
+  List<Constraint> list = <Constraint>[];
+
+  void addConstraint(Constraint c) {
+    list.add(c);
+  }
+
+  int size() => list.length;
+
+  void execute() {
+    for (int i = 0; i < list.length; i++) {
+      list[i].execute();
+    }
+  }
+}
+
+
+/**
+ * This is the standard DeltaBlue benchmark. A long chain of equality
+ * constraints is constructed with a stay constraint on one end. An
+ * edit constraint is then added to the opposite end and the time is
+ * measured for adding and removing this constraint, and extracting
+ * and executing a constraint satisfaction plan. There are two cases.
+ * In case 1, the added constraint is stronger than the stay
+ * constraint and values must propagate down the entire length of the
+ * chain. In case 2, the added constraint is weaker than the stay
+ * constraint so it cannot be accomodated. The cost in this case is,
+ * of course, very low. Typical situations lie somewhere between these
+ * two extremes.
+ */
+void chainTest(int n) {
+  planner = new Planner();
+  Variable prev = null, first = null, last = null;
+  // Build chain of n equality constraints.
+  for (int i = 0; i <= n; i++) {
+    Variable v = new Variable("v$i", 0);
+    if (prev != null) new EqualityConstraint(prev, v, REQUIRED);
+    if (i == 0) first = v;
+    if (i == n) last = v;
+    prev = v;
+  }
+  new StayConstraint(last, STRONG_DEFAULT);
+  EditConstraint edit = new EditConstraint(first, PREFERRED);
+  Plan plan = planner.extractPlanFromConstraints(<Constraint>[edit]);
+  for (int i = 0; i < 100; i++) {
+    first.value = i;
+    plan.execute();
+    if (last.value != i) {
+      print("Chain test failed:");
+      print("Expected last value to be $i but it was ${last.value}.");
+    }
+  }
+}
+
+/**
+ * This test constructs a two sets of variables related to each
+ * other by a simple linear transformation (scale and offset). The
+ * time is measured to change a variable on either side of the
+ * mapping and to change the scale and offset factors.
+ */
+void projectionTest(int n) {
+  planner = new Planner();
+  Variable scale = new Variable("scale", 10);
+  Variable offset = new Variable("offset", 1000);
+  Variable src = null, dst = null;
+
+  List<Variable> dests = <Variable>[];
+  for (int i = 0; i < n; i++) {
+    src = new Variable("src", i);
+    dst = new Variable("dst", i);
+    dests.add(dst);
+    new StayConstraint(src, NORMAL);
+    new ScaleConstraint(src, scale, offset, dst, REQUIRED);
+  }
+  change(src, 17);
+  if (dst.value != 1170) print("Projection 1 failed");
+  change(dst, 1050);
+  if (src.value != 5) print("Projection 2 failed");
+  change(scale, 5);
+  for (int i = 0; i < n - 1; i++) {
+    if (dests[i].value != i * 5 + 1000) print("Projection 3 failed");
+  }
+  change(offset, 2000);
+  for (int i = 0; i < n - 1; i++) {
+    if (dests[i].value != i * 5 + 2000) print("Projection 4 failed");
+  }
+}
+
+void change(Variable v, int newValue) {
+  EditConstraint edit = new EditConstraint(v, PREFERRED);
+  Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
+  for (int i = 0; i < 10; i++) {
+    v.value = newValue;
+    plan.execute();
+  }
+  edit.destroyConstraint();
+}
+
+Planner planner;
diff --git a/pkg/kernel/testcases/input/argument.dart b/pkg/kernel/testcases/input/argument.dart
new file mode 100644
index 0000000..5052721
--- /dev/null
+++ b/pkg/kernel/testcases/input/argument.dart
@@ -0,0 +1,32 @@
+abstract class Base {}
+
+class Foo extends Base {}
+class Bar extends Base {}
+class Baz extends Base {}
+
+void foo(x) {
+
+}
+
+void bar(x) {
+
+}
+
+void foo_escaped(x) {
+
+}
+
+void bar_escaped(x) {
+
+}
+
+void escape(fn) {
+  fn(new Baz());
+}
+
+main() {
+  foo(new Foo());
+  bar(new Bar());
+  escape(foo_escaped);
+  escape(bar_escaped);
+}
diff --git a/pkg/kernel/testcases/input/arithmetic.dart b/pkg/kernel/testcases/input/arithmetic.dart
new file mode 100644
index 0000000..91b5c0a
--- /dev/null
+++ b/pkg/kernel/testcases/input/arithmetic.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+int foo(int x, int y) {
+  var z = x + y;
+  return z << 4;
+}
+
+void loop(List xs) {
+  int _ = xs.length;
+  for (int i = 0; i < xs.length; i++) {}
+}
+
+main() {
+  foo(4, 5);
+  foo(6, 7);
+  loop(['dfg']);
+}
diff --git a/pkg/kernel/testcases/input/async_function.dart b/pkg/kernel/testcases/input/async_function.dart
new file mode 100644
index 0000000..7b3001e
--- /dev/null
+++ b/pkg/kernel/testcases/input/async_function.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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';
+
+Future<String> asyncString() async {
+  return "foo";
+}
+
+Future<String> asyncString2() async {
+  return asyncString();
+}
+
+Iterable<String> syncStarString() sync* {
+  yield "foo";
+  yield* syncStarString2();
+  yield* stringList;
+}
+
+Iterable<String> syncStarString2() sync* {
+  yield "foo";
+}
+
+Stream<String> asyncStarString() async* {
+  yield "foo";
+  yield* asyncStarString2();
+  yield await asyncString();
+}
+
+Stream<String> asyncStarString2() async* {
+  yield "bar";
+}
+
+List<String> stringList = ["bar"];
+
+main() async {
+  String str = await asyncString();
+}
diff --git a/pkg/kernel/testcases/input/bad_store.dart b/pkg/kernel/testcases/input/bad_store.dart
new file mode 100644
index 0000000..98c7095
--- /dev/null
+++ b/pkg/kernel/testcases/input/bad_store.dart
@@ -0,0 +1,19 @@
+class Foo {
+  var field;
+}
+
+dynamic identity(x) => x;
+
+void use(x) {}
+
+main(List<String> args) {
+  dynamic foo = identity(new Foo());
+  if (args.length > 1) {
+    foo.field = "string";
+    var first = foo.field;
+    use(first);
+    foo.noField = "string";
+    var second = foo.noField;
+    use(second);
+  }
+}
diff --git a/pkg/kernel/testcases/input/call.dart b/pkg/kernel/testcases/input/call.dart
new file mode 100644
index 0000000..15ddb85
--- /dev/null
+++ b/pkg/kernel/testcases/input/call.dart
@@ -0,0 +1,44 @@
+class Callable {
+  call(x) {
+    return "string";
+  }
+}
+
+class CallableGetter {
+  get call => new Callable();
+}
+
+main() {
+  var closure = (x) => x;
+  var int1 = closure(1);
+  var int2 = closure.call(1);
+  var int3 = closure.call.call(1);
+  var int4 = closure.call.call.call(1);
+
+  var callable = new Callable();
+  var string1 = callable(1);
+  var string2 = callable.call(1);
+  var string3 = callable.call.call(1);
+  var string4 = callable.call.call.call(1);
+
+  var callableGetter = new CallableGetter();
+  var string5 = callableGetter(1);
+  var string6 = callableGetter.call(1);
+  var string7 = callableGetter.call.call(1);
+  var string8 = callableGetter.call.call.call(1);
+
+  var nothing1 = closure();
+  var nothing2 = closure.call();
+  var nothing3 = closure.call.call();
+  var nothing4 = closure.call.call.call();
+
+  var nothing5 = callable();
+  var nothing6 = callable.call();
+  var nothing7 = callable.call.call();
+  var nothing8 = callable.call.call.call();
+
+  var nothing9  = callableGetter();
+  var nothing10 = callableGetter.call();
+  var nothing11 = callableGetter.call.call();
+  var nothing12 = callableGetter.call.call.call();
+}
diff --git a/pkg/kernel/testcases/input/closure.dart b/pkg/kernel/testcases/input/closure.dart
new file mode 100644
index 0000000..dbabb52
--- /dev/null
+++ b/pkg/kernel/testcases/input/closure.dart
@@ -0,0 +1,19 @@
+class Foo {
+  var _field = new Bar();
+}
+
+class Bar {}
+
+useCallback(callback) {
+  var _ = callback();
+}
+
+main() {
+  var x;
+  inner() {
+    x = new Foo();
+    return new Foo();
+  }
+  useCallback(inner);
+  var _ = inner()._field;
+}
diff --git a/pkg/kernel/testcases/input/escape.dart b/pkg/kernel/testcases/input/escape.dart
new file mode 100644
index 0000000..7dbc54e
--- /dev/null
+++ b/pkg/kernel/testcases/input/escape.dart
@@ -0,0 +1,42 @@
+class A {
+  var field;
+}
+class B {
+  var field;
+}
+class C {
+  operator==(x) => false;
+}
+
+class X implements A, B {
+  var field;
+}
+
+void useAsA(A object) {
+  var _ = object.field;
+}
+
+void useAsB(B object) {
+  var _ = object.field;
+  escape(object);
+}
+
+void escape(x) {
+  x ??= "";
+  x ??= 45;
+  if (x is! int && x is! String) {
+    x.field = 45;
+  }
+}
+
+main() {
+  // escape("");
+  // escape(45);
+
+  var object = new X();
+  useAsA(new A());
+  useAsA(object);
+
+  useAsB(new B());
+  useAsB(object);
+}
diff --git a/pkg/kernel/testcases/input/external.dart b/pkg/kernel/testcases/input/external.dart
new file mode 100644
index 0000000..54ce8a7
--- /dev/null
+++ b/pkg/kernel/testcases/input/external.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:isolate';
+
+var subscription;
+
+void onData(x) {
+  print(x);
+  subscription.cancel();
+}
+
+main() {
+  var string = new String.fromCharCode(65); // External string factory.
+  var port = new ReceivePort(); // External factory.
+  subscription = port.listen(onData); // Dynamic call on external instance.
+  port.sendPort.send(string);
+}
diff --git a/pkg/kernel/testcases/input/fallthrough.dart b/pkg/kernel/testcases/input/fallthrough.dart
new file mode 100644
index 0000000..7aab1e3
--- /dev/null
+++ b/pkg/kernel/testcases/input/fallthrough.dart
@@ -0,0 +1,17 @@
+void main(List<String> args) {
+  var x = args.length;
+  switch (x) {
+    case 3:
+      x = 4;
+    case 5:
+      break;
+    case 6:
+    case 7:
+      if (args[0] == '') {
+        break;
+      } else {
+        return;
+      }
+    case 4:
+  }
+}
diff --git a/pkg/kernel/testcases/input/micro.dart b/pkg/kernel/testcases/input/micro.dart
new file mode 100644
index 0000000..51ae34b
--- /dev/null
+++ b/pkg/kernel/testcases/input/micro.dart
@@ -0,0 +1,75 @@
+staticMethod() {
+  return "sdfg";
+}
+
+class Foo {
+  instanceMethod() {
+    return 123;
+  }
+}
+
+external bool externalStatic();
+
+abstract class ExternalValue {}
+
+abstract class Bar {
+  ExternalValue externalInstanceMethod();
+}
+
+external Bar createBar();
+
+class Box {
+  var field;
+}
+
+stringArgument(x) {
+}
+
+intArgument(x) {
+}
+
+class FinalBox {
+  final finalField;
+  FinalBox(this.finalField);
+}
+
+class SubFinalBox extends FinalBox {
+  SubFinalBox(value) : super(value);
+}
+
+class DynamicReceiver1 {
+  dynamicallyCalled(x) {}
+}
+class DynamicReceiver2 {
+  dynamicallyCalled(x) {}
+}
+
+void makeDynamicCall(receiver) {
+  receiver.dynamicallyCalled("sdfg");
+}
+
+main() {
+  var x = staticMethod();
+  var y = new Foo().instanceMethod();
+  var z = externalStatic();
+  var w = createBar().externalInstanceMethod();
+
+  stringArgument("sdfg");
+  intArgument(42);
+
+  var box = new Box();
+  box.field = "sdfg";
+  var a = box.field;
+
+  var finalBox = new FinalBox("dfg");
+  var b = finalBox.finalField;
+
+  var subBox = new SubFinalBox("dfg");
+  var c = subBox.finalField;
+
+  makeDynamicCall(new DynamicReceiver1());
+  makeDynamicCall(new DynamicReceiver2());
+
+  var list = ["string"];
+  var d = list[0];
+}
diff --git a/pkg/kernel/testcases/input/named_parameters.dart b/pkg/kernel/testcases/input/named_parameters.dart
new file mode 100644
index 0000000..edf1f1d
--- /dev/null
+++ b/pkg/kernel/testcases/input/named_parameters.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 Superclass {
+  foo({alpha, beta}) {}
+  bar({beta, alpha}) {}
+
+  namedCallback(callback({String alpha, int beta})) {
+    callback(alpha: 'one', beta: 2);
+    callback(beta: 1, alpha: 'two');
+  }
+}
+
+class Subclass extends Superclass {
+  foo({beta, alpha}) {}
+  bar({alpha, beta}) {}
+
+  namedCallback(callback({int beta, String alpha})) {}
+}
+
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
+
+main() {
+  new Subclass().foo(beta: 1, alpha: 2);
+  new Subclass().foo(alpha: 1, beta: 2);
+  topLevelNamed(1, 2, gamma: 3, delta: 4);
+  topLevelNamed(1, 2, delta: 3, gamma: 4);
+}
diff --git a/pkg/kernel/testcases/input/null_aware.dart b/pkg/kernel/testcases/input/null_aware.dart
new file mode 100644
index 0000000..bb1e3e0
--- /dev/null
+++ b/pkg/kernel/testcases/input/null_aware.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+class Foo {
+  int field;
+  static int staticField;
+}
+
+main() {
+  Foo foo = new Foo();
+  foo?.field = 5;
+  Foo?.staticField = 5;
+  foo.field ??= 5;
+  Foo.staticField ??= 5;
+  foo?.field ??= 5;
+  Foo?.staticField ??= 5;
+
+  int intValue = foo.field ?? 6;
+  num numValue = foo.field ?? 4.5;
+}
diff --git a/pkg/kernel/testcases/input/optional.dart b/pkg/kernel/testcases/input/optional.dart
new file mode 100644
index 0000000..cabd741
--- /dev/null
+++ b/pkg/kernel/testcases/input/optional.dart
@@ -0,0 +1,48 @@
+class Foo {
+  method(x, [y, z]) {
+    return "string";
+  }
+}
+
+abstract class External {
+  String externalMethod(int x, [int y, int z]);
+  void listen(Listener listener);
+}
+external External createExternal();
+
+abstract class Listener {
+  void event(String input, [int x, int y]);
+}
+
+class TestListener extends Listener {
+  void event(input, [x, y]) {}
+}
+
+class ExtendedListener extends Listener {
+  void event(input, [x, y, z]) {}
+}
+
+class InvalidListener {
+  void event(input, [x]) {}
+}
+
+main() {
+  var foo = new Foo();
+  var string1 = foo.method(1);
+  var string2 = foo.method(1, 2);
+  var string3 = foo.method(1, 2, 3);
+
+  var extern = createExternal();
+  var string4 = extern.externalMethod(1);
+  var string5 = extern.externalMethod(1, 2);
+  var string6 = extern.externalMethod(1, 2, 3);
+
+  extern.listen(new TestListener());
+  extern.listen(new ExtendedListener());
+  extern.listen(new InvalidListener());
+
+  var nothing1 = foo.method();
+  var nothing2 = foo.method(1, 2, 3, 4);
+  var nothing3 = extern.externalMethod();
+  var nothing4 = extern.externalMethod(1, 2, 3, 4);
+}
diff --git a/pkg/kernel/testcases/input/override.dart b/pkg/kernel/testcases/input/override.dart
new file mode 100644
index 0000000..89e2b31
--- /dev/null
+++ b/pkg/kernel/testcases/input/override.dart
@@ -0,0 +1,20 @@
+class Foo {}
+class Bar extends Foo {}
+
+class Base {
+  Foo method() {
+    return new Foo();
+  }
+}
+
+class Sub extends Base {
+  Foo method() {
+    return new Bar();
+  }
+}
+
+main(List<String> args) {
+  var object = args.length == 0 ? new Base() : new Sub();
+  var a = object.method();
+  print(a);
+}
diff --git a/pkg/kernel/testcases/input/prefer_baseclass.dart b/pkg/kernel/testcases/input/prefer_baseclass.dart
new file mode 100644
index 0000000..67b93b6
--- /dev/null
+++ b/pkg/kernel/testcases/input/prefer_baseclass.dart
@@ -0,0 +1,26 @@
+class A {}
+class B {}
+
+class AB1 extends A implements B {}
+class AB2 extends A implements B {}
+
+class BA1 extends B implements A {}
+class BA2 extends B implements A {}
+
+takeSubclassOfA(obj) {
+  // The analysis should at least infer that 'obj' is a subclass of A,
+  // When the upper bound is ambiguous, it should use the common superclass, if
+  // there is one besides Object.
+}
+
+takeSubclassOfB(obj) {
+  // Likewise, the analysis should infer that 'obj' is a subclass of B.
+}
+
+main() {
+  takeSubclassOfA(new AB1());
+  takeSubclassOfA(new AB2());
+
+  takeSubclassOfB(new BA1());
+  takeSubclassOfB(new BA2());
+}
diff --git a/pkg/kernel/testcases/input/redirecting_factory.dart b/pkg/kernel/testcases/input/redirecting_factory.dart
new file mode 100644
index 0000000..cf7e91e
--- /dev/null
+++ b/pkg/kernel/testcases/input/redirecting_factory.dart
@@ -0,0 +1,47 @@
+abstract class FooBase<Tf> {
+	int get x;
+	factory FooBase(int x) = Foo<Tf>;
+}
+
+abstract class Foo<T> implements FooBase {
+	factory Foo(int x) = Bar<String,T>;
+}
+
+class Bar<Sb,Tb> implements Foo<Tb> {
+	int x;
+	Bar(this.x) {
+		print('Bar<$Sb,$Tb>');
+	}
+}
+
+class Builder<X> {
+	method() {
+		return new FooBase<X>(4);
+	}
+}
+
+class SimpleCase<A,B> {
+	factory SimpleCase() = SimpleCaseImpl<A,B>;
+}
+
+class SimpleCaseImpl<Ai,Bi> implements SimpleCase<Ai,Bi> {
+	factory SimpleCaseImpl() = SimpleCaseImpl2<Ai,Bi>;
+}
+
+class SimpleCaseImpl2<Ai2,Bi2> implements SimpleCaseImpl<Ai2,Bi2> {
+}
+
+class Base<M> {
+
+}
+class Mixin<M> {
+
+}
+
+class Mix<M> = Base<M> with Mixin<M>;
+
+main() {
+	print(new FooBase<double>(4).x);
+	new SimpleCase<int,double>();
+	new Mix<double>();
+}
diff --git a/pkg/kernel/testcases/input/static_setter.dart b/pkg/kernel/testcases/input/static_setter.dart
new file mode 100644
index 0000000..55e6b0a
--- /dev/null
+++ b/pkg/kernel/testcases/input/static_setter.dart
@@ -0,0 +1,9 @@
+class Foo {}
+
+set foo(x) {
+
+}
+
+main() {
+  foo = new Foo();
+}
diff --git a/pkg/kernel/testcases/input/store_load.dart b/pkg/kernel/testcases/input/store_load.dart
new file mode 100644
index 0000000..79243bf
--- /dev/null
+++ b/pkg/kernel/testcases/input/store_load.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+class Foo {
+  var _field;
+}
+class FooValue {}
+
+class Bar {
+  var _field; // Same name.
+}
+class BarValue {}
+
+main() {
+  var foo = new Foo();
+  foo._field = new FooValue();
+  var fooValue = foo._field;
+  print(fooValue);
+
+  var bar = new Bar();
+  bar._field = new BarValue();
+  var barValue = bar._field;
+  print(barValue);
+}
diff --git a/pkg/kernel/testcases/input/stringliteral.dart b/pkg/kernel/testcases/input/stringliteral.dart
new file mode 100644
index 0000000..8e64de2
--- /dev/null
+++ b/pkg/kernel/testcases/input/stringliteral.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+var color = 'brown';
+var thing = 'lazy dog';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var adjacent = '$color$color$color';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+
+main() {}
diff --git a/pkg/kernel/testcases/input/uninitialized_fields.dart b/pkg/kernel/testcases/input/uninitialized_fields.dart
new file mode 100644
index 0000000..5ff04ff
--- /dev/null
+++ b/pkg/kernel/testcases/input/uninitialized_fields.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 Uninitialized {
+  int x;
+}
+class PartiallyInitialized {
+  int x;
+  PartiallyInitialized(this.x);
+  PartiallyInitialized.noInitializer();
+}
+class Initialized {
+  int x;
+  Initialized(this.x);
+}
+class Forwarding {
+  int x;
+  Forwarding.initialize(this.x);
+  Forwarding(int arg) : this.initialize(arg);
+}
+
+int uninitializedTopLevel;
+int initializedTopLevel = 4;
+
+main() {
+
+}
diff --git a/pkg/kernel/testcases/input/void-methods.dart b/pkg/kernel/testcases/input/void-methods.dart
new file mode 100644
index 0000000..36f4e72
--- /dev/null
+++ b/pkg/kernel/testcases/input/void-methods.dart
@@ -0,0 +1,12 @@
+class Foo {
+  List list = [1,2,3];
+  set first(x) => list[0] = x;
+  operator[]=(x,y) => list[x] = y;
+  void clear() => list.clear();
+}
+
+main() {
+  new Foo().first = 4;
+  new Foo()[3] = 4;
+  new Foo().clear();
+}
diff --git a/pkg/kernel/testcases/spec-mode/DeltaBlue.baseline.txt b/pkg/kernel/testcases/spec-mode/DeltaBlue.baseline.txt
new file mode 100644
index 0000000..edb8f83
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/DeltaBlue.baseline.txt
@@ -0,0 +1,450 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class DeltaBlue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method run() → void {
+    self::chainTest(100);
+    self::projectionTest(100);
+  }
+}
+class Strength extends core::Object {
+  final field core::int value;
+  final field core::String name;
+  const constructor •(core::int value, core::String name) → void
+    : self::Strength::value = value, self::Strength::name = name, super core::Object::•()
+    ;
+  method nextWeaker() → self::Strength
+    return const <self::Strength>[self::STRONG_PREFERRED, self::PREFERRED, self::STRONG_DEFAULT, self::NORMAL, self::WEAK_DEFAULT, self::WEAKEST].[](this.value);
+  static method stronger(self::Strength s1, self::Strength s2) → core::bool {
+    return s1.value.<(s2.value);
+  }
+  static method weaker(self::Strength s1, self::Strength s2) → core::bool {
+    return s1.value.>(s2.value);
+  }
+  static method weakest(self::Strength s1, self::Strength s2) → self::Strength {
+    return self::Strength::weaker(s1, s2) ? s1 : s2;
+  }
+  static method strongest(self::Strength s1, self::Strength s2) → self::Strength {
+    return self::Strength::stronger(s1, s2) ? s1 : s2;
+  }
+}
+abstract class Constraint extends core::Object {
+  final field self::Strength strength;
+  const constructor •(self::Strength strength) → void
+    : self::Constraint::strength = strength, super core::Object::•()
+    ;
+  abstract method isSatisfied() → core::bool;
+  abstract method markUnsatisfied() → void;
+  abstract method addToGraph() → void;
+  abstract method removeFromGraph() → void;
+  abstract method chooseMethod(core::int mark) → void;
+  abstract method markInputs(core::int mark) → void;
+  abstract method inputsKnown(core::int mark) → core::bool;
+  abstract method output() → self::Variable;
+  abstract method execute() → void;
+  abstract method recalculate() → void;
+  method addConstraint() → void {
+    this.addToGraph();
+    self::planner.incrementalAdd(this);
+  }
+  method satisfy(dynamic mark) → self::Constraint {
+    this.chooseMethod(mark);
+    if(!this.isSatisfied()) {
+      if(this.strength.==(self::REQUIRED)) {
+        core::print("Could not satisfy a required constraint!");
+      }
+      return null;
+    }
+    this.markInputs(mark);
+    self::Variable out = this.output();
+    self::Constraint overridden = out.determinedBy;
+    if(!overridden.==(null))
+      overridden.markUnsatisfied();
+    out.determinedBy = this;
+    if(!self::planner.addPropagate(this, mark))
+      core::print("Cycle encountered");
+    out.mark = mark;
+    return overridden;
+  }
+  method destroyConstraint() → void {
+    if(this.isSatisfied())
+      self::planner.incrementalRemove(this);
+    this.removeFromGraph();
+  }
+  method isInput() → core::bool
+    return false;
+}
+abstract class UnaryConstraint extends self::Constraint {
+  final field self::Variable myOutput;
+  field core::bool satisfied = false;
+  constructor •(self::Variable myOutput, self::Strength strength) → void
+    : self::UnaryConstraint::myOutput = myOutput, super self::Constraint::•(strength) {
+    this.addConstraint();
+  }
+  method addToGraph() → void {
+    this.myOutput.addConstraint(this);
+    this.satisfied = false;
+  }
+  method chooseMethod(core::int mark) → void {
+    this.satisfied = !this.myOutput.mark.==(mark) && self::Strength::stronger(this.strength, this.myOutput.walkStrength);
+  }
+  method isSatisfied() → core::bool
+    return this.satisfied;
+  method markInputs(core::int mark) → void {}
+  method output() → self::Variable
+    return this.myOutput;
+  method recalculate() → void {
+    this.myOutput.walkStrength = this.strength;
+    this.myOutput.stay = !this.isInput();
+    if(this.myOutput.stay)
+      this.execute();
+  }
+  method markUnsatisfied() → void {
+    this.satisfied = false;
+  }
+  method inputsKnown(core::int mark) → core::bool
+    return true;
+  method removeFromGraph() → void {
+    if(!this.myOutput.==(null))
+      this.myOutput.removeConstraint(this);
+    this.satisfied = false;
+  }
+}
+class StayConstraint extends self::UnaryConstraint {
+  constructor •(self::Variable v, self::Strength str) → void
+    : super self::UnaryConstraint::•(v, str)
+    ;
+  method execute() → void {}
+}
+class EditConstraint extends self::UnaryConstraint {
+  constructor •(self::Variable v, self::Strength str) → void
+    : super self::UnaryConstraint::•(v, str)
+    ;
+  method isInput() → core::bool
+    return true;
+  method execute() → void {}
+}
+abstract class BinaryConstraint extends self::Constraint {
+  field self::Variable v1;
+  field self::Variable v2;
+  field core::int direction = self::NONE;
+  constructor •(self::Variable v1, self::Variable v2, self::Strength strength) → void
+    : self::BinaryConstraint::v1 = v1, self::BinaryConstraint::v2 = v2, super self::Constraint::•(strength) {
+    this.addConstraint();
+  }
+  method chooseMethod(core::int mark) → void {
+    if(this.v1.mark.==(mark)) {
+      this.direction = !this.v2.mark.==(mark) && self::Strength::stronger(this.strength, this.v2.walkStrength) ? self::FORWARD : self::NONE;
+    }
+    if(this.v2.mark.==(mark)) {
+      this.direction = !this.v1.mark.==(mark) && self::Strength::stronger(this.strength, this.v1.walkStrength) ? self::BACKWARD : self::NONE;
+    }
+    if(self::Strength::weaker(this.v1.walkStrength, this.v2.walkStrength)) {
+      this.direction = self::Strength::stronger(this.strength, this.v1.walkStrength) ? self::BACKWARD : self::NONE;
+    }
+    else {
+      this.direction = self::Strength::stronger(this.strength, this.v2.walkStrength) ? self::FORWARD : self::BACKWARD;
+    }
+  }
+  method addToGraph() → void {
+    this.v1.addConstraint(this);
+    this.v2.addConstraint(this);
+    this.direction = self::NONE;
+  }
+  method isSatisfied() → core::bool
+    return !this.direction.==(self::NONE);
+  method markInputs(core::int mark) → void {
+    this.input().mark = mark;
+  }
+  method input() → self::Variable
+    return this.direction.==(self::FORWARD) ? this.v1 : this.v2;
+  method output() → self::Variable
+    return this.direction.==(self::FORWARD) ? this.v2 : this.v1;
+  method recalculate() → void {
+    self::Variable ihn = this.input();
+    self::Variable out = this.output();
+    out.walkStrength = self::Strength::weakest(this.strength, ihn.walkStrength);
+    out.stay = ihn.stay;
+    if(out.stay)
+      this.execute();
+  }
+  method markUnsatisfied() → void {
+    this.direction = self::NONE;
+  }
+  method inputsKnown(core::int mark) → core::bool {
+    self::Variable i = this.input();
+    return i.mark.==(mark) || i.stay || i.determinedBy.==(null);
+  }
+  method removeFromGraph() → void {
+    if(!this.v1.==(null))
+      this.v1.removeConstraint(this);
+    if(!this.v2.==(null))
+      this.v2.removeConstraint(this);
+    this.direction = self::NONE;
+  }
+}
+class ScaleConstraint extends self::BinaryConstraint {
+  final field self::Variable scale;
+  final field self::Variable offset;
+  constructor •(self::Variable src, self::Variable scale, self::Variable offset, self::Variable dest, self::Strength strength) → void
+    : self::ScaleConstraint::scale = scale, self::ScaleConstraint::offset = offset, super self::BinaryConstraint::•(src, dest, strength)
+    ;
+  method addToGraph() → void {
+    this.{=self::BinaryConstraint::addToGraph}();
+    this.scale.addConstraint(this);
+    this.offset.addConstraint(this);
+  }
+  method removeFromGraph() → void {
+    this.{=self::BinaryConstraint::removeFromGraph}();
+    if(!this.scale.==(null))
+      this.scale.removeConstraint(this);
+    if(!this.offset.==(null))
+      this.offset.removeConstraint(this);
+  }
+  method markInputs(core::int mark) → void {
+    this.{=self::BinaryConstraint::markInputs}(mark);
+    this.scale.mark = this.offset.mark = mark;
+  }
+  method execute() → void {
+    if(this.direction.==(self::FORWARD)) {
+      this.v2.value = this.v1.value.*(this.scale.value).+(this.offset.value);
+    }
+    else {
+      this.v1.value = this.v2.value.-(this.offset.value).~/(this.scale.value);
+    }
+  }
+  method recalculate() → void {
+    self::Variable ihn = this.input();
+    self::Variable out = this.output();
+    out.walkStrength = self::Strength::weakest(this.strength, ihn.walkStrength);
+    out.stay = ihn.stay && this.scale.stay && this.offset.stay;
+    if(out.stay)
+      this.execute();
+  }
+}
+class EqualityConstraint extends self::BinaryConstraint {
+  constructor •(self::Variable v1, self::Variable v2, self::Strength strength) → void
+    : super self::BinaryConstraint::•(v1, v2, strength)
+    ;
+  method execute() → void {
+    this.output().value = this.input().value;
+  }
+}
+class Variable extends core::Object {
+  field core::List<self::Constraint> constraints = <self::Constraint>[];
+  field self::Constraint determinedBy = null;
+  field core::int mark = 0;
+  field self::Strength walkStrength = self::WEAKEST;
+  field core::bool stay = true;
+  field core::int value;
+  final field core::String name;
+  constructor •(core::String name, core::int value) → void
+    : self::Variable::name = name, self::Variable::value = value, super core::Object::•()
+    ;
+  method addConstraint(self::Constraint c) → void {
+    this.constraints.add(c);
+  }
+  method removeConstraint(self::Constraint c) → void {
+    this.constraints.remove(c);
+    if(this.determinedBy.==(c))
+      this.determinedBy = null;
+  }
+}
+class Planner extends core::Object {
+  field core::int currentMark = 0;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method incrementalAdd(self::Constraint c) → void {
+    core::int mark = this.newMark();
+    for (self::Constraint overridden = c.satisfy(mark); !overridden.==(null); overridden = overridden.satisfy(mark))
+      ;
+  }
+  method incrementalRemove(self::Constraint c) → void {
+    self::Variable out = c.output();
+    c.markUnsatisfied();
+    c.removeFromGraph();
+    core::List<self::Constraint> unsatisfied = this.removePropagateFrom(out);
+    self::Strength strength = self::REQUIRED;
+    do {
+      for (core::int i = 0; i.<(unsatisfied.length); i = i.+(1)) {
+        self::Constraint u = unsatisfied.[](i);
+        if(u.strength.==(strength))
+          this.incrementalAdd(u);
+      }
+      strength = strength.nextWeaker();
+    }
+    while (!strength.==(self::WEAKEST))
+  }
+  method newMark() → core::int
+    return this.currentMark = this.currentMark.+(1);
+  method makePlan(core::List<self::Constraint> sources) → self::Plan {
+    core::int mark = this.newMark();
+    self::Plan plan = new self::Plan::•();
+    core::List<self::Constraint> todo = sources;
+    while (todo.length.>(0)) {
+      self::Constraint c = todo.removeLast();
+      if(!c.output().mark.==(mark) && c.inputsKnown(mark)) {
+        plan.addConstraint(c);
+        c.output().mark = mark;
+        this.addConstraintsConsumingTo(c.output(), todo);
+      }
+    }
+    return plan;
+  }
+  method extractPlanFromConstraints(core::List<self::Constraint> constraints) → self::Plan {
+    core::List<self::Constraint> sources = <self::Constraint>[];
+    for (core::int i = 0; i.<(constraints.length); i = i.+(1)) {
+      self::Constraint c = constraints.[](i);
+      if(c.isInput() && c.isSatisfied())
+        sources.add(c);
+    }
+    return this.makePlan(sources);
+  }
+  method addPropagate(self::Constraint c, core::int mark) → core::bool {
+    core::List<self::Constraint> todo = <self::Constraint>[c];
+    while (todo.length.>(0)) {
+      self::Constraint d = todo.removeLast();
+      if(d.output().mark.==(mark)) {
+        this.incrementalRemove(c);
+        return false;
+      }
+      d.recalculate();
+      this.addConstraintsConsumingTo(d.output(), todo);
+    }
+    return true;
+  }
+  method removePropagateFrom(self::Variable out) → core::List<self::Constraint> {
+    out.determinedBy = null;
+    out.walkStrength = self::WEAKEST;
+    out.stay = true;
+    core::List<self::Constraint> unsatisfied = <self::Constraint>[];
+    core::List<self::Variable> todo = <self::Variable>[out];
+    while (todo.length.>(0)) {
+      self::Variable v = todo.removeLast();
+      for (core::int i = 0; i.<(v.constraints.length); i = i.+(1)) {
+        self::Constraint c = v.constraints.[](i);
+        if(!c.isSatisfied())
+          unsatisfied.add(c);
+      }
+      self::Constraint determining = v.determinedBy;
+      for (core::int i = 0; i.<(v.constraints.length); i = i.+(1)) {
+        self::Constraint next = v.constraints.[](i);
+        if(!next.==(determining) && next.isSatisfied()) {
+          next.recalculate();
+          todo.add(next.output());
+        }
+      }
+    }
+    return unsatisfied;
+  }
+  method addConstraintsConsumingTo(self::Variable v, core::List<self::Constraint> coll) → void {
+    self::Constraint determining = v.determinedBy;
+    for (core::int i = 0; i.<(v.constraints.length); i = i.+(1)) {
+      self::Constraint c = v.constraints.[](i);
+      if(!c.==(determining) && c.isSatisfied())
+        coll.add(c);
+    }
+  }
+}
+class Plan extends core::Object {
+  field core::List<self::Constraint> list = <self::Constraint>[];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method addConstraint(self::Constraint c) → void {
+    this.list.add(c);
+  }
+  method size() → core::int
+    return this.list.length;
+  method execute() → void {
+    for (core::int i = 0; i.<(this.list.length); i = i.+(1)) {
+      this.list.[](i).execute();
+    }
+  }
+}
+static const field dynamic REQUIRED = const self::Strength::•(0, "required");
+static const field dynamic STRONG_PREFERRED = const self::Strength::•(1, "strongPreferred");
+static const field dynamic PREFERRED = const self::Strength::•(2, "preferred");
+static const field dynamic STRONG_DEFAULT = const self::Strength::•(3, "strongDefault");
+static const field dynamic NORMAL = const self::Strength::•(4, "normal");
+static const field dynamic WEAK_DEFAULT = const self::Strength::•(5, "weakDefault");
+static const field dynamic WEAKEST = const self::Strength::•(6, "weakest");
+static const field core::int NONE = 1;
+static const field core::int FORWARD = 2;
+static const field core::int BACKWARD = 0;
+static field self::Planner planner = null;
+static method main() → dynamic {
+  new self::DeltaBlue::•().run();
+}
+static method chainTest(core::int n) → void {
+  self::planner = new self::Planner::•();
+  self::Variable prev = null;
+  self::Variable first = null;
+  self::Variable last = null;
+  for (core::int i = 0; i.<=(n); i = i.+(1)) {
+    self::Variable v = new self::Variable::•("v${i}", 0);
+    if(!prev.==(null))
+      new self::EqualityConstraint::•(prev, v, self::REQUIRED);
+    if(i.==(0))
+      first = v;
+    if(i.==(n))
+      last = v;
+    prev = v;
+  }
+  new self::StayConstraint::•(last, self::STRONG_DEFAULT);
+  self::EditConstraint edit = new self::EditConstraint::•(first, self::PREFERRED);
+  self::Plan plan = self::planner.extractPlanFromConstraints(<self::Constraint>[edit]);
+  for (core::int i = 0; i.<(100); i = i.+(1)) {
+    first.value = i;
+    plan.execute();
+    if(!last.value.==(i)) {
+      core::print("Chain test failed:");
+      core::print("Expected last value to be ${i} but it was ${last.value}.");
+    }
+  }
+}
+static method projectionTest(core::int n) → void {
+  self::planner = new self::Planner::•();
+  self::Variable scale = new self::Variable::•("scale", 10);
+  self::Variable offset = new self::Variable::•("offset", 1000);
+  self::Variable src = null;
+  self::Variable dst = null;
+  core::List<self::Variable> dests = <self::Variable>[];
+  for (core::int i = 0; i.<(n); i = i.+(1)) {
+    src = new self::Variable::•("src", i);
+    dst = new self::Variable::•("dst", i);
+    dests.add(dst);
+    new self::StayConstraint::•(src, self::NORMAL);
+    new self::ScaleConstraint::•(src, scale, offset, dst, self::REQUIRED);
+  }
+  self::change(src, 17);
+  if(!dst.value.==(1170))
+    core::print("Projection 1 failed");
+  self::change(dst, 1050);
+  if(!src.value.==(5))
+    core::print("Projection 2 failed");
+  self::change(scale, 5);
+  for (core::int i = 0; i.<(n.-(1)); i = i.+(1)) {
+    if(!dests.[](i).value.==(i.*(5).+(1000)))
+      core::print("Projection 3 failed");
+  }
+  self::change(offset, 2000);
+  for (core::int i = 0; i.<(n.-(1)); i = i.+(1)) {
+    if(!dests.[](i).value.==(i.*(5).+(2000)))
+      core::print("Projection 4 failed");
+  }
+}
+static method change(self::Variable v, core::int newValue) → void {
+  self::EditConstraint edit = new self::EditConstraint::•(v, self::PREFERRED);
+  self::Plan plan = self::planner.extractPlanFromConstraints(<self::EditConstraint>[edit]);
+  for (core::int i = 0; i.<(10); i = i.+(1)) {
+    v.value = newValue;
+    plan.execute();
+  }
+  edit.destroyConstraint();
+}
diff --git a/pkg/kernel/testcases/spec-mode/argument.baseline.txt b/pkg/kernel/testcases/spec-mode/argument.baseline.txt
new file mode 100644
index 0000000..27c776c
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/argument.baseline.txt
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class Base extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Bar extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Baz extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method foo(dynamic x) → void {}
+static method bar(dynamic x) → void {}
+static method foo_escaped(dynamic x) → void {}
+static method bar_escaped(dynamic x) → void {}
+static method escape(dynamic fn) → void {
+  fn.call(new self::Baz::•());
+}
+static method main() → dynamic {
+  self::foo(new self::Foo::•());
+  self::bar(new self::Bar::•());
+  self::escape(self::foo_escaped);
+  self::escape(self::bar_escaped);
+}
diff --git a/pkg/kernel/testcases/spec-mode/arithmetic.baseline.txt b/pkg/kernel/testcases/spec-mode/arithmetic.baseline.txt
new file mode 100644
index 0000000..7c867f3
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/arithmetic.baseline.txt
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo(core::int x, core::int y) → core::int {
+  dynamic z = x.+(y);
+  return z.<<(4);
+}
+static method loop(core::List<dynamic> xs) → void {
+  core::int _ = xs.length;
+  for (core::int i = 0; i.<(xs.length); i = i.+(1)) {
+  }
+}
+static method main() → dynamic {
+  self::foo(4, 5);
+  self::foo(6, 7);
+  self::loop(<dynamic>["dfg"]);
+}
diff --git a/pkg/kernel/testcases/spec-mode/async_function.baseline.txt b/pkg/kernel/testcases/spec-mode/async_function.baseline.txt
new file mode 100644
index 0000000..6a9bffa
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/async_function.baseline.txt
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field core::List<core::String> stringList = <dynamic>["bar"];
+static method asyncString() → asy::Future<core::String> async {
+  return "foo";
+}
+static method asyncString2() → asy::Future<core::String> async {
+  return self::asyncString();
+}
+static method syncStarString() → core::Iterable<core::String> sync* {
+  yield "foo";
+  yield* self::syncStarString2();
+  yield* self::stringList;
+}
+static method syncStarString2() → core::Iterable<core::String> sync* {
+  yield "foo";
+}
+static method asyncStarString() → asy::Stream<core::String> async* {
+  yield "foo";
+  yield* self::asyncStarString2();
+  yield await self::asyncString();
+}
+static method asyncStarString2() → asy::Stream<core::String> async* {
+  yield "bar";
+}
+static method main() → dynamic async {
+  core::String str = await self::asyncString();
+}
diff --git a/pkg/kernel/testcases/spec-mode/bad_store.baseline.txt b/pkg/kernel/testcases/spec-mode/bad_store.baseline.txt
new file mode 100644
index 0000000..06f7dd5
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/bad_store.baseline.txt
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method identity(dynamic x) → dynamic
+  return x;
+static method use(dynamic x) → void {}
+static method main(core::List<core::String> args) → dynamic {
+  dynamic foo = self::identity(new self::Foo::•());
+  if(args.length.>(1)) {
+    foo.field = "string";
+    dynamic first = foo.field;
+    self::use(first);
+    foo.noField = "string";
+    dynamic second = foo.noField;
+    self::use(second);
+  }
+}
diff --git a/pkg/kernel/testcases/spec-mode/call.baseline.txt b/pkg/kernel/testcases/spec-mode/call.baseline.txt
new file mode 100644
index 0000000..5ef0d83
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/call.baseline.txt
@@ -0,0 +1,48 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Callable extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(dynamic x) → dynamic {
+    return "string";
+  }
+}
+class CallableGetter extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  get call() → dynamic
+    return new self::Callable::•();
+}
+static method main() → dynamic {
+  dynamic closure = (dynamic x) → dynamic => x;
+  dynamic int1 = closure.call(1);
+  dynamic int2 = closure.call(1);
+  dynamic int3 = closure.call.call(1);
+  dynamic int4 = closure.call.call.call(1);
+  dynamic callable = new self::Callable::•();
+  dynamic string1 = callable.call(1);
+  dynamic string2 = callable.call(1);
+  dynamic string3 = callable.call.call(1);
+  dynamic string4 = callable.call.call.call(1);
+  dynamic callableGetter = new self::CallableGetter::•();
+  dynamic string5 = callableGetter.call(1);
+  dynamic string6 = callableGetter.call(1);
+  dynamic string7 = callableGetter.call.call(1);
+  dynamic string8 = callableGetter.call.call.call(1);
+  dynamic nothing1 = closure.call();
+  dynamic nothing2 = closure.call();
+  dynamic nothing3 = closure.call.call();
+  dynamic nothing4 = closure.call.call.call();
+  dynamic nothing5 = callable.call();
+  dynamic nothing6 = callable.call();
+  dynamic nothing7 = callable.call.call();
+  dynamic nothing8 = callable.call.call.call();
+  dynamic nothing9 = callableGetter.call();
+  dynamic nothing10 = callableGetter.call();
+  dynamic nothing11 = callableGetter.call.call();
+  dynamic nothing12 = callableGetter.call.call.call();
+}
diff --git a/pkg/kernel/testcases/spec-mode/closure.baseline.txt b/pkg/kernel/testcases/spec-mode/closure.baseline.txt
new file mode 100644
index 0000000..364fb6f
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/closure.baseline.txt
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic _field = new self::Bar::•();
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useCallback(dynamic callback) → dynamic {
+  dynamic _ = callback.call();
+}
+static method main() → dynamic {
+  dynamic x;
+  function inner() → dynamic {
+    x = new self::Foo::•();
+    return new self::Foo::•();
+  }
+  self::useCallback(inner);
+  dynamic _ = inner.call()._field;
+}
diff --git a/pkg/kernel/testcases/spec-mode/escape.baseline.txt b/pkg/kernel/testcases/spec-mode/escape.baseline.txt
new file mode 100644
index 0000000..2370690
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/escape.baseline.txt
@@ -0,0 +1,50 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ==(dynamic x) → dynamic
+    return false;
+}
+class X extends core::Object implements self::A, self::B {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useAsA(self::A object) → void {
+  dynamic _ = object.field;
+}
+static method useAsB(self::B object) → void {
+  dynamic _ = object.field;
+  self::escape(object);
+}
+static method escape(dynamic x) → void {
+  x.==(null) ? x = "" : null;
+  x.==(null) ? x = 45 : null;
+  if(!(x is core::int) && !(x is core::String)) {
+    x.field = 45;
+  }
+}
+static method main() → dynamic {
+  dynamic object = new self::X::•();
+  self::useAsA(new self::A::•());
+  self::useAsA(object);
+  self::useAsB(new self::B::•());
+  self::useAsB(object);
+}
diff --git a/pkg/kernel/testcases/spec-mode/external.baseline.txt b/pkg/kernel/testcases/spec-mode/external.baseline.txt
new file mode 100644
index 0000000..74c2005
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/external.baseline.txt
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:isolate" as iso;
+
+static field dynamic subscription = null;
+static method onData(dynamic x) → void {
+  core::print(x);
+  self::subscription.cancel();
+}
+static method main() → dynamic {
+  dynamic string = core::String::fromCharCode(65);
+  dynamic port = iso::ReceivePort::•();
+  self::subscription = port.listen(self::onData);
+  port.sendPort.send(string);
+}
diff --git a/pkg/kernel/testcases/spec-mode/fallthrough.baseline.txt b/pkg/kernel/testcases/spec-mode/fallthrough.baseline.txt
new file mode 100644
index 0000000..d14510f
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/fallthrough.baseline.txt
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main(core::List<core::String> args) → void {
+  dynamic x = args.length;
+  #L1:
+  switch(x) {
+    #L2:
+    case 3:
+      {
+        x = 4;
+        throw new core::FallThroughError::•();
+      }
+    #L3:
+    case 5:
+      {
+        break #L1;
+      }
+    #L4:
+    case 6:
+    case 7:
+      {
+        if(args.[](0).==("")) {
+          break #L1;
+        }
+        else {
+          return;
+        }
+        throw new core::FallThroughError::•();
+      }
+    #L5:
+    case 4:
+      {
+        break #L1;
+      }
+  }
+}
diff --git a/pkg/kernel/testcases/spec-mode/micro.baseline.txt b/pkg/kernel/testcases/spec-mode/micro.baseline.txt
new file mode 100644
index 0000000..585ce19
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/micro.baseline.txt
@@ -0,0 +1,81 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method instanceMethod() → dynamic {
+    return 123;
+  }
+}
+abstract class ExternalValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method externalInstanceMethod() → self::ExternalValue;
+}
+class Box extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FinalBox extends core::Object {
+  final field dynamic finalField;
+  constructor •(dynamic finalField) → void
+    : self::FinalBox::finalField = finalField, super core::Object::•()
+    ;
+}
+class SubFinalBox extends self::FinalBox {
+  constructor •(dynamic value) → void
+    : super self::FinalBox::•(value)
+    ;
+}
+class DynamicReceiver1 extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method dynamicallyCalled(dynamic x) → dynamic {}
+}
+class DynamicReceiver2 extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method dynamicallyCalled(dynamic x) → dynamic {}
+}
+static method staticMethod() → dynamic {
+  return "sdfg";
+}
+external static method externalStatic() → core::bool;
+external static method createBar() → self::Bar;
+static method stringArgument(dynamic x) → dynamic {}
+static method intArgument(dynamic x) → dynamic {}
+static method makeDynamicCall(dynamic receiver) → void {
+  receiver.dynamicallyCalled("sdfg");
+}
+static method main() → dynamic {
+  dynamic x = self::staticMethod();
+  dynamic y = new self::Foo::•().instanceMethod();
+  dynamic z = self::externalStatic();
+  dynamic w = self::createBar().externalInstanceMethod();
+  self::stringArgument("sdfg");
+  self::intArgument(42);
+  dynamic box = new self::Box::•();
+  box.field = "sdfg";
+  dynamic a = box.field;
+  dynamic finalBox = new self::FinalBox::•("dfg");
+  dynamic b = finalBox.finalField;
+  dynamic subBox = new self::SubFinalBox::•("dfg");
+  dynamic c = subBox.finalField;
+  self::makeDynamicCall(new self::DynamicReceiver1::•());
+  self::makeDynamicCall(new self::DynamicReceiver2::•());
+  dynamic list = <dynamic>["string"];
+  dynamic d = list.[](0);
+}
diff --git a/pkg/kernel/testcases/spec-mode/named_parameters.baseline.txt b/pkg/kernel/testcases/spec-mode/named_parameters.baseline.txt
new file mode 100644
index 0000000..0963b64
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/named_parameters.baseline.txt
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo({dynamic alpha, dynamic beta}) → dynamic {}
+  method bar({dynamic beta, dynamic alpha}) → dynamic {}
+  method namedCallback(({alpha: core::String, beta: core::int}) → dynamic callback) → dynamic {
+    callback.call(alpha: "one", beta: 2);
+    callback.call(beta: 1, alpha: "two");
+  }
+}
+class Subclass extends self::Superclass {
+  constructor •() → void
+    : super self::Superclass::•()
+    ;
+  method foo({dynamic beta, dynamic alpha}) → dynamic {}
+  method bar({dynamic alpha, dynamic beta}) → dynamic {}
+  method namedCallback(({alpha: core::String, beta: core::int}) → dynamic callback) → dynamic {}
+}
+static method topLevelNamed(dynamic beta, dynamic alpha, {dynamic gamma, dynamic delta}) → dynamic {}
+static method topLevelOptional(dynamic beta, dynamic alpha, [dynamic gamma, dynamic delta]) → dynamic {}
+static method main() → dynamic {
+  new self::Subclass::•().foo(beta: 1, alpha: 2);
+  new self::Subclass::•().foo(alpha: 1, beta: 2);
+  self::topLevelNamed(1, 2, gamma: 3, delta: 4);
+  self::topLevelNamed(1, 2, delta: 3, gamma: 4);
+}
diff --git a/pkg/kernel/testcases/spec-mode/null_aware.baseline.txt b/pkg/kernel/testcases/spec-mode/null_aware.baseline.txt
new file mode 100644
index 0000000..9a60a62
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/null_aware.baseline.txt
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  static field core::int staticField = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  let final dynamic #t1 = foo in #t1.==(null) ? null : #t1.field = 5;
+  self::Foo::staticField = 5;
+  let final dynamic #t2 = foo in #t2.field.==(null) ? #t2.field = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  let final dynamic #t3 = foo in #t3.==(null) ? null : #t3.field.==(null) ? #t3.field = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  core::int intValue = let final dynamic #t4 = foo.field in #t4.==(null) ? 6 : #t4;
+  core::num numValue = let final dynamic #t5 = foo.field in #t5.==(null) ? 4.5 : #t5;
+}
diff --git a/pkg/kernel/testcases/spec-mode/optional.baseline.txt b/pkg/kernel/testcases/spec-mode/optional.baseline.txt
new file mode 100644
index 0000000..947d12b
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/optional.baseline.txt
@@ -0,0 +1,61 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method(dynamic x, [dynamic y, dynamic z]) → dynamic {
+    return "string";
+  }
+}
+abstract class External extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method externalMethod(core::int x, [core::int y, core::int z]) → core::String;
+  abstract method listen(self::Listener listener) → void;
+}
+abstract class Listener extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method event(core::String input, [core::int x, core::int y]) → void;
+}
+class TestListener extends self::Listener {
+  constructor •() → void
+    : super self::Listener::•()
+    ;
+  method event(dynamic input, [dynamic x, dynamic y]) → void {}
+}
+class ExtendedListener extends self::Listener {
+  constructor •() → void
+    : super self::Listener::•()
+    ;
+  method event(dynamic input, [dynamic x, dynamic y, dynamic z]) → void {}
+}
+class InvalidListener extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method event(dynamic input, [dynamic x]) → void {}
+}
+external static method createExternal() → self::External;
+static method main() → dynamic {
+  dynamic foo = new self::Foo::•();
+  dynamic string1 = foo.method(1);
+  dynamic string2 = foo.method(1, 2);
+  dynamic string3 = foo.method(1, 2, 3);
+  dynamic extern = self::createExternal();
+  dynamic string4 = extern.externalMethod(1);
+  dynamic string5 = extern.externalMethod(1, 2);
+  dynamic string6 = extern.externalMethod(1, 2, 3);
+  extern.listen(new self::TestListener::•());
+  extern.listen(new self::ExtendedListener::•());
+  extern.listen(new self::InvalidListener::•());
+  dynamic nothing1 = foo.method();
+  dynamic nothing2 = foo.method(1, 2, 3, 4);
+  dynamic nothing3 = extern.externalMethod();
+  dynamic nothing4 = extern.externalMethod(1, 2, 3, 4);
+}
diff --git a/pkg/kernel/testcases/spec-mode/override.baseline.txt b/pkg/kernel/testcases/spec-mode/override.baseline.txt
new file mode 100644
index 0000000..c46b187
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/override.baseline.txt
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends self::Foo {
+  constructor •() → void
+    : super self::Foo::•()
+    ;
+}
+class Base extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → self::Foo {
+    return new self::Foo::•();
+  }
+}
+class Sub extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+  method method() → self::Foo {
+    return new self::Bar::•();
+  }
+}
+static method main(core::List<core::String> args) → dynamic {
+  dynamic object = args.length.==(0) ? new self::Base::•() : new self::Sub::•();
+  dynamic a = object.method();
+  core::print(a);
+}
diff --git a/pkg/kernel/testcases/spec-mode/prefer_baseclass.baseline.txt b/pkg/kernel/testcases/spec-mode/prefer_baseclass.baseline.txt
new file mode 100644
index 0000000..8e82d39
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/prefer_baseclass.baseline.txt
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class AB1 extends self::A implements self::B {
+  constructor •() → void
+    : super self::A::•()
+    ;
+}
+class AB2 extends self::A implements self::B {
+  constructor •() → void
+    : super self::A::•()
+    ;
+}
+class BA1 extends self::B implements self::A {
+  constructor •() → void
+    : super self::B::•()
+    ;
+}
+class BA2 extends self::B implements self::A {
+  constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method takeSubclassOfA(dynamic obj) → dynamic {}
+static method takeSubclassOfB(dynamic obj) → dynamic {}
+static method main() → dynamic {
+  self::takeSubclassOfA(new self::AB1::•());
+  self::takeSubclassOfA(new self::AB2::•());
+  self::takeSubclassOfB(new self::BA1::•());
+  self::takeSubclassOfB(new self::BA2::•());
+}
diff --git a/pkg/kernel/testcases/spec-mode/redirecting_factory.baseline.txt b/pkg/kernel/testcases/spec-mode/redirecting_factory.baseline.txt
new file mode 100644
index 0000000..8ad4aa2
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/redirecting_factory.baseline.txt
@@ -0,0 +1,53 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class FooBase<Tf extends core::Object> extends core::Object {
+  abstract get x() → core::int;
+}
+abstract class Foo<T extends core::Object> extends core::Object implements self::FooBase<dynamic> {
+}
+class Bar<Sb extends core::Object, Tb extends core::Object> extends core::Object implements self::Foo<self::Bar::Tb> {
+  field core::int x;
+  constructor •(core::int x) → void
+    : self::Bar::x = x, super core::Object::•() {
+    core::print("Bar<${self::Bar::Sb},${self::Bar::Tb}>");
+  }
+}
+class Builder<X extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    return new self::Bar::•<core::String, self::Builder::X>(4);
+  }
+}
+class SimpleCase<A extends core::Object, B extends core::Object> extends core::Object {
+}
+class SimpleCaseImpl<Ai extends core::Object, Bi extends core::Object> extends core::Object implements self::SimpleCase<self::SimpleCaseImpl::Ai, self::SimpleCaseImpl::Bi> {
+}
+class SimpleCaseImpl2<Ai2 extends core::Object, Bi2 extends core::Object> extends core::Object implements self::SimpleCaseImpl<self::SimpleCaseImpl2::Ai2, self::SimpleCaseImpl2::Bi2> {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Base<M extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mixin<M extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mix<M extends core::Object> extends self::Base<self::Mix::M> implements self::Mixin<self::Mix::M> {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::Bar::•<core::String, core::double>(4).x);
+  new self::SimpleCaseImpl2::•<core::int, core::double>();
+  new self::Mix::•<core::double>();
+}
diff --git a/pkg/kernel/testcases/spec-mode/static_setter.baseline.txt b/pkg/kernel/testcases/spec-mode/static_setter.baseline.txt
new file mode 100644
index 0000000..af6242f
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/static_setter.baseline.txt
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static set foo(dynamic x) → dynamic {}
+static method main() → dynamic {
+  self::foo = new self::Foo::•();
+}
diff --git a/pkg/kernel/testcases/spec-mode/store_load.baseline.txt b/pkg/kernel/testcases/spec-mode/store_load.baseline.txt
new file mode 100644
index 0000000..166eccc
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/store_load.baseline.txt
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic _field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  field dynamic _field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class BarValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic foo = new self::Foo::•();
+  foo._field = new self::FooValue::•();
+  dynamic fooValue = foo._field;
+  core::print(fooValue);
+  dynamic bar = new self::Bar::•();
+  bar._field = new self::BarValue::•();
+  dynamic barValue = bar._field;
+  core::print(barValue);
+}
diff --git a/pkg/kernel/testcases/spec-mode/stringliteral.baseline.txt b/pkg/kernel/testcases/spec-mode/stringliteral.baseline.txt
new file mode 100644
index 0000000..5fce998
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/stringliteral.baseline.txt
@@ -0,0 +1,10 @@
+library;
+import self as self;
+
+static field dynamic color = "brown";
+static field dynamic thing = "lazy dog";
+static field dynamic phrase = "The quick ${self::color} fox\njumped over the ${self::thing}.\n";
+static field dynamic adjacent = "${self::color}${self::color}${self::color}";
+static field dynamic linebreaks = "${self::color}\n${self::color}\n${self::color}";
+static field dynamic other = "${self::color}\n is \n${self::color}";
+static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/spec-mode/uninitialized_fields.baseline.txt b/pkg/kernel/testcases/spec-mode/uninitialized_fields.baseline.txt
new file mode 100644
index 0000000..c4b9044
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/uninitialized_fields.baseline.txt
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Uninitialized extends core::Object {
+  field core::int x = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class PartiallyInitialized extends core::Object {
+  field core::int x = null;
+  constructor •(core::int x) → void
+    : self::PartiallyInitialized::x = x, super core::Object::•()
+    ;
+  constructor noInitializer() → void
+    : super core::Object::•()
+    ;
+}
+class Initialized extends core::Object {
+  field core::int x;
+  constructor •(core::int x) → void
+    : self::Initialized::x = x, super core::Object::•()
+    ;
+}
+class Forwarding extends core::Object {
+  field core::int x;
+  constructor initialize(core::int x) → void
+    : self::Forwarding::x = x, super core::Object::•()
+    ;
+  constructor •(core::int arg) → void
+    : this self::Forwarding::initialize(arg)
+    ;
+}
+static field core::int uninitializedTopLevel = null;
+static field core::int initializedTopLevel = 4;
+static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/spec-mode/void-methods.baseline.txt b/pkg/kernel/testcases/spec-mode/void-methods.baseline.txt
new file mode 100644
index 0000000..e0dc634
--- /dev/null
+++ b/pkg/kernel/testcases/spec-mode/void-methods.baseline.txt
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::List<dynamic> list = <dynamic>[1, 2, 3];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  set first(dynamic x) → dynamic
+    this.list.[]=(0, x);
+  operator []=(dynamic x, dynamic y) → dynamic
+    this.list.[]=(x, y);
+  method clear() → void
+    return this.list.clear();
+}
+static method main() → dynamic {
+  new self::Foo::•().first = 4;
+  new self::Foo::•().[]=(3, 4);
+  new self::Foo::•().clear();
+}
diff --git a/pkg/kernel/testcases/strong-mode/DeltaBlue.baseline.txt b/pkg/kernel/testcases/strong-mode/DeltaBlue.baseline.txt
new file mode 100644
index 0000000..f2735c6
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/DeltaBlue.baseline.txt
@@ -0,0 +1,454 @@
+// dynamic is not a subtype of dart.core::int (DeltaBlue.dart:126:17)
+// dynamic is not a subtype of dart.core::int (DeltaBlue.dart:133:15)
+// dynamic is not a subtype of dart.core::int (DeltaBlue.dart:138:36)
+// dynamic is not a subtype of dart.core::int (DeltaBlue.dart:139:15)
+library;
+import self as self;
+import "dart:core" as core;
+
+class DeltaBlue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method run() → void {
+    self::chainTest(100);
+    self::projectionTest(100);
+  }
+}
+class Strength extends core::Object {
+  final field core::int value;
+  final field core::String name;
+  const constructor •(core::int value, core::String name) → void
+    : self::Strength::value = value, self::Strength::name = name, super core::Object::•()
+    ;
+  method nextWeaker() → self::Strength
+    return const <self::Strength>[self::STRONG_PREFERRED, self::PREFERRED, self::STRONG_DEFAULT, self::NORMAL, self::WEAK_DEFAULT, self::WEAKEST].{core::List::[]}(this.{self::Strength::value});
+  static method stronger(self::Strength s1, self::Strength s2) → core::bool {
+    return s1.{self::Strength::value}.{core::num::<}(s2.{self::Strength::value});
+  }
+  static method weaker(self::Strength s1, self::Strength s2) → core::bool {
+    return s1.{self::Strength::value}.{core::num::>}(s2.{self::Strength::value});
+  }
+  static method weakest(self::Strength s1, self::Strength s2) → self::Strength {
+    return self::Strength::weaker(s1, s2) ? s1 : s2;
+  }
+  static method strongest(self::Strength s1, self::Strength s2) → self::Strength {
+    return self::Strength::stronger(s1, s2) ? s1 : s2;
+  }
+}
+abstract class Constraint extends core::Object {
+  final field self::Strength strength;
+  const constructor •(self::Strength strength) → void
+    : self::Constraint::strength = strength, super core::Object::•()
+    ;
+  abstract method isSatisfied() → core::bool;
+  abstract method markUnsatisfied() → void;
+  abstract method addToGraph() → void;
+  abstract method removeFromGraph() → void;
+  abstract method chooseMethod(core::int mark) → void;
+  abstract method markInputs(core::int mark) → void;
+  abstract method inputsKnown(core::int mark) → core::bool;
+  abstract method output() → self::Variable;
+  abstract method execute() → void;
+  abstract method recalculate() → void;
+  method addConstraint() → void {
+    this.{self::Constraint::addToGraph}();
+    self::planner.{self::Planner::incrementalAdd}(this);
+  }
+  method satisfy(dynamic mark) → self::Constraint {
+    this.{self::Constraint::chooseMethod}(mark);
+    if(!this.{self::Constraint::isSatisfied}()) {
+      if(this.{self::Constraint::strength}.{core::Object::==}(self::REQUIRED)) {
+        core::print("Could not satisfy a required constraint!");
+      }
+      return null;
+    }
+    this.{self::Constraint::markInputs}(mark);
+    self::Variable out = this.{self::Constraint::output}();
+    self::Constraint overridden = out.{self::Variable::determinedBy};
+    if(!overridden.{core::Object::==}(null))
+      overridden.{self::Constraint::markUnsatisfied}();
+    out.{self::Variable::determinedBy} = this;
+    if(!self::planner.{self::Planner::addPropagate}(this, mark))
+      core::print("Cycle encountered");
+    out.{self::Variable::mark} = mark;
+    return overridden;
+  }
+  method destroyConstraint() → void {
+    if(this.{self::Constraint::isSatisfied}())
+      self::planner.{self::Planner::incrementalRemove}(this);
+    this.{self::Constraint::removeFromGraph}();
+  }
+  method isInput() → core::bool
+    return false;
+}
+abstract class UnaryConstraint extends self::Constraint {
+  final field self::Variable myOutput;
+  field core::bool satisfied = false;
+  constructor •(self::Variable myOutput, self::Strength strength) → void
+    : self::UnaryConstraint::myOutput = myOutput, super self::Constraint::•(strength) {
+    this.{self::Constraint::addConstraint}();
+  }
+  method addToGraph() → void {
+    this.{self::UnaryConstraint::myOutput}.{self::Variable::addConstraint}(this);
+    this.{self::UnaryConstraint::satisfied} = false;
+  }
+  method chooseMethod(core::int mark) → void {
+    this.{self::UnaryConstraint::satisfied} = !this.{self::UnaryConstraint::myOutput}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::UnaryConstraint::myOutput}.{self::Variable::walkStrength});
+  }
+  method isSatisfied() → core::bool
+    return this.{self::UnaryConstraint::satisfied};
+  method markInputs(core::int mark) → void {}
+  method output() → self::Variable
+    return this.{self::UnaryConstraint::myOutput};
+  method recalculate() → void {
+    this.{self::UnaryConstraint::myOutput}.{self::Variable::walkStrength} = this.{self::Constraint::strength};
+    this.{self::UnaryConstraint::myOutput}.{self::Variable::stay} = !this.{self::Constraint::isInput}();
+    if(this.{self::UnaryConstraint::myOutput}.{self::Variable::stay})
+      this.{self::Constraint::execute}();
+  }
+  method markUnsatisfied() → void {
+    this.{self::UnaryConstraint::satisfied} = false;
+  }
+  method inputsKnown(core::int mark) → core::bool
+    return true;
+  method removeFromGraph() → void {
+    if(!this.{self::UnaryConstraint::myOutput}.{core::Object::==}(null))
+      this.{self::UnaryConstraint::myOutput}.{self::Variable::removeConstraint}(this);
+    this.{self::UnaryConstraint::satisfied} = false;
+  }
+}
+class StayConstraint extends self::UnaryConstraint {
+  constructor •(self::Variable v, self::Strength str) → void
+    : super self::UnaryConstraint::•(v, str)
+    ;
+  method execute() → void {}
+}
+class EditConstraint extends self::UnaryConstraint {
+  constructor •(self::Variable v, self::Strength str) → void
+    : super self::UnaryConstraint::•(v, str)
+    ;
+  method isInput() → core::bool
+    return true;
+  method execute() → void {}
+}
+abstract class BinaryConstraint extends self::Constraint {
+  field self::Variable v1;
+  field self::Variable v2;
+  field core::int direction = self::NONE;
+  constructor •(self::Variable v1, self::Variable v2, self::Strength strength) → void
+    : self::BinaryConstraint::v1 = v1, self::BinaryConstraint::v2 = v2, super self::Constraint::•(strength) {
+    this.{self::Constraint::addConstraint}();
+  }
+  method chooseMethod(core::int mark) → void {
+    if(this.{self::BinaryConstraint::v1}.{self::Variable::mark}.{core::num::==}(mark)) {
+      this.{self::BinaryConstraint::direction} = !this.{self::BinaryConstraint::v2}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ? self::FORWARD : self::NONE;
+    }
+    if(this.{self::BinaryConstraint::v2}.{self::Variable::mark}.{core::num::==}(mark)) {
+      this.{self::BinaryConstraint::direction} = !this.{self::BinaryConstraint::v1}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}) ? self::BACKWARD : self::NONE;
+    }
+    if(self::Strength::weaker(this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength})) {
+      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}) ? self::BACKWARD : self::NONE;
+    }
+    else {
+      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ? self::FORWARD : self::BACKWARD;
+    }
+  }
+  method addToGraph() → void {
+    this.{self::BinaryConstraint::v1}.{self::Variable::addConstraint}(this);
+    this.{self::BinaryConstraint::v2}.{self::Variable::addConstraint}(this);
+    this.{self::BinaryConstraint::direction} = self::NONE;
+  }
+  method isSatisfied() → core::bool
+    return !this.{self::BinaryConstraint::direction}.{core::num::==}(self::NONE);
+  method markInputs(core::int mark) → void {
+    this.{self::BinaryConstraint::input}().{self::Variable::mark} = mark;
+  }
+  method input() → self::Variable
+    return this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD) ? this.{self::BinaryConstraint::v1} : this.{self::BinaryConstraint::v2};
+  method output() → self::Variable
+    return this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD) ? this.{self::BinaryConstraint::v2} : this.{self::BinaryConstraint::v1};
+  method recalculate() → void {
+    self::Variable ihn = this.{self::BinaryConstraint::input}();
+    self::Variable out = this.{self::BinaryConstraint::output}();
+    out.{self::Variable::walkStrength} = self::Strength::weakest(this.{self::Constraint::strength}, ihn.{self::Variable::walkStrength});
+    out.{self::Variable::stay} = ihn.{self::Variable::stay};
+    if(out.{self::Variable::stay})
+      this.{self::Constraint::execute}();
+  }
+  method markUnsatisfied() → void {
+    this.{self::BinaryConstraint::direction} = self::NONE;
+  }
+  method inputsKnown(core::int mark) → core::bool {
+    self::Variable i = this.{self::BinaryConstraint::input}();
+    return i.{self::Variable::mark}.{core::num::==}(mark) || i.{self::Variable::stay} || i.{self::Variable::determinedBy}.{core::Object::==}(null);
+  }
+  method removeFromGraph() → void {
+    if(!this.{self::BinaryConstraint::v1}.{core::Object::==}(null))
+      this.{self::BinaryConstraint::v1}.{self::Variable::removeConstraint}(this);
+    if(!this.{self::BinaryConstraint::v2}.{core::Object::==}(null))
+      this.{self::BinaryConstraint::v2}.{self::Variable::removeConstraint}(this);
+    this.{self::BinaryConstraint::direction} = self::NONE;
+  }
+}
+class ScaleConstraint extends self::BinaryConstraint {
+  final field self::Variable scale;
+  final field self::Variable offset;
+  constructor •(self::Variable src, self::Variable scale, self::Variable offset, self::Variable dest, self::Strength strength) → void
+    : self::ScaleConstraint::scale = scale, self::ScaleConstraint::offset = offset, super self::BinaryConstraint::•(src, dest, strength)
+    ;
+  method addToGraph() → void {
+    this.{=self::BinaryConstraint::addToGraph}();
+    this.{self::ScaleConstraint::scale}.{self::Variable::addConstraint}(this);
+    this.{self::ScaleConstraint::offset}.{self::Variable::addConstraint}(this);
+  }
+  method removeFromGraph() → void {
+    this.{=self::BinaryConstraint::removeFromGraph}();
+    if(!this.{self::ScaleConstraint::scale}.{core::Object::==}(null))
+      this.{self::ScaleConstraint::scale}.{self::Variable::removeConstraint}(this);
+    if(!this.{self::ScaleConstraint::offset}.{core::Object::==}(null))
+      this.{self::ScaleConstraint::offset}.{self::Variable::removeConstraint}(this);
+  }
+  method markInputs(core::int mark) → void {
+    this.{=self::BinaryConstraint::markInputs}(mark);
+    this.{self::ScaleConstraint::scale}.{self::Variable::mark} = this.{self::ScaleConstraint::offset}.{self::Variable::mark} = mark;
+  }
+  method execute() → void {
+    if(this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD)) {
+      this.{self::BinaryConstraint::v2}.{self::Variable::value} = this.{self::BinaryConstraint::v1}.{self::Variable::value}.{core::num::*}(this.{self::ScaleConstraint::scale}.{self::Variable::value}).{core::num::+}(this.{self::ScaleConstraint::offset}.{self::Variable::value});
+    }
+    else {
+      this.{self::BinaryConstraint::v1}.{self::Variable::value} = this.{self::BinaryConstraint::v2}.{self::Variable::value}.{core::num::-}(this.{self::ScaleConstraint::offset}.{self::Variable::value}).{core::num::~/}(this.{self::ScaleConstraint::scale}.{self::Variable::value});
+    }
+  }
+  method recalculate() → void {
+    self::Variable ihn = this.{self::BinaryConstraint::input}();
+    self::Variable out = this.{self::BinaryConstraint::output}();
+    out.{self::Variable::walkStrength} = self::Strength::weakest(this.{self::Constraint::strength}, ihn.{self::Variable::walkStrength});
+    out.{self::Variable::stay} = ihn.{self::Variable::stay} && this.{self::ScaleConstraint::scale}.{self::Variable::stay} && this.{self::ScaleConstraint::offset}.{self::Variable::stay};
+    if(out.{self::Variable::stay})
+      this.{self::ScaleConstraint::execute}();
+  }
+}
+class EqualityConstraint extends self::BinaryConstraint {
+  constructor •(self::Variable v1, self::Variable v2, self::Strength strength) → void
+    : super self::BinaryConstraint::•(v1, v2, strength)
+    ;
+  method execute() → void {
+    this.{self::BinaryConstraint::output}().{self::Variable::value} = this.{self::BinaryConstraint::input}().{self::Variable::value};
+  }
+}
+class Variable extends core::Object {
+  field core::List<self::Constraint> constraints = <self::Constraint>[];
+  field self::Constraint determinedBy = null;
+  field core::int mark = 0;
+  field self::Strength walkStrength = self::WEAKEST;
+  field core::bool stay = true;
+  field core::int value;
+  final field core::String name;
+  constructor •(core::String name, core::int value) → void
+    : self::Variable::name = name, self::Variable::value = value, super core::Object::•()
+    ;
+  method addConstraint(self::Constraint c) → void {
+    this.{self::Variable::constraints}.{core::List::add}(c);
+  }
+  method removeConstraint(self::Constraint c) → void {
+    this.{self::Variable::constraints}.{core::List::remove}(c);
+    if(this.{self::Variable::determinedBy}.{core::Object::==}(c))
+      this.{self::Variable::determinedBy} = null;
+  }
+}
+class Planner extends core::Object {
+  field core::int currentMark = 0;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method incrementalAdd(self::Constraint c) → void {
+    core::int mark = this.{self::Planner::newMark}();
+    for (self::Constraint overridden = c.{self::Constraint::satisfy}(mark); !overridden.{core::Object::==}(null); overridden = overridden.{self::Constraint::satisfy}(mark))
+      ;
+  }
+  method incrementalRemove(self::Constraint c) → void {
+    self::Variable out = c.{self::Constraint::output}();
+    c.{self::Constraint::markUnsatisfied}();
+    c.{self::Constraint::removeFromGraph}();
+    core::List<self::Constraint> unsatisfied = this.{self::Planner::removePropagateFrom}(out);
+    self::Strength strength = self::REQUIRED;
+    do {
+      for (core::int i = 0; i.{core::num::<}(unsatisfied.{core::List::length}); i = i.{core::num::+}(1)) {
+        self::Constraint u = unsatisfied.{core::List::[]}(i);
+        if(u.{self::Constraint::strength}.{core::Object::==}(strength))
+          this.{self::Planner::incrementalAdd}(u);
+      }
+      strength = strength.{self::Strength::nextWeaker}();
+    }
+    while (!strength.{core::Object::==}(self::WEAKEST))
+  }
+  method newMark() → core::int
+    return this.{self::Planner::currentMark} = this.{self::Planner::currentMark}.{core::num::+}(1);
+  method makePlan(core::List<self::Constraint> sources) → self::Plan {
+    core::int mark = this.{self::Planner::newMark}();
+    self::Plan plan = new self::Plan::•();
+    core::List<self::Constraint> todo = sources;
+    while (todo.{core::List::length}.{core::num::>}(0)) {
+      self::Constraint c = todo.{core::List::removeLast}();
+      if(!c.{self::Constraint::output}().{self::Variable::mark}.{core::num::==}(mark) && c.{self::Constraint::inputsKnown}(mark)) {
+        plan.{self::Plan::addConstraint}(c);
+        c.{self::Constraint::output}().{self::Variable::mark} = mark;
+        this.{self::Planner::addConstraintsConsumingTo}(c.{self::Constraint::output}(), todo);
+      }
+    }
+    return plan;
+  }
+  method extractPlanFromConstraints(core::List<self::Constraint> constraints) → self::Plan {
+    core::List<self::Constraint> sources = <self::Constraint>[];
+    for (core::int i = 0; i.{core::num::<}(constraints.{core::List::length}); i = i.{core::num::+}(1)) {
+      self::Constraint c = constraints.{core::List::[]}(i);
+      if(c.{self::Constraint::isInput}() && c.{self::Constraint::isSatisfied}())
+        sources.{core::List::add}(c);
+    }
+    return this.{self::Planner::makePlan}(sources);
+  }
+  method addPropagate(self::Constraint c, core::int mark) → core::bool {
+    core::List<self::Constraint> todo = <self::Constraint>[c];
+    while (todo.{core::List::length}.{core::num::>}(0)) {
+      self::Constraint d = todo.{core::List::removeLast}();
+      if(d.{self::Constraint::output}().{self::Variable::mark}.{core::num::==}(mark)) {
+        this.{self::Planner::incrementalRemove}(c);
+        return false;
+      }
+      d.{self::Constraint::recalculate}();
+      this.{self::Planner::addConstraintsConsumingTo}(d.{self::Constraint::output}(), todo);
+    }
+    return true;
+  }
+  method removePropagateFrom(self::Variable out) → core::List<self::Constraint> {
+    out.{self::Variable::determinedBy} = null;
+    out.{self::Variable::walkStrength} = self::WEAKEST;
+    out.{self::Variable::stay} = true;
+    core::List<self::Constraint> unsatisfied = <self::Constraint>[];
+    core::List<self::Variable> todo = <self::Variable>[out];
+    while (todo.{core::List::length}.{core::num::>}(0)) {
+      self::Variable v = todo.{core::List::removeLast}();
+      for (core::int i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
+        self::Constraint c = v.{self::Variable::constraints}.{core::List::[]}(i);
+        if(!c.{self::Constraint::isSatisfied}())
+          unsatisfied.{core::List::add}(c);
+      }
+      self::Constraint determining = v.{self::Variable::determinedBy};
+      for (core::int i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
+        self::Constraint next = v.{self::Variable::constraints}.{core::List::[]}(i);
+        if(!next.{core::Object::==}(determining) && next.{self::Constraint::isSatisfied}()) {
+          next.{self::Constraint::recalculate}();
+          todo.{core::List::add}(next.{self::Constraint::output}());
+        }
+      }
+    }
+    return unsatisfied;
+  }
+  method addConstraintsConsumingTo(self::Variable v, core::List<self::Constraint> coll) → void {
+    self::Constraint determining = v.{self::Variable::determinedBy};
+    for (core::int i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
+      self::Constraint c = v.{self::Variable::constraints}.{core::List::[]}(i);
+      if(!c.{core::Object::==}(determining) && c.{self::Constraint::isSatisfied}())
+        coll.{core::List::add}(c);
+    }
+  }
+}
+class Plan extends core::Object {
+  field core::List<self::Constraint> list = <self::Constraint>[];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method addConstraint(self::Constraint c) → void {
+    this.{self::Plan::list}.{core::List::add}(c);
+  }
+  method size() → core::int
+    return this.{self::Plan::list}.{core::List::length};
+  method execute() → void {
+    for (core::int i = 0; i.{core::num::<}(this.{self::Plan::list}.{core::List::length}); i = i.{core::num::+}(1)) {
+      this.{self::Plan::list}.{core::List::[]}(i).{self::Constraint::execute}();
+    }
+  }
+}
+static const field self::Strength REQUIRED = const self::Strength::•(0, "required");
+static const field self::Strength STRONG_PREFERRED = const self::Strength::•(1, "strongPreferred");
+static const field self::Strength PREFERRED = const self::Strength::•(2, "preferred");
+static const field self::Strength STRONG_DEFAULT = const self::Strength::•(3, "strongDefault");
+static const field self::Strength NORMAL = const self::Strength::•(4, "normal");
+static const field self::Strength WEAK_DEFAULT = const self::Strength::•(5, "weakDefault");
+static const field self::Strength WEAKEST = const self::Strength::•(6, "weakest");
+static const field core::int NONE = 1;
+static const field core::int FORWARD = 2;
+static const field core::int BACKWARD = 0;
+static field self::Planner planner = null;
+static method main() → dynamic {
+  new self::DeltaBlue::•().{self::DeltaBlue::run}();
+}
+static method chainTest(core::int n) → void {
+  self::planner = new self::Planner::•();
+  self::Variable prev = null;
+  self::Variable first = null;
+  self::Variable last = null;
+  for (core::int i = 0; i.{core::num::<=}(n); i = i.{core::num::+}(1)) {
+    self::Variable v = new self::Variable::•("v${i}", 0);
+    if(!prev.{core::Object::==}(null))
+      new self::EqualityConstraint::•(prev, v, self::REQUIRED);
+    if(i.{core::num::==}(0))
+      first = v;
+    if(i.{core::num::==}(n))
+      last = v;
+    prev = v;
+  }
+  new self::StayConstraint::•(last, self::STRONG_DEFAULT);
+  self::EditConstraint edit = new self::EditConstraint::•(first, self::PREFERRED);
+  self::Plan plan = self::planner.{self::Planner::extractPlanFromConstraints}(<self::Constraint>[edit]);
+  for (core::int i = 0; i.{core::num::<}(100); i = i.{core::num::+}(1)) {
+    first.{self::Variable::value} = i;
+    plan.{self::Plan::execute}();
+    if(!last.{self::Variable::value}.{core::num::==}(i)) {
+      core::print("Chain test failed:");
+      core::print("Expected last value to be ${i} but it was ${last.{self::Variable::value}}.");
+    }
+  }
+}
+static method projectionTest(core::int n) → void {
+  self::planner = new self::Planner::•();
+  self::Variable scale = new self::Variable::•("scale", 10);
+  self::Variable offset = new self::Variable::•("offset", 1000);
+  self::Variable src = null;
+  self::Variable dst = null;
+  core::List<self::Variable> dests = <self::Variable>[];
+  for (core::int i = 0; i.{core::num::<}(n); i = i.{core::num::+}(1)) {
+    src = new self::Variable::•("src", i);
+    dst = new self::Variable::•("dst", i);
+    dests.{core::List::add}(dst);
+    new self::StayConstraint::•(src, self::NORMAL);
+    new self::ScaleConstraint::•(src, scale, offset, dst, self::REQUIRED);
+  }
+  self::change(src, 17);
+  if(!dst.{self::Variable::value}.{core::num::==}(1170))
+    core::print("Projection 1 failed");
+  self::change(dst, 1050);
+  if(!src.{self::Variable::value}.{core::num::==}(5))
+    core::print("Projection 2 failed");
+  self::change(scale, 5);
+  for (core::int i = 0; i.{core::num::<}(n.{core::num::-}(1)); i = i.{core::num::+}(1)) {
+    if(!dests.{core::List::[]}(i).{self::Variable::value}.{core::num::==}(i.{core::num::*}(5).{core::num::+}(1000)))
+      core::print("Projection 3 failed");
+  }
+  self::change(offset, 2000);
+  for (core::int i = 0; i.{core::num::<}(n.{core::num::-}(1)); i = i.{core::num::+}(1)) {
+    if(!dests.{core::List::[]}(i).{self::Variable::value}.{core::num::==}(i.{core::num::*}(5).{core::num::+}(2000)))
+      core::print("Projection 4 failed");
+  }
+}
+static method change(self::Variable v, core::int newValue) → void {
+  self::EditConstraint edit = new self::EditConstraint::•(v, self::PREFERRED);
+  self::Plan plan = self::planner.{self::Planner::extractPlanFromConstraints}(<self::EditConstraint>[edit]);
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    v.{self::Variable::value} = newValue;
+    plan.{self::Plan::execute}();
+  }
+  edit.{self::Constraint::destroyConstraint}();
+}
diff --git a/pkg/kernel/testcases/strong-mode/argument.baseline.txt b/pkg/kernel/testcases/strong-mode/argument.baseline.txt
new file mode 100644
index 0000000..27c776c
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/argument.baseline.txt
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class Base extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Bar extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Baz extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method foo(dynamic x) → void {}
+static method bar(dynamic x) → void {}
+static method foo_escaped(dynamic x) → void {}
+static method bar_escaped(dynamic x) → void {}
+static method escape(dynamic fn) → void {
+  fn.call(new self::Baz::•());
+}
+static method main() → dynamic {
+  self::foo(new self::Foo::•());
+  self::bar(new self::Bar::•());
+  self::escape(self::foo_escaped);
+  self::escape(self::bar_escaped);
+}
diff --git a/pkg/kernel/testcases/strong-mode/arithmetic.baseline.txt b/pkg/kernel/testcases/strong-mode/arithmetic.baseline.txt
new file mode 100644
index 0000000..e2b593f
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/arithmetic.baseline.txt
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo(core::int x, core::int y) → core::int {
+  core::int z = x.{core::num::+}(y);
+  return z.{core::int::<<}(4);
+}
+static method loop(core::List<dynamic> xs) → void {
+  core::int _ = xs.{core::List::length};
+  for (core::int i = 0; i.{core::num::<}(xs.{core::List::length}); i = i.{core::num::+}(1)) {
+  }
+}
+static method main() → dynamic {
+  self::foo(4, 5);
+  self::foo(6, 7);
+  self::loop(<core::String>["dfg"]);
+}
diff --git a/pkg/kernel/testcases/strong-mode/async_function.baseline.txt b/pkg/kernel/testcases/strong-mode/async_function.baseline.txt
new file mode 100644
index 0000000..4cbc5e0
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/async_function.baseline.txt
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field core::List<core::String> stringList = <core::String>["bar"];
+static method asyncString() → asy::Future<core::String> async {
+  return "foo";
+}
+static method asyncString2() → asy::Future<core::String> async {
+  return self::asyncString();
+}
+static method syncStarString() → core::Iterable<core::String> sync* {
+  yield "foo";
+  yield* self::syncStarString2();
+  yield* self::stringList;
+}
+static method syncStarString2() → core::Iterable<core::String> sync* {
+  yield "foo";
+}
+static method asyncStarString() → asy::Stream<core::String> async* {
+  yield "foo";
+  yield* self::asyncStarString2();
+  yield await self::asyncString();
+}
+static method asyncStarString2() → asy::Stream<core::String> async* {
+  yield "bar";
+}
+static method main() → dynamic async {
+  core::String str = await self::asyncString();
+}
diff --git a/pkg/kernel/testcases/strong-mode/bad_store.baseline.txt b/pkg/kernel/testcases/strong-mode/bad_store.baseline.txt
new file mode 100644
index 0000000..161e6a5
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/bad_store.baseline.txt
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method identity(dynamic x) → dynamic
+  return x;
+static method use(dynamic x) → void {}
+static method main(core::List<core::String> args) → dynamic {
+  dynamic foo = self::identity(new self::Foo::•());
+  if(args.{core::List::length}.{core::num::>}(1)) {
+    foo.field = "string";
+    dynamic first = foo.field;
+    self::use(first);
+    foo.noField = "string";
+    dynamic second = foo.noField;
+    self::use(second);
+  }
+}
diff --git a/pkg/kernel/testcases/strong-mode/call.baseline.txt b/pkg/kernel/testcases/strong-mode/call.baseline.txt
new file mode 100644
index 0000000..387757e
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/call.baseline.txt
@@ -0,0 +1,53 @@
+// Too few positional arguments (call.dart:30:17)
+// Too few positional arguments (call.dart:31:25)
+// Too few positional arguments (call.dart:35:17)
+// Too few positional arguments (call.dart:36:26)
+// Too few positional arguments (call.dart:37:31)
+library;
+import self as self;
+import "dart:core" as core;
+
+class Callable extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(dynamic x) → dynamic {
+    return "string";
+  }
+}
+class CallableGetter extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  get call() → dynamic
+    return new self::Callable::•();
+}
+static method main() → dynamic {
+  (dynamic) → dynamic closure = (dynamic x) → dynamic => x;
+  dynamic int1 = closure.call(1);
+  dynamic int2 = closure.call(1);
+  dynamic int3 = closure.call.call(1);
+  dynamic int4 = closure.call.call.call(1);
+  self::Callable callable = new self::Callable::•();
+  dynamic string1 = callable.{self::Callable::call}(1);
+  dynamic string2 = callable.{self::Callable::call}(1);
+  dynamic string3 = callable.{self::Callable::call}.call(1);
+  dynamic string4 = callable.{self::Callable::call}.call.call(1);
+  self::CallableGetter callableGetter = new self::CallableGetter::•();
+  dynamic string5 = callableGetter.call(1);
+  dynamic string6 = callableGetter.{self::CallableGetter::call}.call(1);
+  dynamic string7 = callableGetter.{self::CallableGetter::call}.call(1);
+  dynamic string8 = callableGetter.{self::CallableGetter::call}.call.call(1);
+  dynamic nothing1 = closure.call();
+  dynamic nothing2 = closure.call();
+  dynamic nothing3 = closure.call.call();
+  dynamic nothing4 = closure.call.call.call();
+  dynamic nothing5 = callable.{self::Callable::call}();
+  dynamic nothing6 = callable.{self::Callable::call}();
+  dynamic nothing7 = callable.{self::Callable::call}.call();
+  dynamic nothing8 = callable.{self::Callable::call}.call.call();
+  dynamic nothing9 = callableGetter.call();
+  dynamic nothing10 = callableGetter.{self::CallableGetter::call}.call();
+  dynamic nothing11 = callableGetter.{self::CallableGetter::call}.call();
+  dynamic nothing12 = callableGetter.{self::CallableGetter::call}.call.call();
+}
diff --git a/pkg/kernel/testcases/strong-mode/closure.baseline.txt b/pkg/kernel/testcases/strong-mode/closure.baseline.txt
new file mode 100644
index 0000000..01ba4e5
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/closure.baseline.txt
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field self::Bar _field = new self::Bar::•();
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useCallback(dynamic callback) → dynamic {
+  dynamic _ = callback.call();
+}
+static method main() → dynamic {
+  dynamic x;
+  function inner() → dynamic {
+    x = new self::Foo::•();
+    return new self::Foo::•();
+  }
+  self::useCallback(inner);
+  self::Bar _ = inner.call().{self::Foo::_field};
+}
diff --git a/pkg/kernel/testcases/strong-mode/escape.baseline.txt b/pkg/kernel/testcases/strong-mode/escape.baseline.txt
new file mode 100644
index 0000000..fd61f99
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/escape.baseline.txt
@@ -0,0 +1,50 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ==(dynamic x) → core::bool
+    return false;
+}
+class X extends core::Object implements self::A, self::B {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useAsA(self::A object) → void {
+  dynamic _ = object.{self::A::field};
+}
+static method useAsB(self::B object) → void {
+  dynamic _ = object.{self::B::field};
+  self::escape(object);
+}
+static method escape(dynamic x) → void {
+  x.==(null) ? x = "" : null;
+  x.==(null) ? x = 45 : null;
+  if(!(x is core::int) && !(x is core::String)) {
+    x.field = 45;
+  }
+}
+static method main() → dynamic {
+  self::X object = new self::X::•();
+  self::useAsA(new self::A::•());
+  self::useAsA(object);
+  self::useAsB(new self::B::•());
+  self::useAsB(object);
+}
diff --git a/pkg/kernel/testcases/strong-mode/external.baseline.txt b/pkg/kernel/testcases/strong-mode/external.baseline.txt
new file mode 100644
index 0000000..e4d6f84
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/external.baseline.txt
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:isolate" as iso;
+
+static field dynamic subscription = null;
+static method onData(dynamic x) → void {
+  core::print(x);
+  self::subscription.cancel();
+}
+static method main() → dynamic {
+  core::String string = core::String::fromCharCode(65);
+  iso::ReceivePort port = iso::ReceivePort::•();
+  self::subscription = port.{iso::ReceivePort::listen}(self::onData);
+  port.{iso::ReceivePort::sendPort}.{iso::SendPort::send}(string);
+}
diff --git a/pkg/kernel/testcases/strong-mode/fallthrough.baseline.txt b/pkg/kernel/testcases/strong-mode/fallthrough.baseline.txt
new file mode 100644
index 0000000..8c544b3
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/fallthrough.baseline.txt
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main(core::List<core::String> args) → void {
+  core::int x = args.{core::List::length};
+  #L1:
+  switch(x) {
+    #L2:
+    case 3:
+      {
+        x = 4;
+        throw new core::FallThroughError::•();
+      }
+    #L3:
+    case 5:
+      {
+        break #L1;
+      }
+    #L4:
+    case 6:
+    case 7:
+      {
+        if(args.{core::List::[]}(0).{core::String::==}("")) {
+          break #L1;
+        }
+        else {
+          return;
+        }
+        throw new core::FallThroughError::•();
+      }
+    #L5:
+    case 4:
+      {
+        break #L1;
+      }
+  }
+}
diff --git a/pkg/kernel/testcases/strong-mode/micro.baseline.txt b/pkg/kernel/testcases/strong-mode/micro.baseline.txt
new file mode 100644
index 0000000..994a9c9
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/micro.baseline.txt
@@ -0,0 +1,81 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method instanceMethod() → dynamic {
+    return 123;
+  }
+}
+abstract class ExternalValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method externalInstanceMethod() → self::ExternalValue;
+}
+class Box extends core::Object {
+  field dynamic field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FinalBox extends core::Object {
+  final field dynamic finalField;
+  constructor •(dynamic finalField) → void
+    : self::FinalBox::finalField = finalField, super core::Object::•()
+    ;
+}
+class SubFinalBox extends self::FinalBox {
+  constructor •(dynamic value) → void
+    : super self::FinalBox::•(value)
+    ;
+}
+class DynamicReceiver1 extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method dynamicallyCalled(dynamic x) → dynamic {}
+}
+class DynamicReceiver2 extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method dynamicallyCalled(dynamic x) → dynamic {}
+}
+static method staticMethod() → dynamic {
+  return "sdfg";
+}
+external static method externalStatic() → core::bool;
+external static method createBar() → self::Bar;
+static method stringArgument(dynamic x) → dynamic {}
+static method intArgument(dynamic x) → dynamic {}
+static method makeDynamicCall(dynamic receiver) → void {
+  receiver.dynamicallyCalled("sdfg");
+}
+static method main() → dynamic {
+  dynamic x = self::staticMethod();
+  dynamic y = new self::Foo::•().{self::Foo::instanceMethod}();
+  core::bool z = self::externalStatic();
+  self::ExternalValue w = self::createBar().{self::Bar::externalInstanceMethod}();
+  self::stringArgument("sdfg");
+  self::intArgument(42);
+  self::Box box = new self::Box::•();
+  box.{self::Box::field} = "sdfg";
+  dynamic a = box.{self::Box::field};
+  self::FinalBox finalBox = new self::FinalBox::•("dfg");
+  dynamic b = finalBox.{self::FinalBox::finalField};
+  self::SubFinalBox subBox = new self::SubFinalBox::•("dfg");
+  dynamic c = subBox.{self::FinalBox::finalField};
+  self::makeDynamicCall(new self::DynamicReceiver1::•());
+  self::makeDynamicCall(new self::DynamicReceiver2::•());
+  core::List<core::String> list = <core::String>["string"];
+  core::String d = list.{core::List::[]}(0);
+}
diff --git a/pkg/kernel/testcases/strong-mode/named_parameters.baseline.txt b/pkg/kernel/testcases/strong-mode/named_parameters.baseline.txt
new file mode 100644
index 0000000..279ed4a
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/named_parameters.baseline.txt
@@ -0,0 +1,33 @@
+// ({alpha: dynamic, beta: dynamic}) → dynamic is not a subtype of ({beta: dynamic, alpha: dynamic}) → dynamic (no location)
+// ({beta: dynamic, alpha: dynamic}) → dynamic is not a subtype of ({alpha: dynamic, beta: dynamic}) → dynamic (no location)
+library;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo({dynamic alpha, dynamic beta}) → dynamic {}
+  method bar({dynamic beta, dynamic alpha}) → dynamic {}
+  method namedCallback(({alpha: core::String, beta: core::int}) → dynamic callback) → dynamic {
+    callback.call(alpha: "one", beta: 2);
+    callback.call(beta: 1, alpha: "two");
+  }
+}
+class Subclass extends self::Superclass {
+  constructor •() → void
+    : super self::Superclass::•()
+    ;
+  method foo({dynamic beta, dynamic alpha}) → dynamic {}
+  method bar({dynamic alpha, dynamic beta}) → dynamic {}
+  method namedCallback(({alpha: core::String, beta: core::int}) → dynamic callback) → dynamic {}
+}
+static method topLevelNamed(dynamic beta, dynamic alpha, {dynamic gamma, dynamic delta}) → dynamic {}
+static method topLevelOptional(dynamic beta, dynamic alpha, [dynamic gamma, dynamic delta]) → dynamic {}
+static method main() → dynamic {
+  new self::Subclass::•().{self::Subclass::foo}(beta: 1, alpha: 2);
+  new self::Subclass::•().{self::Subclass::foo}(alpha: 1, beta: 2);
+  self::topLevelNamed(1, 2, gamma: 3, delta: 4);
+  self::topLevelNamed(1, 2, delta: 3, gamma: 4);
+}
diff --git a/pkg/kernel/testcases/strong-mode/null_aware.baseline.txt b/pkg/kernel/testcases/strong-mode/null_aware.baseline.txt
new file mode 100644
index 0000000..7788c08
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/null_aware.baseline.txt
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  static field core::int staticField = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  let final self::Foo #t1 = foo in #t1.==(null) ? null : #t1.{self::Foo::field} = 5;
+  self::Foo::staticField = 5;
+  let final self::Foo #t2 = foo in #t2.{self::Foo::field}.==(null) ? #t2.{self::Foo::field} = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  let final self::Foo #t3 = foo in #t3.==(null) ? null : #t3.{self::Foo::field}.==(null) ? #t3.{self::Foo::field} = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  core::int intValue = let final core::int #t4 = foo.{self::Foo::field} in #t4.==(null) ? 6 : #t4;
+  core::num numValue = let final core::int #t5 = foo.{self::Foo::field} in #t5.==(null) ? 4.5 : #t5;
+}
diff --git a/pkg/kernel/testcases/strong-mode/optional.baseline.txt b/pkg/kernel/testcases/strong-mode/optional.baseline.txt
new file mode 100644
index 0000000..1087a03
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/optional.baseline.txt
@@ -0,0 +1,66 @@
+// #lib1::InvalidListener is not a subtype of #lib1::Listener (optional.dart:42:20)
+// Too few positional arguments (optional.dart:44:21)
+// Too many positional arguments (optional.dart:45:21)
+// Too few positional arguments (optional.dart:46:24)
+// Too many positional arguments (optional.dart:47:24)
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method(dynamic x, [dynamic y, dynamic z]) → dynamic {
+    return "string";
+  }
+}
+abstract class External extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method externalMethod(core::int x, [core::int y, core::int z]) → core::String;
+  abstract method listen(self::Listener listener) → void;
+}
+abstract class Listener extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method event(core::String input, [core::int x, core::int y]) → void;
+}
+class TestListener extends self::Listener {
+  constructor •() → void
+    : super self::Listener::•()
+    ;
+  method event(core::String input, [core::int x, core::int y]) → void {}
+}
+class ExtendedListener extends self::Listener {
+  constructor •() → void
+    : super self::Listener::•()
+    ;
+  method event(core::String input, [core::int x, core::int y, dynamic z]) → void {}
+}
+class InvalidListener extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method event(dynamic input, [dynamic x]) → void {}
+}
+external static method createExternal() → self::External;
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  dynamic string1 = foo.{self::Foo::method}(1);
+  dynamic string2 = foo.{self::Foo::method}(1, 2);
+  dynamic string3 = foo.{self::Foo::method}(1, 2, 3);
+  self::External extern = self::createExternal();
+  core::String string4 = extern.{self::External::externalMethod}(1);
+  core::String string5 = extern.{self::External::externalMethod}(1, 2);
+  core::String string6 = extern.{self::External::externalMethod}(1, 2, 3);
+  extern.{self::External::listen}(new self::TestListener::•());
+  extern.{self::External::listen}(new self::ExtendedListener::•());
+  extern.{self::External::listen}(new self::InvalidListener::•());
+  dynamic nothing1 = foo.{self::Foo::method}();
+  dynamic nothing2 = foo.{self::Foo::method}(1, 2, 3, 4);
+  core::String nothing3 = extern.{self::External::externalMethod}();
+  core::String nothing4 = extern.{self::External::externalMethod}(1, 2, 3, 4);
+}
diff --git a/pkg/kernel/testcases/strong-mode/override.baseline.txt b/pkg/kernel/testcases/strong-mode/override.baseline.txt
new file mode 100644
index 0000000..1f28522
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/override.baseline.txt
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends self::Foo {
+  constructor •() → void
+    : super self::Foo::•()
+    ;
+}
+class Base extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → self::Foo {
+    return new self::Foo::•();
+  }
+}
+class Sub extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+  method method() → self::Foo {
+    return new self::Bar::•();
+  }
+}
+static method main(core::List<core::String> args) → dynamic {
+  self::Base object = args.{core::List::length}.{core::num::==}(0) ? new self::Base::•() : new self::Sub::•();
+  self::Foo a = object.{self::Base::method}();
+  core::print(a);
+}
diff --git a/pkg/kernel/testcases/strong-mode/prefer_baseclass.baseline.txt b/pkg/kernel/testcases/strong-mode/prefer_baseclass.baseline.txt
new file mode 100644
index 0000000..8e82d39
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/prefer_baseclass.baseline.txt
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class AB1 extends self::A implements self::B {
+  constructor •() → void
+    : super self::A::•()
+    ;
+}
+class AB2 extends self::A implements self::B {
+  constructor •() → void
+    : super self::A::•()
+    ;
+}
+class BA1 extends self::B implements self::A {
+  constructor •() → void
+    : super self::B::•()
+    ;
+}
+class BA2 extends self::B implements self::A {
+  constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method takeSubclassOfA(dynamic obj) → dynamic {}
+static method takeSubclassOfB(dynamic obj) → dynamic {}
+static method main() → dynamic {
+  self::takeSubclassOfA(new self::AB1::•());
+  self::takeSubclassOfA(new self::AB2::•());
+  self::takeSubclassOfB(new self::BA1::•());
+  self::takeSubclassOfB(new self::BA2::•());
+}
diff --git a/pkg/kernel/testcases/strong-mode/redirecting_factory.baseline.txt b/pkg/kernel/testcases/strong-mode/redirecting_factory.baseline.txt
new file mode 100644
index 0000000..be5bd7c
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/redirecting_factory.baseline.txt
@@ -0,0 +1,53 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class FooBase<Tf extends core::Object> extends core::Object {
+  abstract get x() → core::int;
+}
+abstract class Foo<T extends core::Object> extends core::Object implements self::FooBase<dynamic> {
+}
+class Bar<Sb extends core::Object, Tb extends core::Object> extends core::Object implements self::Foo<self::Bar::Tb> {
+  field core::int x;
+  constructor •(core::int x) → void
+    : self::Bar::x = x, super core::Object::•() {
+    core::print("Bar<${self::Bar::Sb},${self::Bar::Tb}>");
+  }
+}
+class Builder<X extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → dynamic {
+    return new self::Bar::•<core::String, self::Builder::X>(4);
+  }
+}
+class SimpleCase<A extends core::Object, B extends core::Object> extends core::Object {
+}
+class SimpleCaseImpl<Ai extends core::Object, Bi extends core::Object> extends core::Object implements self::SimpleCase<self::SimpleCaseImpl::Ai, self::SimpleCaseImpl::Bi> {
+}
+class SimpleCaseImpl2<Ai2 extends core::Object, Bi2 extends core::Object> extends core::Object implements self::SimpleCaseImpl<self::SimpleCaseImpl2::Ai2, self::SimpleCaseImpl2::Bi2> {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Base<M extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mixin<M extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mix<M extends core::Object> extends self::Base<self::Mix::M> implements self::Mixin<self::Mix::M> {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::Bar::•<core::String, core::double>(4).{self::FooBase::x});
+  new self::SimpleCaseImpl2::•<core::int, core::double>();
+  new self::Mix::•<core::double>();
+}
diff --git a/pkg/kernel/testcases/strong-mode/static_setter.baseline.txt b/pkg/kernel/testcases/strong-mode/static_setter.baseline.txt
new file mode 100644
index 0000000..af6242f
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/static_setter.baseline.txt
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static set foo(dynamic x) → dynamic {}
+static method main() → dynamic {
+  self::foo = new self::Foo::•();
+}
diff --git a/pkg/kernel/testcases/strong-mode/store_load.baseline.txt b/pkg/kernel/testcases/strong-mode/store_load.baseline.txt
new file mode 100644
index 0000000..c06ea70
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/store_load.baseline.txt
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic _field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  field dynamic _field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class BarValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  foo.{self::Foo::_field} = new self::FooValue::•();
+  dynamic fooValue = foo.{self::Foo::_field};
+  core::print(fooValue);
+  self::Bar bar = new self::Bar::•();
+  bar.{self::Bar::_field} = new self::BarValue::•();
+  dynamic barValue = bar.{self::Bar::_field};
+  core::print(barValue);
+}
diff --git a/pkg/kernel/testcases/strong-mode/stringliteral.baseline.txt b/pkg/kernel/testcases/strong-mode/stringliteral.baseline.txt
new file mode 100644
index 0000000..00fca06
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/stringliteral.baseline.txt
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::String color = "brown";
+static field core::String thing = "lazy dog";
+static field core::String phrase = "The quick ${self::color} fox\njumped over the ${self::thing}.\n";
+static field core::String adjacent = "${self::color}${self::color}${self::color}";
+static field core::String linebreaks = "${self::color}\n${self::color}\n${self::color}";
+static field core::String other = "${self::color}\n is \n${self::color}";
+static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/strong-mode/uninitialized_fields.baseline.txt b/pkg/kernel/testcases/strong-mode/uninitialized_fields.baseline.txt
new file mode 100644
index 0000000..c4b9044
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/uninitialized_fields.baseline.txt
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Uninitialized extends core::Object {
+  field core::int x = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class PartiallyInitialized extends core::Object {
+  field core::int x = null;
+  constructor •(core::int x) → void
+    : self::PartiallyInitialized::x = x, super core::Object::•()
+    ;
+  constructor noInitializer() → void
+    : super core::Object::•()
+    ;
+}
+class Initialized extends core::Object {
+  field core::int x;
+  constructor •(core::int x) → void
+    : self::Initialized::x = x, super core::Object::•()
+    ;
+}
+class Forwarding extends core::Object {
+  field core::int x;
+  constructor initialize(core::int x) → void
+    : self::Forwarding::x = x, super core::Object::•()
+    ;
+  constructor •(core::int arg) → void
+    : this self::Forwarding::initialize(arg)
+    ;
+}
+static field core::int uninitializedTopLevel = null;
+static field core::int initializedTopLevel = 4;
+static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/strong-mode/void-methods.baseline.txt b/pkg/kernel/testcases/strong-mode/void-methods.baseline.txt
new file mode 100644
index 0000000..73cd4d9
--- /dev/null
+++ b/pkg/kernel/testcases/strong-mode/void-methods.baseline.txt
@@ -0,0 +1,22 @@
+// dynamic is not a subtype of dart.core::int (void-methods.dart:4:27)
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::List<dynamic> list = <core::int>[1, 2, 3];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  set first(dynamic x) → void
+    this.{self::Foo::list}.{core::List::[]=}(0, x);
+  operator []=(dynamic x, dynamic y) → dynamic
+    this.{self::Foo::list}.{core::List::[]=}(x, y);
+  method clear() → void
+    this.{self::Foo::list}.{core::List::clear}();
+}
+static method main() → dynamic {
+  new self::Foo::•().{self::Foo::first} = 4;
+  new self::Foo::•().{self::Foo::[]=}(3, 4);
+  new self::Foo::•().{self::Foo::clear}();
+}
diff --git a/pkg/kernel/testcases/type-propagation/DeltaBlue.baseline.txt b/pkg/kernel/testcases/type-propagation/DeltaBlue.baseline.txt
new file mode 100644
index 0000000..298b869
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/DeltaBlue.baseline.txt
@@ -0,0 +1,450 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class DeltaBlue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method run() → void/Null {
+    self::chainTest(100);
+    self::projectionTest(100);
+  }
+}
+class Strength extends core::Object {
+  final field core::int/core::int* {int} value;
+  final field core::String/core::String* {string} name;
+  const constructor •(core::int/core::int* {int} value, core::String/core::String* {string} name) → void
+    : self::Strength::value = value, self::Strength::name = name, super core::Object::•()
+    ;
+  method nextWeaker() → self::Strength/core::Object+ {*}
+    return const <self::Strength>[self::STRONG_PREFERRED, self::PREFERRED, self::STRONG_DEFAULT, self::NORMAL, self::WEAK_DEFAULT, self::WEAKEST].[](this.value);
+  static method stronger(self::Strength/self::Strength! {other} s1, self::Strength/self::Strength! {other} s2) → core::bool/core::bool* {other} {
+    return s1.value.<(s2.value);
+  }
+  static method weaker(self::Strength/self::Strength! {other} s1, self::Strength/self::Strength! {other} s2) → core::bool/core::bool* {other} {
+    return s1.value.>(s2.value);
+  }
+  static method weakest(self::Strength/self::Strength! {other} s1, self::Strength/self::Strength! {other} s2) → self::Strength/self::Strength! {other} {
+    return self::Strength::weaker(s1, s2) ? s1 : s2;
+  }
+  static method strongest(self::Strength/Nothing s1, self::Strength/Nothing s2) → self::Strength/Nothing {
+    return self::Strength::stronger(s1, s2) ? s1 : s2;
+  }
+}
+abstract class Constraint extends core::Object {
+  final field self::Strength/self::Strength! {other} strength;
+  const constructor •(self::Strength/self::Strength! {other} strength) → void
+    : self::Constraint::strength = strength, super core::Object::•()
+    ;
+  abstract method isSatisfied() → core::bool/<missing type>;
+  abstract method markUnsatisfied() → void/<missing type>;
+  abstract method addToGraph() → void/<missing type>;
+  abstract method removeFromGraph() → void/<missing type>;
+  abstract method chooseMethod(core::int/<missing type> mark) → void/<missing type>;
+  abstract method markInputs(core::int/<missing type> mark) → void/<missing type>;
+  abstract method inputsKnown(core::int/<missing type> mark) → core::bool/<missing type>;
+  abstract method output() → self::Variable/<missing type>;
+  abstract method execute() → void/<missing type>;
+  abstract method recalculate() → void/<missing type>;
+  method addConstraint() → void/Null {
+    this.addToGraph();
+    self::planner.incrementalAdd(this);
+  }
+  method satisfy(dynamic/core::num* {int,double} mark) → self::Constraint/self::Constraint+ {null,other} {
+    this.chooseMethod(mark);
+    if(!this.isSatisfied()) {
+      if(this.strength.==(self::REQUIRED)) {
+        core::print("Could not satisfy a required constraint!");
+      }
+      return null;
+    }
+    this.markInputs(mark);
+    self::Variable/self::Variable! {null,other} out = this.output();
+    self::Constraint/self::Constraint+ {null,other} overridden = out.determinedBy;
+    if(!overridden.==(null))
+      overridden.markUnsatisfied();
+    out.determinedBy = this;
+    if(!self::planner.addPropagate(this, mark))
+      core::print("Cycle encountered");
+    out.mark = mark;
+    return overridden;
+  }
+  method destroyConstraint() → void/Null {
+    if(this.isSatisfied())
+      self::planner.incrementalRemove(this);
+    this.removeFromGraph();
+  }
+  method isInput() → core::bool/core::bool* {other}
+    return false;
+}
+abstract class UnaryConstraint extends self::Constraint {
+  final field self::Variable/self::Variable! {null,other} myOutput;
+  field core::bool/core::bool* {other} satisfied = false;
+  constructor •(self::Variable/self::Variable! {null,other} myOutput, self::Strength/self::Strength! {other} strength) → void
+    : self::UnaryConstraint::myOutput = myOutput, super self::Constraint::•(strength) {
+    this.addConstraint();
+  }
+  method addToGraph() → void/Null {
+    this.myOutput.addConstraint(this);
+    this.satisfied = false;
+  }
+  method chooseMethod(core::int/core::num* {int,double} mark) → void/Null {
+    this.satisfied = !this.myOutput.mark.==(mark) && self::Strength::stronger(this.strength, this.myOutput.walkStrength);
+  }
+  method isSatisfied() → core::bool/core::bool* {other}
+    return this.satisfied;
+  method markInputs(core::int/core::num* {int,double} mark) → void/Null {}
+  method output() → self::Variable/self::Variable! {null,other}
+    return this.myOutput;
+  method recalculate() → void/Null {
+    this.myOutput.walkStrength = this.strength;
+    this.myOutput.stay = !this.isInput();
+    if(this.myOutput.stay)
+      this.execute();
+  }
+  method markUnsatisfied() → void/Null {
+    this.satisfied = false;
+  }
+  method inputsKnown(core::int/core::num* {int,double} mark) → core::bool/core::bool* {other}
+    return true;
+  method removeFromGraph() → void/Null {
+    if(!this.myOutput.==(null))
+      this.myOutput.removeConstraint(this);
+    this.satisfied = false;
+  }
+}
+class StayConstraint extends self::UnaryConstraint {
+  constructor •(self::Variable/self::Variable! {null,other} v, self::Strength/self::Strength! {other} str) → void
+    : super self::UnaryConstraint::•(v, str)
+    ;
+  method execute() → void/Null {}
+}
+class EditConstraint extends self::UnaryConstraint {
+  constructor •(self::Variable/self::Variable! {null,other} v, self::Strength/self::Strength! {other} str) → void
+    : super self::UnaryConstraint::•(v, str)
+    ;
+  method isInput() → core::bool/core::bool* {other}
+    return true;
+  method execute() → void/Null {}
+}
+abstract class BinaryConstraint extends self::Constraint {
+  field self::Variable/self::Variable! {null,other} v1;
+  field self::Variable/self::Variable! {null,other} v2;
+  field core::int/core::int* {int} direction = self::NONE;
+  constructor •(self::Variable/self::Variable! {null,other} v1, self::Variable/self::Variable! {null,other} v2, self::Strength/self::Strength! {other} strength) → void
+    : self::BinaryConstraint::v1 = v1, self::BinaryConstraint::v2 = v2, super self::Constraint::•(strength) {
+    this.addConstraint();
+  }
+  method chooseMethod(core::int/core::num* {int,double} mark) → void/Null {
+    if(this.v1.mark.==(mark)) {
+      this.direction = !this.v2.mark.==(mark) && self::Strength::stronger(this.strength, this.v2.walkStrength) ? self::FORWARD : self::NONE;
+    }
+    if(this.v2.mark.==(mark)) {
+      this.direction = !this.v1.mark.==(mark) && self::Strength::stronger(this.strength, this.v1.walkStrength) ? self::BACKWARD : self::NONE;
+    }
+    if(self::Strength::weaker(this.v1.walkStrength, this.v2.walkStrength)) {
+      this.direction = self::Strength::stronger(this.strength, this.v1.walkStrength) ? self::BACKWARD : self::NONE;
+    }
+    else {
+      this.direction = self::Strength::stronger(this.strength, this.v2.walkStrength) ? self::FORWARD : self::BACKWARD;
+    }
+  }
+  method addToGraph() → void/Null {
+    this.v1.addConstraint(this);
+    this.v2.addConstraint(this);
+    this.direction = self::NONE;
+  }
+  method isSatisfied() → core::bool/core::bool* {other}
+    return !this.direction.==(self::NONE);
+  method markInputs(core::int/core::num* {int,double} mark) → void/Null {
+    this.input().mark = mark;
+  }
+  method input() → self::Variable/self::Variable! {null,other}
+    return this.direction.==(self::FORWARD) ? this.v1 : this.v2;
+  method output() → self::Variable/self::Variable! {null,other}
+    return this.direction.==(self::FORWARD) ? this.v2 : this.v1;
+  method recalculate() → void/Null {
+    self::Variable/self::Variable! {null,other} ihn = this.input();
+    self::Variable/self::Variable! {null,other} out = this.output();
+    out.walkStrength = self::Strength::weakest(this.strength, ihn.walkStrength);
+    out.stay = ihn.stay;
+    if(out.stay)
+      this.execute();
+  }
+  method markUnsatisfied() → void/Null {
+    this.direction = self::NONE;
+  }
+  method inputsKnown(core::int/core::num* {int,double} mark) → core::bool/core::bool* {other} {
+    self::Variable/self::Variable! {null,other} i = this.input();
+    return i.mark.==(mark) || i.stay || i.determinedBy.==(null);
+  }
+  method removeFromGraph() → void/Null {
+    if(!this.v1.==(null))
+      this.v1.removeConstraint(this);
+    if(!this.v2.==(null))
+      this.v2.removeConstraint(this);
+    this.direction = self::NONE;
+  }
+}
+class ScaleConstraint extends self::BinaryConstraint {
+  final field self::Variable/self::Variable! {other} scale;
+  final field self::Variable/self::Variable! {other} offset;
+  constructor •(self::Variable/self::Variable! {null,other} src, self::Variable/self::Variable! {other} scale, self::Variable/self::Variable! {other} offset, self::Variable/self::Variable! {null,other} dest, self::Strength/self::Strength! {other} strength) → void
+    : self::ScaleConstraint::scale = scale, self::ScaleConstraint::offset = offset, super self::BinaryConstraint::•(src, dest, strength)
+    ;
+  method addToGraph() → void/Null {
+    this.{=self::BinaryConstraint::addToGraph}();
+    this.scale.addConstraint(this);
+    this.offset.addConstraint(this);
+  }
+  method removeFromGraph() → void/Null {
+    this.{=self::BinaryConstraint::removeFromGraph}();
+    if(!this.scale.==(null))
+      this.scale.removeConstraint(this);
+    if(!this.offset.==(null))
+      this.offset.removeConstraint(this);
+  }
+  method markInputs(core::int/core::num* {int,double} mark) → void/Null {
+    this.{=self::BinaryConstraint::markInputs}(mark);
+    this.scale.mark = this.offset.mark = mark;
+  }
+  method execute() → void/Null {
+    if(this.direction.==(self::FORWARD)) {
+      this.v2.value = this.v1.value.*(this.scale.value).+(this.offset.value);
+    }
+    else {
+      this.v1.value = this.v2.value.-(this.offset.value).~/(this.scale.value);
+    }
+  }
+  method recalculate() → void/Null {
+    self::Variable/self::Variable! {null,other} ihn = this.input();
+    self::Variable/self::Variable! {null,other} out = this.output();
+    out.walkStrength = self::Strength::weakest(this.strength, ihn.walkStrength);
+    out.stay = ihn.stay && this.scale.stay && this.offset.stay;
+    if(out.stay)
+      this.execute();
+  }
+}
+class EqualityConstraint extends self::BinaryConstraint {
+  constructor •(self::Variable/self::Variable! {null,other} v1, self::Variable/self::Variable! {other} v2, self::Strength/self::Strength! {other} strength) → void
+    : super self::BinaryConstraint::•(v1, v2, strength)
+    ;
+  method execute() → void/Null {
+    this.output().value = this.input().value;
+  }
+}
+class Variable extends core::Object {
+  field core::List<self::Constraint>/core::List* {other} constraints = <self::Constraint>[];
+  field self::Constraint/self::Constraint+ {null,other} determinedBy = null;
+  field core::int/core::num* {int,double} mark = 0;
+  field self::Strength/self::Strength! {other} walkStrength = self::WEAKEST;
+  field core::bool/core::bool* {other} stay = true;
+  field core::int/core::num* {int,double} value;
+  final field core::String/core::String* {string} name;
+  constructor •(core::String/core::String* {string} name, core::int/core::num* {int,double} value) → void
+    : self::Variable::name = name, self::Variable::value = value, super core::Object::•()
+    ;
+  method addConstraint(self::Constraint/self::Constraint+ {other} c) → void/Null {
+    this.constraints.add(c);
+  }
+  method removeConstraint(self::Constraint/self::Constraint+ {other} c) → void/Null {
+    this.constraints.remove(c);
+    if(this.determinedBy.==(c))
+      this.determinedBy = null;
+  }
+}
+class Planner extends core::Object {
+  field core::int/core::num* {int,double} currentMark = 0;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method incrementalAdd(self::Constraint/core::Object+ {*} c) → void/Null {
+    core::int/core::num* {int,double} mark = this.newMark();
+    for (self::Constraint/self::Constraint+ {null,other} overridden = c.satisfy(mark); !overridden.==(null); overridden = overridden.satisfy(mark))
+      ;
+  }
+  method incrementalRemove(self::Constraint/self::Constraint+ {other} c) → void/Null {
+    self::Variable/self::Variable! {null,other} out = c.output();
+    c.markUnsatisfied();
+    c.removeFromGraph();
+    core::List<self::Constraint>/core::List* {other} unsatisfied = this.removePropagateFrom(out);
+    self::Strength/core::Object+ {*} strength = self::REQUIRED;
+    do {
+      for (core::int/core::num* {int,double} i = 0; i.<(unsatisfied.length); i = i.+(1)) {
+        self::Constraint/core::Object+ {*} u = unsatisfied.[](i);
+        if(u.strength.==(strength))
+          this.incrementalAdd(u);
+      }
+      strength = strength.nextWeaker();
+    }
+    while (!strength.==(self::WEAKEST))
+  }
+  method newMark() → core::int/core::num* {int,double}
+    return this.currentMark = this.currentMark.+(1);
+  method makePlan(core::List<self::Constraint>/core::List* {other} sources) → self::Plan/self::Plan! {other} {
+    core::int/core::num* {int,double} mark = this.newMark();
+    self::Plan/self::Plan! {other} plan = new self::Plan::•();
+    core::List<self::Constraint>/core::List* {other} todo = sources;
+    while (todo.length.>(0)) {
+      self::Constraint/core::Object+ {*} c = todo.removeLast();
+      if(!c.output().mark.==(mark) && c.inputsKnown(mark)) {
+        plan.addConstraint(c);
+        c.output().mark = mark;
+        this.addConstraintsConsumingTo(c.output(), todo);
+      }
+    }
+    return plan;
+  }
+  method extractPlanFromConstraints(core::List<self::Constraint>/core::List* {other} constraints) → self::Plan/self::Plan! {other} {
+    core::List<self::Constraint>/core::List* {other} sources = <self::Constraint>[];
+    for (core::int/core::num* {int,double} i = 0; i.<(constraints.length); i = i.+(1)) {
+      self::Constraint/core::Object+ {*} c = constraints.[](i);
+      if(c.isInput() && c.isSatisfied())
+        sources.add(c);
+    }
+    return this.makePlan(sources);
+  }
+  method addPropagate(self::Constraint/self::Constraint+ {other} c, core::int/core::num* {int,double} mark) → core::bool/core::bool* {other} {
+    core::List<self::Constraint>/core::List* {other} todo = <self::Constraint>[c];
+    while (todo.length.>(0)) {
+      self::Constraint/core::Object+ {*} d = todo.removeLast();
+      if(d.output().mark.==(mark)) {
+        this.incrementalRemove(c);
+        return false;
+      }
+      d.recalculate();
+      this.addConstraintsConsumingTo(d.output(), todo);
+    }
+    return true;
+  }
+  method removePropagateFrom(self::Variable/self::Variable! {null,other} out) → core::List<self::Constraint>/core::List* {other} {
+    out.determinedBy = null;
+    out.walkStrength = self::WEAKEST;
+    out.stay = true;
+    core::List<self::Constraint>/core::List* {other} unsatisfied = <self::Constraint>[];
+    core::List<self::Variable>/core::List* {other} todo = <self::Variable>[out];
+    while (todo.length.>(0)) {
+      self::Variable/core::Object+ {*} v = todo.removeLast();
+      for (core::int/core::num* {int,double} i = 0; i.<(v.constraints.length); i = i.+(1)) {
+        self::Constraint/core::Object+ {*} c = v.constraints.[](i);
+        if(!c.isSatisfied())
+          unsatisfied.add(c);
+      }
+      self::Constraint/self::Constraint+ {null,other} determining = v.determinedBy;
+      for (core::int/core::num* {int,double} i = 0; i.<(v.constraints.length); i = i.+(1)) {
+        self::Constraint/core::Object+ {*} next = v.constraints.[](i);
+        if(!next.==(determining) && next.isSatisfied()) {
+          next.recalculate();
+          todo.add(next.output());
+        }
+      }
+    }
+    return unsatisfied;
+  }
+  method addConstraintsConsumingTo(self::Variable/self::Variable! {null,other} v, core::List<self::Constraint>/core::List* {other} coll) → void/Null {
+    self::Constraint/self::Constraint+ {null,other} determining = v.determinedBy;
+    for (core::int/core::num* {int,double} i = 0; i.<(v.constraints.length); i = i.+(1)) {
+      self::Constraint/core::Object+ {*} c = v.constraints.[](i);
+      if(!c.==(determining) && c.isSatisfied())
+        coll.add(c);
+    }
+  }
+}
+class Plan extends core::Object {
+  field core::List<self::Constraint>/core::List* {other} list = <self::Constraint>[];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method addConstraint(self::Constraint/core::Object+ {*} c) → void/Null {
+    this.list.add(c);
+  }
+  method size() → core::int/core::int* {int}
+    return this.list.length;
+  method execute() → void/Null {
+    for (core::int/core::num* {int,double} i = 0; i.<(this.list.length); i = i.+(1)) {
+      this.list.[](i).execute();
+    }
+  }
+}
+static const field dynamic/self::Strength! {other} REQUIRED = const self::Strength::•(0, "required");
+static const field dynamic/self::Strength! {other} STRONG_PREFERRED = const self::Strength::•(1, "strongPreferred");
+static const field dynamic/self::Strength! {other} PREFERRED = const self::Strength::•(2, "preferred");
+static const field dynamic/self::Strength! {other} STRONG_DEFAULT = const self::Strength::•(3, "strongDefault");
+static const field dynamic/self::Strength! {other} NORMAL = const self::Strength::•(4, "normal");
+static const field dynamic/self::Strength! {other} WEAK_DEFAULT = const self::Strength::•(5, "weakDefault");
+static const field dynamic/self::Strength! {other} WEAKEST = const self::Strength::•(6, "weakest");
+static const field core::int/core::int* {int} NONE = 1;
+static const field core::int/core::int* {int} FORWARD = 2;
+static const field core::int/core::int* {int} BACKWARD = 0;
+static field self::Planner/self::Planner! {null,other} planner = null;
+static method main() → dynamic/Null {
+  new self::DeltaBlue::•().run();
+}
+static method chainTest(core::int/core::int* {int} n) → void/Null {
+  self::planner = new self::Planner::•();
+  self::Variable/self::Variable! {null,other} prev = null;
+  self::Variable/self::Variable! {null,other} first = null;
+  self::Variable/self::Variable! {null,other} last = null;
+  for (core::int/core::num* {int,double} i = 0; i.<=(n); i = i.+(1)) {
+    self::Variable/self::Variable! {other} v = new self::Variable::•("v${i}", 0);
+    if(!prev.==(null))
+      new self::EqualityConstraint::•(prev, v, self::REQUIRED);
+    if(i.==(0))
+      first = v;
+    if(i.==(n))
+      last = v;
+    prev = v;
+  }
+  new self::StayConstraint::•(last, self::STRONG_DEFAULT);
+  self::EditConstraint/self::EditConstraint! {other} edit = new self::EditConstraint::•(first, self::PREFERRED);
+  self::Plan/self::Plan! {other} plan = self::planner.extractPlanFromConstraints(<self::Constraint>[edit]);
+  for (core::int/core::num* {int,double} i = 0; i.<(100); i = i.+(1)) {
+    first.value = i;
+    plan.execute();
+    if(!last.value.==(i)) {
+      core::print("Chain test failed:");
+      core::print("Expected last value to be ${i} but it was ${last.value}.");
+    }
+  }
+}
+static method projectionTest(core::int/core::int* {int} n) → void/Null {
+  self::planner = new self::Planner::•();
+  self::Variable/self::Variable! {other} scale = new self::Variable::•("scale", 10);
+  self::Variable/self::Variable! {other} offset = new self::Variable::•("offset", 1000);
+  self::Variable/self::Variable! {null,other} src = null;
+  self::Variable/self::Variable! {null,other} dst = null;
+  core::List<self::Variable>/core::List* {other} dests = <self::Variable>[];
+  for (core::int/core::num* {int,double} i = 0; i.<(n); i = i.+(1)) {
+    src = new self::Variable::•("src", i);
+    dst = new self::Variable::•("dst", i);
+    dests.add(dst);
+    new self::StayConstraint::•(src, self::NORMAL);
+    new self::ScaleConstraint::•(src, scale, offset, dst, self::REQUIRED);
+  }
+  self::change(src, 17);
+  if(!dst.value.==(1170))
+    core::print("Projection 1 failed");
+  self::change(dst, 1050);
+  if(!src.value.==(5))
+    core::print("Projection 2 failed");
+  self::change(scale, 5);
+  for (core::int/core::num* {int,double} i = 0; i.<(n.-(1)); i = i.+(1)) {
+    if(!dests.[](i).value.==(i.*(5).+(1000)))
+      core::print("Projection 3 failed");
+  }
+  self::change(offset, 2000);
+  for (core::int/core::num* {int,double} i = 0; i.<(n.-(1)); i = i.+(1)) {
+    if(!dests.[](i).value.==(i.*(5).+(2000)))
+      core::print("Projection 4 failed");
+  }
+}
+static method change(self::Variable/self::Variable! {null,other} v, core::int/core::int* {int} newValue) → void/Null {
+  self::EditConstraint/self::EditConstraint! {other} edit = new self::EditConstraint::•(v, self::PREFERRED);
+  self::Plan/self::Plan! {other} plan = self::planner.extractPlanFromConstraints(<self::EditConstraint>[edit]);
+  for (core::int/core::num* {int,double} i = 0; i.<(10); i = i.+(1)) {
+    v.value = newValue;
+    plan.execute();
+  }
+  edit.destroyConstraint();
+}
diff --git a/pkg/kernel/testcases/type-propagation/argument.baseline.txt b/pkg/kernel/testcases/type-propagation/argument.baseline.txt
new file mode 100644
index 0000000..f120511
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/argument.baseline.txt
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class Base extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Bar extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Baz extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method foo(dynamic/self::Foo! {other} x) → void/Null {}
+static method bar(dynamic/self::Bar! {other} x) → void/Null {}
+static method foo_escaped(dynamic/core::Object+ {*} x) → void/Null {}
+static method bar_escaped(dynamic/core::Object+ {*} x) → void/Null {}
+static method escape(dynamic/core::Function* {other} fn) → void/Null {
+  fn.call(new self::Baz::•());
+}
+static method main() → dynamic/Null {
+  self::foo(new self::Foo::•());
+  self::bar(new self::Bar::•());
+  self::escape(self::foo_escaped);
+  self::escape(self::bar_escaped);
+}
diff --git a/pkg/kernel/testcases/type-propagation/arithmetic.baseline.txt b/pkg/kernel/testcases/type-propagation/arithmetic.baseline.txt
new file mode 100644
index 0000000..8a8496d
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/arithmetic.baseline.txt
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo(core::int/core::int* {int} x, core::int/core::int* {int} y) → core::int/core::int* {int} {
+  dynamic/core::num* {int,double} z = x.+(y);
+  return z.<<(4);
+}
+static method loop(core::List<dynamic>/core::List* {other} xs) → void/Null {
+  core::int/core::int* {int} _ = xs.length;
+  for (core::int/core::num* {int,double} i = 0; i.<(xs.length); i = i.+(1)) {
+  }
+}
+static method main() → dynamic/Null {
+  self::foo(4, 5);
+  self::foo(6, 7);
+  self::loop(<dynamic>["dfg"]);
+}
diff --git a/pkg/kernel/testcases/type-propagation/async_function.baseline.txt b/pkg/kernel/testcases/type-propagation/async_function.baseline.txt
new file mode 100644
index 0000000..6735807
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/async_function.baseline.txt
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field core::List<core::String>/core::List* {other} stringList = <dynamic>["bar"];
+static method asyncString() → asy::Future<core::String>/core::String* {string} async {
+  return "foo";
+}
+static method asyncString2() → asy::Future<core::String>/core::String* {string} async {
+  return self::asyncString();
+}
+static method syncStarString() → core::Iterable<core::String>/Null sync* {
+  yield "foo";
+  yield* self::syncStarString2();
+  yield* self::stringList;
+}
+static method syncStarString2() → core::Iterable<core::String>/Null sync* {
+  yield "foo";
+}
+static method asyncStarString() → asy::Stream<core::String>/Null async* {
+  yield "foo";
+  yield* self::asyncStarString2();
+  yield await self::asyncString();
+}
+static method asyncStarString2() → asy::Stream<core::String>/Null async* {
+  yield "bar";
+}
+static method main() → dynamic/Null async {
+  core::String/core::Object* {*} str = await self::asyncString();
+}
diff --git a/pkg/kernel/testcases/type-propagation/bad_store.baseline.txt b/pkg/kernel/testcases/type-propagation/bad_store.baseline.txt
new file mode 100644
index 0000000..fa01512
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/bad_store.baseline.txt
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic/core::String* {null,string} field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method identity(dynamic/self::Foo! {other} x) → dynamic/self::Foo! {other}
+  return x;
+static method use(dynamic/core::String* {null,string} x) → void/Null {}
+static method main(core::List<core::String>/Nothing args) → dynamic/Null {
+  dynamic/self::Foo! {other} foo = self::identity(new self::Foo::•());
+  if(args.length.>(1)) {
+    foo.field = "string";
+    dynamic/core::String* {null,string} first = foo.field;
+    self::use(first);
+    foo.noField = "string";
+    dynamic/Nothing second = foo.noField;
+    self::use(second);
+  }
+}
diff --git a/pkg/kernel/testcases/type-propagation/call.baseline.txt b/pkg/kernel/testcases/type-propagation/call.baseline.txt
new file mode 100644
index 0000000..2198610
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/call.baseline.txt
@@ -0,0 +1,48 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Callable extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(dynamic/core::int* {int} x) → dynamic/core::String* {string} {
+    return "string";
+  }
+}
+class CallableGetter extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  get call() → dynamic/self::Callable! {other}
+    return new self::Callable::•();
+}
+static method main() → dynamic/Null {
+  dynamic/core::Function* {other} closure = (dynamic/core::int* {int} x) → dynamic/core::int* {int} => x;
+  dynamic/core::int* {int} int1 = closure.call(1);
+  dynamic/core::int* {int} int2 = closure.call(1);
+  dynamic/core::int* {int} int3 = closure.call.call(1);
+  dynamic/core::int* {int} int4 = closure.call.call.call(1);
+  dynamic/self::Callable! {other} callable = new self::Callable::•();
+  dynamic/core::String* {string} string1 = callable.call(1);
+  dynamic/core::String* {string} string2 = callable.call(1);
+  dynamic/core::String* {string} string3 = callable.call.call(1);
+  dynamic/core::String* {string} string4 = callable.call.call.call(1);
+  dynamic/self::CallableGetter! {other} callableGetter = new self::CallableGetter::•();
+  dynamic/core::String* {string} string5 = callableGetter.call(1);
+  dynamic/core::String* {string} string6 = callableGetter.call(1);
+  dynamic/core::String* {string} string7 = callableGetter.call.call(1);
+  dynamic/core::String* {string} string8 = callableGetter.call.call.call(1);
+  dynamic/Nothing nothing1 = closure.call();
+  dynamic/Nothing nothing2 = closure.call();
+  dynamic/Nothing nothing3 = closure.call.call();
+  dynamic/Nothing nothing4 = closure.call.call.call();
+  dynamic/Nothing nothing5 = callable.call();
+  dynamic/Nothing nothing6 = callable.call();
+  dynamic/Nothing nothing7 = callable.call.call();
+  dynamic/Nothing nothing8 = callable.call.call.call();
+  dynamic/Nothing nothing9 = callableGetter.call();
+  dynamic/Nothing nothing10 = callableGetter.call();
+  dynamic/Nothing nothing11 = callableGetter.call.call();
+  dynamic/Nothing nothing12 = callableGetter.call.call.call();
+}
diff --git a/pkg/kernel/testcases/type-propagation/closure.baseline.txt b/pkg/kernel/testcases/type-propagation/closure.baseline.txt
new file mode 100644
index 0000000..abb3a73
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/closure.baseline.txt
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic/self::Bar! {other} _field = new self::Bar::•();
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useCallback(dynamic/core::Function* {other} callback) → dynamic/Null {
+  dynamic/self::Foo! {other} _ = callback.call();
+}
+static method main() → dynamic/Null {
+  dynamic/self::Foo! {null,other} x;
+  function inner() → dynamic/self::Foo! {other} {
+    x = new self::Foo::•();
+    return new self::Foo::•();
+  }
+  self::useCallback(inner);
+  dynamic/self::Bar! {other} _ = inner.call()._field;
+}
diff --git a/pkg/kernel/testcases/type-propagation/escape.baseline.txt b/pkg/kernel/testcases/type-propagation/escape.baseline.txt
new file mode 100644
index 0000000..f7ece34
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/escape.baseline.txt
@@ -0,0 +1,50 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic/Null field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field dynamic/core::int* {null,int} field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ==(dynamic/Nothing x) → dynamic/core::bool* {other}
+    return false;
+}
+class X extends core::Object implements self::A, self::B {
+  field dynamic/core::int* {null,int} field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useAsA(self::A/self::A* {other} object) → void/Null {
+  dynamic/core::int* {null,int} _ = object.field;
+}
+static method useAsB(self::B/self::B* {other} object) → void/Null {
+  dynamic/core::int* {null,int} _ = object.field;
+  self::escape(object);
+}
+static method escape(dynamic/core::Object+ {int,string,other} x) → void/Null {
+  x.==(null) ? x = "" : null;
+  x.==(null) ? x = 45 : null;
+  if(!(x is core::int) && !(x is core::String)) {
+    x.field = 45;
+  }
+}
+static method main() → dynamic/Null {
+  dynamic/self::X! {other} object = new self::X::•();
+  self::useAsA(new self::A::•());
+  self::useAsA(object);
+  self::useAsB(new self::B::•());
+  self::useAsB(object);
+}
diff --git a/pkg/kernel/testcases/type-propagation/external.baseline.txt b/pkg/kernel/testcases/type-propagation/external.baseline.txt
new file mode 100644
index 0000000..c80d0b4
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/external.baseline.txt
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:isolate" as iso;
+
+static field dynamic/dart.async::StreamSubscription* {null,other} subscription = null;
+static method onData(dynamic/core::Object* {*} x) → void/Null {
+  core::print(x);
+  self::subscription.cancel();
+}
+static method main() → dynamic/Null {
+  dynamic/core::String* {string} string = core::String::fromCharCode(65);
+  dynamic/iso::ReceivePort* {other} port = iso::ReceivePort::•();
+  self::subscription = port.listen(self::onData);
+  port.sendPort.send(string);
+}
diff --git a/pkg/kernel/testcases/type-propagation/fallthrough.baseline.txt b/pkg/kernel/testcases/type-propagation/fallthrough.baseline.txt
new file mode 100644
index 0000000..1d635f0
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/fallthrough.baseline.txt
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main(core::List<core::String>/Nothing args) → void/Null {
+  dynamic/core::int* {int} x = args.length;
+  #L1:
+  switch(x) {
+    #L2:
+    case 3:
+      {
+        x = 4;
+        throw new core::FallThroughError::•();
+      }
+    #L3:
+    case 5:
+      {
+        break #L1;
+      }
+    #L4:
+    case 6:
+    case 7:
+      {
+        if(args.[](0).==("")) {
+          break #L1;
+        }
+        else {
+          return;
+        }
+        throw new core::FallThroughError::•();
+      }
+    #L5:
+    case 4:
+      {
+        break #L1;
+      }
+  }
+}
diff --git a/pkg/kernel/testcases/type-propagation/micro.baseline.txt b/pkg/kernel/testcases/type-propagation/micro.baseline.txt
new file mode 100644
index 0000000..ccde2c4
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/micro.baseline.txt
@@ -0,0 +1,81 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method instanceMethod() → dynamic/core::int* {int} {
+    return 123;
+  }
+}
+abstract class ExternalValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method externalInstanceMethod() → self::ExternalValue/<missing type>;
+}
+class Box extends core::Object {
+  field dynamic/core::String* {null,string} field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FinalBox extends core::Object {
+  final field dynamic/core::String* {string} finalField;
+  constructor •(dynamic/core::String* {string} finalField) → void
+    : self::FinalBox::finalField = finalField, super core::Object::•()
+    ;
+}
+class SubFinalBox extends self::FinalBox {
+  constructor •(dynamic/core::String* {string} value) → void
+    : super self::FinalBox::•(value)
+    ;
+}
+class DynamicReceiver1 extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method dynamicallyCalled(dynamic/core::String* {string} x) → dynamic/Null {}
+}
+class DynamicReceiver2 extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method dynamicallyCalled(dynamic/core::String* {string} x) → dynamic/Null {}
+}
+static method staticMethod() → dynamic/core::String* {string} {
+  return "sdfg";
+}
+external static method externalStatic() → core::bool/core::bool* {other};
+external static method createBar() → self::Bar/self::Bar* {other};
+static method stringArgument(dynamic/core::String* {string} x) → dynamic/Null {}
+static method intArgument(dynamic/core::int* {int} x) → dynamic/Null {}
+static method makeDynamicCall(dynamic/core::Object+ {other} receiver) → void/Null {
+  receiver.dynamicallyCalled("sdfg");
+}
+static method main() → dynamic/Null {
+  dynamic/core::String* {string} x = self::staticMethod();
+  dynamic/core::int* {int} y = new self::Foo::•().instanceMethod();
+  dynamic/core::bool* {other} z = self::externalStatic();
+  dynamic/self::ExternalValue* {other} w = self::createBar().externalInstanceMethod();
+  self::stringArgument("sdfg");
+  self::intArgument(42);
+  dynamic/self::Box! {other} box = new self::Box::•();
+  box.field = "sdfg";
+  dynamic/core::String* {null,string} a = box.field;
+  dynamic/self::FinalBox! {other} finalBox = new self::FinalBox::•("dfg");
+  dynamic/core::String* {string} b = finalBox.finalField;
+  dynamic/self::SubFinalBox! {other} subBox = new self::SubFinalBox::•("dfg");
+  dynamic/core::String* {string} c = subBox.finalField;
+  self::makeDynamicCall(new self::DynamicReceiver1::•());
+  self::makeDynamicCall(new self::DynamicReceiver2::•());
+  dynamic/core::List* {other} list = <dynamic>["string"];
+  dynamic/core::Object+ {*} d = list.[](0);
+}
diff --git a/pkg/kernel/testcases/type-propagation/named_parameters.baseline.txt b/pkg/kernel/testcases/type-propagation/named_parameters.baseline.txt
new file mode 100644
index 0000000..d005aa2
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/named_parameters.baseline.txt
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo({dynamic/Null alpha, dynamic/Null beta}) → dynamic/Null {}
+  method bar({dynamic/Null beta, dynamic/Null alpha}) → dynamic/Null {}
+  method namedCallback(({alpha: core::String, beta: core::int}) → dynamic/Nothing callback) → dynamic/Null {
+    callback.call(alpha: "one", beta: 2);
+    callback.call(beta: 1, alpha: "two");
+  }
+}
+class Subclass extends self::Superclass {
+  constructor •() → void
+    : super self::Superclass::•()
+    ;
+  method foo({dynamic/core::int* {null,int} beta, dynamic/core::int* {null,int} alpha}) → dynamic/Null {}
+  method bar({dynamic/Null alpha, dynamic/Null beta}) → dynamic/Null {}
+  method namedCallback(({alpha: core::String, beta: core::int}) → dynamic/Nothing callback) → dynamic/Null {}
+}
+static method topLevelNamed(dynamic/core::int* {int} beta, dynamic/core::int* {int} alpha, {dynamic/core::int* {null,int} gamma, dynamic/core::int* {null,int} delta}) → dynamic/Null {}
+static method topLevelOptional(dynamic/Nothing beta, dynamic/Nothing alpha, [dynamic/Null gamma, dynamic/Null delta]) → dynamic/Null {}
+static method main() → dynamic/Null {
+  new self::Subclass::•().foo(beta: 1, alpha: 2);
+  new self::Subclass::•().foo(alpha: 1, beta: 2);
+  self::topLevelNamed(1, 2, gamma: 3, delta: 4);
+  self::topLevelNamed(1, 2, delta: 3, gamma: 4);
+}
diff --git a/pkg/kernel/testcases/type-propagation/null_aware.baseline.txt b/pkg/kernel/testcases/type-propagation/null_aware.baseline.txt
new file mode 100644
index 0000000..7e706e1
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/null_aware.baseline.txt
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int/core::int* {null,int} field = null;
+  static field core::int/core::int* {null,int} staticField = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic/Null {
+  self::Foo/self::Foo! {other} foo = new self::Foo::•();
+  let final dynamic/<missing type> #t1 = foo in #t1.==(null) ? null : #t1.field = 5;
+  self::Foo::staticField = 5;
+  let final dynamic/<missing type> #t2 = foo in #t2.field.==(null) ? #t2.field = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  let final dynamic/<missing type> #t3 = foo in #t3.==(null) ? null : #t3.field.==(null) ? #t3.field = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  core::int/core::int* {null,int} intValue = let final dynamic/<missing type> #t4 = foo.field in #t4.==(null) ? 6 : #t4;
+  core::num/core::num* {null,int,double} numValue = let final dynamic/<missing type> #t5 = foo.field in #t5.==(null) ? 4.5 : #t5;
+}
diff --git a/pkg/kernel/testcases/type-propagation/optional.baseline.txt b/pkg/kernel/testcases/type-propagation/optional.baseline.txt
new file mode 100644
index 0000000..cc8f47e
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/optional.baseline.txt
@@ -0,0 +1,61 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method(dynamic/core::int* {int} x, [dynamic/core::int* {null,int} y, dynamic/core::int* {null,int} z]) → dynamic/core::String* {string} {
+    return "string";
+  }
+}
+abstract class External extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method externalMethod(core::int/<missing type> x, [core::int/<missing type> y, core::int/<missing type> z]) → core::String/<missing type>;
+  abstract method listen(self::Listener/<missing type> listener) → void/<missing type>;
+}
+abstract class Listener extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method event(core::String/<missing type> input, [core::int/<missing type> x, core::int/<missing type> y]) → void/<missing type>;
+}
+class TestListener extends self::Listener {
+  constructor •() → void
+    : super self::Listener::•()
+    ;
+  method event(dynamic/core::String* {string} input, [dynamic/core::int* {null,int} x, dynamic/core::int* {null,int} y]) → void/Null {}
+}
+class ExtendedListener extends self::Listener {
+  constructor •() → void
+    : super self::Listener::•()
+    ;
+  method event(dynamic/core::String* {string} input, [dynamic/core::int* {null,int} x, dynamic/core::int* {null,int} y, dynamic/Null z]) → void/Null {}
+}
+class InvalidListener extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method event(dynamic/core::String* {string} input, [dynamic/core::int* {null,int} x]) → void/Null {}
+}
+external static method createExternal() → self::External/self::External* {other};
+static method main() → dynamic/Null {
+  dynamic/self::Foo! {other} foo = new self::Foo::•();
+  dynamic/core::String* {string} string1 = foo.method(1);
+  dynamic/core::String* {string} string2 = foo.method(1, 2);
+  dynamic/core::String* {string} string3 = foo.method(1, 2, 3);
+  dynamic/self::External* {other} extern = self::createExternal();
+  dynamic/core::String* {string} string4 = extern.externalMethod(1);
+  dynamic/core::String* {string} string5 = extern.externalMethod(1, 2);
+  dynamic/core::String* {string} string6 = extern.externalMethod(1, 2, 3);
+  extern.listen(new self::TestListener::•());
+  extern.listen(new self::ExtendedListener::•());
+  extern.listen(new self::InvalidListener::•());
+  dynamic/Nothing nothing1 = foo.method();
+  dynamic/Nothing nothing2 = foo.method(1, 2, 3, 4);
+  dynamic/Nothing nothing3 = extern.externalMethod();
+  dynamic/Nothing nothing4 = extern.externalMethod(1, 2, 3, 4);
+}
diff --git a/pkg/kernel/testcases/type-propagation/override.baseline.txt b/pkg/kernel/testcases/type-propagation/override.baseline.txt
new file mode 100644
index 0000000..89d7c33
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/override.baseline.txt
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends self::Foo {
+  constructor •() → void
+    : super self::Foo::•()
+    ;
+}
+class Base extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → self::Foo/self::Foo! {other} {
+    return new self::Foo::•();
+  }
+}
+class Sub extends self::Base {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+  method method() → self::Foo/self::Bar! {other} {
+    return new self::Bar::•();
+  }
+}
+static method main(core::List<core::String>/Nothing args) → dynamic/Null {
+  dynamic/self::Base+ {other} object = args.length.==(0) ? new self::Base::•() : new self::Sub::•();
+  dynamic/self::Foo+ {other} a = object.method();
+  core::print(a);
+}
diff --git a/pkg/kernel/testcases/type-propagation/prefer_baseclass.baseline.txt b/pkg/kernel/testcases/type-propagation/prefer_baseclass.baseline.txt
new file mode 100644
index 0000000..c54543b
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/prefer_baseclass.baseline.txt
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class AB1 extends self::A implements self::B {
+  constructor •() → void
+    : super self::A::•()
+    ;
+}
+class AB2 extends self::A implements self::B {
+  constructor •() → void
+    : super self::A::•()
+    ;
+}
+class BA1 extends self::B implements self::A {
+  constructor •() → void
+    : super self::B::•()
+    ;
+}
+class BA2 extends self::B implements self::A {
+  constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method takeSubclassOfA(dynamic/self::A+ {other} obj) → dynamic/Null {}
+static method takeSubclassOfB(dynamic/self::B+ {other} obj) → dynamic/Null {}
+static method main() → dynamic/Null {
+  self::takeSubclassOfA(new self::AB1::•());
+  self::takeSubclassOfA(new self::AB2::•());
+  self::takeSubclassOfB(new self::BA1::•());
+  self::takeSubclassOfB(new self::BA2::•());
+}
diff --git a/pkg/kernel/testcases/type-propagation/redirecting_factory.baseline.txt b/pkg/kernel/testcases/type-propagation/redirecting_factory.baseline.txt
new file mode 100644
index 0000000..20a2d4c
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/redirecting_factory.baseline.txt
@@ -0,0 +1,53 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class FooBase<Tf extends core::Object> extends core::Object {
+  abstract get x() → core::int/<missing type>;
+}
+abstract class Foo<T extends core::Object> extends core::Object implements self::FooBase<dynamic> {
+}
+class Bar<Sb extends core::Object, Tb extends core::Object> extends core::Object implements self::Foo<self::Bar::Tb> {
+  field core::int/core::int* {int} x;
+  constructor •(core::int/core::int* {int} x) → void
+    : self::Bar::x = x, super core::Object::•() {
+    core::print("Bar<${self::Bar::Sb},${self::Bar::Tb}>");
+  }
+}
+class Builder<X extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → dynamic/self::Bar! {other} {
+    return new self::Bar::•<core::String, self::Builder::X>(4);
+  }
+}
+class SimpleCase<A extends core::Object, B extends core::Object> extends core::Object {
+}
+class SimpleCaseImpl<Ai extends core::Object, Bi extends core::Object> extends core::Object implements self::SimpleCase<self::SimpleCaseImpl::Ai, self::SimpleCaseImpl::Bi> {
+}
+class SimpleCaseImpl2<Ai2 extends core::Object, Bi2 extends core::Object> extends core::Object implements self::SimpleCaseImpl<self::SimpleCaseImpl2::Ai2, self::SimpleCaseImpl2::Bi2> {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Base<M extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mixin<M extends core::Object> extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mix<M extends core::Object> extends self::Base<self::Mix::M> implements self::Mixin<self::Mix::M> {
+  constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic/Null {
+  core::print(new self::Bar::•<core::String, core::double>(4).x);
+  new self::SimpleCaseImpl2::•<core::int, core::double>();
+  new self::Mix::•<core::double>();
+}
diff --git a/pkg/kernel/testcases/type-propagation/static_setter.baseline.txt b/pkg/kernel/testcases/type-propagation/static_setter.baseline.txt
new file mode 100644
index 0000000..6bf6f26
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/static_setter.baseline.txt
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static set foo(dynamic/self::Foo! {other} x) → dynamic/Null {}
+static method main() → dynamic/Null {
+  self::foo = new self::Foo::•();
+}
diff --git a/pkg/kernel/testcases/type-propagation/store_load.baseline.txt b/pkg/kernel/testcases/type-propagation/store_load.baseline.txt
new file mode 100644
index 0000000..0e1c0ee
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/store_load.baseline.txt
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic/self::FooValue! {null,other} _field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  field dynamic/self::BarValue! {null,other} _field = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class BarValue extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic/Null {
+  dynamic/self::Foo! {other} foo = new self::Foo::•();
+  foo._field = new self::FooValue::•();
+  dynamic/self::FooValue! {null,other} fooValue = foo._field;
+  core::print(fooValue);
+  dynamic/self::Bar! {other} bar = new self::Bar::•();
+  bar._field = new self::BarValue::•();
+  dynamic/self::BarValue! {null,other} barValue = bar._field;
+  core::print(barValue);
+}
diff --git a/pkg/kernel/testcases/type-propagation/stringliteral.baseline.txt b/pkg/kernel/testcases/type-propagation/stringliteral.baseline.txt
new file mode 100644
index 0000000..ded8c03
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/stringliteral.baseline.txt
@@ -0,0 +1,10 @@
+library;
+import self as self;
+
+static field dynamic/dart.core::String* {string} color = "brown";
+static field dynamic/dart.core::String* {string} thing = "lazy dog";
+static field dynamic/dart.core::String* {string} phrase = "The quick ${self::color} fox\njumped over the ${self::thing}.\n";
+static field dynamic/dart.core::String* {string} adjacent = "${self::color}${self::color}${self::color}";
+static field dynamic/dart.core::String* {string} linebreaks = "${self::color}\n${self::color}\n${self::color}";
+static field dynamic/dart.core::String* {string} other = "${self::color}\n is \n${self::color}";
+static method main() → dynamic/Null {}
diff --git a/pkg/kernel/testcases/type-propagation/uninitialized_fields.baseline.txt b/pkg/kernel/testcases/type-propagation/uninitialized_fields.baseline.txt
new file mode 100644
index 0000000..d9a8ef5
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/uninitialized_fields.baseline.txt
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Uninitialized extends core::Object {
+  field core::int/Null x = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class PartiallyInitialized extends core::Object {
+  field core::int/Null x = null;
+  constructor •(core::int/Nothing x) → void
+    : self::PartiallyInitialized::x = x, super core::Object::•()
+    ;
+  constructor noInitializer() → void
+    : super core::Object::•()
+    ;
+}
+class Initialized extends core::Object {
+  field core::int/Nothing x;
+  constructor •(core::int/Nothing x) → void
+    : self::Initialized::x = x, super core::Object::•()
+    ;
+}
+class Forwarding extends core::Object {
+  field core::int/Null x;
+  constructor initialize(core::int/Nothing x) → void
+    : self::Forwarding::x = x, super core::Object::•()
+    ;
+  constructor •(core::int/Nothing arg) → void
+    : this self::Forwarding::initialize(arg)
+    ;
+}
+static field core::int/Null uninitializedTopLevel = null;
+static field core::int/core::int* {int} initializedTopLevel = 4;
+static method main() → dynamic/Null {}
diff --git a/pkg/kernel/testcases/type-propagation/void-methods.baseline.txt b/pkg/kernel/testcases/type-propagation/void-methods.baseline.txt
new file mode 100644
index 0000000..72fa578
--- /dev/null
+++ b/pkg/kernel/testcases/type-propagation/void-methods.baseline.txt
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::List<dynamic>/core::List* {other} list = <dynamic>[1, 2, 3];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  set first(dynamic/core::int* {int} x) → dynamic/Null
+    this.list.[]=(0, x);
+  operator []=(dynamic/core::int* {int} x, dynamic/core::int* {int} y) → dynamic/Null
+    this.list.[]=(x, y);
+  method clear() → void/Null
+    return this.list.clear();
+}
+static method main() → dynamic/Null {
+  new self::Foo::•().first = 4;
+  new self::Foo::•().[]=(3, 4);
+  new self::Foo::•().clear();
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 01ed03e..17e515b 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -72,6 +72,7 @@
 async/test/stream_zip_test: RuntimeError, OK # Issue 26103. Timers are not supported.
 lookup_map/test/lookup_map_test: RuntimeError, OK # Issue 26103. Timers are not supported.
 front_end/test/*: RuntimeError, OK # Issue 26103. Timers are not supported.
+kernel/test/*: RuntimeError, OK # Issue 26103. Timers are not supported.
 
 [ $compiler == dart2js && $runtime == drt ]
 async/test/stream_zip_test: RuntimeError, Pass # Issue 18548
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 56bb53a..0e75ba274 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -7,7 +7,7 @@
 declare_args() {
   # Whether to fall back to built-in root certificates when they cannot be
   # verified at the operating system level.
-  dart_use_fallback_root_certificates = false
+  dart_use_fallback_root_certificates = true
 
   # The BUILD.gn file that we pull from chromium as part of zlib has a
   # dependence on //base, which we don't pull in. In a standalone build of the
@@ -419,8 +419,6 @@
       if (is_mac) {
         libs += [ "CoreServices.framework" ]
       }
-    } else if (defined(is_fuchsia) && is_fuchsia) {
-      defines += [ "DART_IO_SECURE_SOCKET_DISABLED" ]
     } else {
       deps = [
         "//third_party/boringssl",
@@ -439,7 +437,7 @@
                  "log.h",
                ] + extra_sources
 
-    if (is_linux || is_win) {
+    if (is_linux || is_win || (defined(is_fuchsia) && is_fuchsia)) {
       if (dart_use_fallback_root_certificates) {
         sources += [ "//third_party/root_certificates/root_certificates.cc" ]
       } else {
diff --git a/runtime/bin/directory_fuchsia.cc b/runtime/bin/directory_fuchsia.cc
index 5223cb0..24ecd27 100644
--- a/runtime/bin/directory_fuchsia.cc
+++ b/runtime/bin/directory_fuchsia.cc
@@ -222,4 +222,4 @@
 }  // namespace bin
 }  // namespace dart
 
-#endif  // defined(TARGET_OS_LINUX)
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/fdutils_fuchsia.cc b/runtime/bin/fdutils_fuchsia.cc
index dd9e881..4aa4b29 100644
--- a/runtime/bin/fdutils_fuchsia.cc
+++ b/runtime/bin/fdutils_fuchsia.cc
@@ -71,8 +71,6 @@
 
 
 intptr_t FDUtils::AvailableBytes(intptr_t fd) {
-// TODO(MG-364): Enable this code when it is supported.
-#if 0
   int available;  // ioctl for FIONREAD expects an 'int*' argument.
   int result = NO_RETRY_EXPECTED(ioctl(fd, FIONREAD, &available));
   if (result < 0) {
@@ -80,9 +78,6 @@
   }
   ASSERT(available >= 0);
   return static_cast<intptr_t>(available);
-#endif
-  errno = ENOTSUP;
-  return -1;
 }
 
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 53babb7..e18f2f5 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -22,6 +22,7 @@
 #include "bin/vmservice_impl.h"
 
 #include "include/dart_api.h"
+#include "include/dart_tools_api.h"
 
 #include "platform/hashmap.h"
 #include "platform/globals.h"
@@ -684,7 +685,8 @@
 
 void StubNativeFunction(Dart_NativeArguments arguments) {
   // This is a stub function for the resolver
-  UNREACHABLE();
+  Dart_SetReturnValue(
+      arguments, Dart_NewApiError("<EMBEDDER DID NOT SETUP NATIVE RESOLVER>"));
 }
 
 
@@ -735,6 +737,27 @@
 }
 
 
+// Iterate over all libraries and setup the stub native lookup. This must be
+// run after |SetupStubNativeResolversForPrecompilation| because the former
+// loads some libraries.
+static void SetupStubNativeResolvers() {
+  Dart_Handle libraries = Dart_GetLoadedLibraries();
+  intptr_t libraries_length;
+  Dart_ListLength(libraries, &libraries_length);
+  for (intptr_t i = 0; i < libraries_length; i++) {
+    Dart_Handle library = Dart_ListGetAt(libraries, i);
+    DART_CHECK_VALID(library);
+    Dart_NativeEntryResolver old_resolver = NULL;
+    Dart_GetNativeResolver(library, &old_resolver);
+    if (old_resolver == NULL) {
+      Dart_Handle result =
+          Dart_SetNativeResolver(library, &StubNativeLookup, &StubNativeSymbol);
+      DART_CHECK_VALID(result);
+    }
+  }
+}
+
+
 static void ImportNativeEntryPointLibrariesIntoRoot(
     const Dart_QualifiedFunctionName* entries) {
   if (entries == NULL) {
@@ -995,7 +1018,7 @@
   if ((entries == NULL) && IsSnapshottingForPrecompilation()) {
     Log::PrintErr(
         "Could not find native embedder entry points during precompilation\n");
-    exit(255);
+    exit(kErrorExitCode);
   }
   return entries;
 }
@@ -1081,7 +1104,7 @@
     Log::PrintErr("%s", Dart_GetError(result));
     Dart_ExitScope();
     Dart_ShutdownIsolate();
-    exit(255);
+    exit(kErrorExitCode);
   }
   // This is a generic dart snapshot which needs builtin library setup.
   Dart_Handle library =
@@ -1101,7 +1124,7 @@
     Log::PrintErr("Errors encountered while loading: %s\n", err_msg);
     Dart_ExitScope();
     Dart_ShutdownIsolate();
-    exit(255);
+    exit(kErrorExitCode);
   }
 }
 
@@ -1166,7 +1189,7 @@
   // Parse command line arguments.
   if (ParseArguments(argc, argv, &vm_options, &app_script_name) < 0) {
     PrintUsage();
-    return 255;
+    return kErrorExitCode;
   }
 
   Thread::InitOnce();
@@ -1183,6 +1206,7 @@
 
   if (IsSnapshottingForPrecompilation()) {
     vm_options.AddArgument("--precompilation");
+    vm_options.AddArgument("--print_snapshot_sizes");
 #if TARGET_ARCH_ARM
     // This is for the iPod Touch 5th Generation (and maybe other older devices)
     vm_options.AddArgument("--no-use_integer_division");
@@ -1213,7 +1237,7 @@
   if (error != NULL) {
     Log::PrintErr("VM initialization failed: %s\n", error);
     free(error);
-    return 255;
+    return kErrorExitCode;
   }
 
   IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root,
@@ -1223,7 +1247,7 @@
   if (isolate == NULL) {
     Log::PrintErr("Error: %s", error);
     free(error);
-    exit(255);
+    exit(kErrorExitCode);
   }
 
   Dart_Handle result;
@@ -1270,15 +1294,22 @@
     intptr_t kernel_length = 0;
     const bool is_kernel_file =
         TryReadKernel(app_script_name, &kernel, &kernel_length);
+
+    void* kernel_program = NULL;
+    if (is_kernel_file) {
+      kernel_program = Dart_ReadKernelBinary(kernel, kernel_length);
+      free(const_cast<uint8_t*>(kernel));
+    }
+
     Dart_Isolate isolate =
         is_kernel_file
-            ? Dart_CreateIsolateFromKernel(NULL, NULL, kernel, kernel_length,
-                                           NULL, isolate_data, &error)
+            ? Dart_CreateIsolateFromKernel(NULL, NULL, kernel_program, NULL,
+                                           isolate_data, &error)
             : Dart_CreateIsolate(NULL, NULL, NULL, NULL, isolate_data, &error);
     if (isolate == NULL) {
-      fprintf(stderr, "%s", error);
+      Log::PrintErr("%s", error);
       free(error);
-      exit(255);
+      exit(kErrorExitCode);
     }
     Dart_EnterScope();
     result = Dart_SetEnvironmentCallback(EnvironmentCallback);
@@ -1293,8 +1324,7 @@
         ParseEntryPointsManifestIfPresent();
 
     if (is_kernel_file) {
-      Dart_Handle library = Dart_LoadKernel(kernel, kernel_length);
-      free(const_cast<uint8_t*>(kernel));
+      Dart_Handle library = Dart_LoadKernel(kernel_program);
       if (Dart_IsError(library)) FATAL("Failed to load app from Kernel IR");
     } else {
       // Set up the library tag handler in such a manner that it will use the
@@ -1305,6 +1335,8 @@
 
     SetupStubNativeResolversForPrecompilation(entry_points);
 
+    SetupStubNativeResolvers();
+
     if (!is_kernel_file) {
       // Load the specified script.
       library = LoadSnapshotCreationScript(app_script_name);
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index fdeae6c..d0a95e2 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -371,7 +371,12 @@
         dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length);
         reload_extensions = true;
       } else if (payload_type == DartUtils::kKernelMagicNumber) {
-        dart_result = Dart_LoadKernel(payload, payload_length);
+        // TODO(27590): This code path is only hit when trying to spawn
+        // isolates. We currently do not have support for neither
+        // `Isolate.spawn()` nor `Isolate.spawnUri()` with kernel-based
+        // frontend.
+        void* kernel_binary = Dart_ReadKernelBinary(payload, payload_length);
+        dart_result = Dart_LoadKernel(kernel_binary);
       } else {
         dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0);
       }
diff --git a/runtime/bin/log_android.cc b/runtime/bin/log_android.cc
index 7f68d68..42a6755 100644
--- a/runtime/bin/log_android.cc
+++ b/runtime/bin/log_android.cc
@@ -21,6 +21,7 @@
   // (critical ones or not) if we print them to stdout/stderr.
   // We also log using android's logging system.
   vprintf(format, args);
+  fflush(stdout);
   __android_log_vprint(ANDROID_LOG_INFO, "Dart", format, args);
 }
 
@@ -29,6 +30,7 @@
   // (critical ones or not) if we print them to stdout/stderr.
   // We also log using android's logging system.
   vfprintf(stderr, format, args);
+  fflush(stderr);
   __android_log_vprint(ANDROID_LOG_ERROR, "Dart", format, args);
 }
 
diff --git a/runtime/bin/log_linux.cc b/runtime/bin/log_linux.cc
index abb1983..e9dcf1c 100644
--- a/runtime/bin/log_linux.cc
+++ b/runtime/bin/log_linux.cc
@@ -19,7 +19,7 @@
 
 void Log::VPrintErr(const char* format, va_list args) {
   vfprintf(stderr, format, args);
-  fflush(stdout);
+  fflush(stderr);
 }
 
 }  // namespace bin
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 21fde13..0adf4ac 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -108,7 +108,7 @@
 static Dart_Isolate main_isolate = NULL;
 
 
-static const char* DEFAULT_VM_SERVICE_SERVER_IP = "127.0.0.1";
+static const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
 static const int DEFAULT_VM_SERVICE_SERVER_PORT = 8181;
 // VM Service options.
 static const char* vm_service_server_ip = DEFAULT_VM_SERVICE_SERVER_IP;
@@ -133,7 +133,6 @@
   va_start(arguments, format);
   Log::VPrintErr(format, arguments);
   va_end(arguments);
-  fflush(stderr);
 
   Dart_ExitScope();
   Dart_ShutdownIsolate();
@@ -223,17 +222,18 @@
 }
 
 
-static bool ExtractPortAndIP(const char* option_value,
-                             int* out_port,
-                             const char** out_ip,
-                             int default_port,
-                             const char* default_ip) {
+static bool ExtractPortAndAddress(const char* option_value,
+                                  int* out_port,
+                                  const char** out_ip,
+                                  int default_port,
+                                  const char* default_ip) {
   // [option_value] has to be one of the following formats:
   //   - ""
   //   - ":8181"
   //   - "=8181"
   //   - ":8181/192.168.0.1"
   //   - "=8181/192.168.0.1"
+  //   - "=8181/::1"
 
   if (*option_value == '\0') {
     *out_ip = default_ip;
@@ -253,16 +253,9 @@
     return true;
   }
 
-  int _, n;
-  if (sscanf(option_value + 1, "%d/%d.%d.%d.%d%n",  // NOLINT(runtime/printf)
-             &_, &_, &_, &_, &_, &n)) {
-    if (option_value[1 + n] == '\0') {
-      *out_ip = slash + 1;
-      *out_port = port;
-      return true;
-    }
-  }
-  return false;
+  *out_ip = slash + 1;
+  *out_port = port;
+  return true;
 }
 
 
@@ -376,12 +369,12 @@
                                          CommandLineOptions* vm_options) {
   ASSERT(option_value != NULL);
 
-  if (!ExtractPortAndIP(option_value, &vm_service_server_port,
-                        &vm_service_server_ip, DEFAULT_VM_SERVICE_SERVER_PORT,
-                        DEFAULT_VM_SERVICE_SERVER_IP)) {
+  if (!ExtractPortAndAddress(
+          option_value, &vm_service_server_port, &vm_service_server_ip,
+          DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
     Log::PrintErr(
         "unrecognized --enable-vm-service option syntax. "
-        "Use --enable-vm-service[=<port number>[/<IPv4 address>]]\n");
+        "Use --enable-vm-service[=<port number>[/<bind address>]]\n");
     return false;
   }
 
@@ -405,12 +398,12 @@
                                  CommandLineOptions* vm_options) {
   ASSERT(option_value != NULL);
 
-  if (!ExtractPortAndIP(option_value, &vm_service_server_port,
-                        &vm_service_server_ip, DEFAULT_VM_SERVICE_SERVER_PORT,
-                        DEFAULT_VM_SERVICE_SERVER_IP)) {
+  if (!ExtractPortAndAddress(
+          option_value, &vm_service_server_port, &vm_service_server_ip,
+          DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
     Log::PrintErr(
         "unrecognized --observe option syntax. "
-        "Use --observe[=<port number>[/<IPv4 address>]]\n");
+        "Use --observe[=<port number>[/<bind address>]]\n");
     return false;
   }
 
@@ -807,18 +800,19 @@
       !run_app_snapshot &&
       TryReadKernel(script_uri, &kernel_file, &kernel_length);
 
-  IsolateData* isolate_data =
-      new IsolateData(script_uri, package_root, packages_config);
-  Dart_Isolate isolate =
-      is_kernel ? Dart_CreateIsolateFromKernel(script_uri, main, kernel_file,
-                                               kernel_length, flags,
-                                               isolate_data, error)
-                : Dart_CreateIsolate(script_uri, main, isolate_snapshot_buffer,
-                                     flags, isolate_data, error);
+  void* kernel_program = NULL;
   if (is_kernel) {
+    kernel_program = Dart_ReadKernelBinary(kernel_file, kernel_length);
     free(const_cast<uint8_t*>(kernel_file));
   }
 
+  IsolateData* isolate_data =
+      new IsolateData(script_uri, package_root, packages_config);
+  Dart_Isolate isolate =
+      is_kernel ? Dart_CreateIsolateFromKernel(script_uri, main, kernel_program,
+                                               flags, isolate_data, error)
+                : Dart_CreateIsolate(script_uri, main, isolate_snapshot_buffer,
+                                     flags, isolate_data, error);
   if (isolate == NULL) {
     delete isolate_data;
     return NULL;
@@ -831,12 +825,7 @@
   CHECK_RESULT(result);
 
   if (is_kernel) {
-    // TODO(27590): We should not read the kernel file again!
-    if (!TryReadKernel(script_uri, &kernel_file, &kernel_length)) {
-      FATAL("Failed to read kernel second time");
-    }
-    Dart_Handle result = Dart_LoadKernel(kernel_file, kernel_length);
-    free(const_cast<uint8_t*>(kernel_file));
+    Dart_Handle result = Dart_LoadKernel(kernel_program);
     CHECK_RESULT(result);
   }
   if (is_kernel || (isolate_snapshot_buffer != NULL)) {
@@ -1030,7 +1019,7 @@
 "\n"
 "--enable-vm-service[=<port>[/<bind-address>]]\n"
 "  enables the VM service and listens on specified port for connections\n"
-"  (default port number is 8181, default bind address is 127.0.0.1).\n"
+"  (default port number is 8181, default bind address is localhost).\n"
 #if !defined(TARGET_OS_MACOS)
 "\n"
 "--root-certs-file=<path>\n"
@@ -1240,14 +1229,23 @@
     return false;
   }
 
+  int64_t vmisolate_size = header[1];
   int64_t vmisolate_position =
       Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
+  int64_t isolate_size = header[2];
   int64_t isolate_position =
-      Utils::RoundUp(vmisolate_position + header[1], kAppSnapshotPageSize);
-  int64_t rodata_position =
-      Utils::RoundUp(isolate_position + header[2], kAppSnapshotPageSize);
-  int64_t instructions_position =
-      Utils::RoundUp(rodata_position + header[3], kAppSnapshotPageSize);
+      Utils::RoundUp(vmisolate_position + vmisolate_size, kAppSnapshotPageSize);
+  int64_t rodata_size = header[3];
+  int64_t rodata_position = isolate_position + isolate_size;
+  if (rodata_size != 0) {
+    rodata_position = Utils::RoundUp(rodata_position, kAppSnapshotPageSize);
+  }
+  int64_t instructions_size = header[4];
+  int64_t instructions_position = rodata_position + rodata_size;
+  if (instructions_size != 0) {
+    instructions_position =
+        Utils::RoundUp(instructions_position, kAppSnapshotPageSize);
+  }
 
   void* read_only_buffer =
       file->Map(File::kReadOnly, vmisolate_position,
@@ -1261,14 +1259,14 @@
                       (vmisolate_position - vmisolate_position);
   *isolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer) +
                     (isolate_position - vmisolate_position);
-  if (header[3] == 0) {
+  if (rodata_size == 0) {
     *rodata_buffer = NULL;
   } else {
     *rodata_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer) +
                      (rodata_position - vmisolate_position);
   }
 
-  if (header[4] == 0) {
+  if (instructions_size == 0) {
     *instructions_buffer = NULL;
   } else {
     *instructions_buffer = reinterpret_cast<const uint8_t*>(
@@ -1589,9 +1587,8 @@
       // Load the embedder's portion of the VM service's Dart code so it will
       // be included in the app snapshot.
       if (!VmService::LoadForGenPrecompiled()) {
-        fprintf(stderr, "VM service loading failed: %s\n",
-                VmService::GetErrorMessage());
-        fflush(stderr);
+        Log::PrintErr("VM service loading failed: %s\n",
+                      VmService::GetErrorMessage());
         exit(kErrorExitCode);
       }
     }
@@ -1839,8 +1836,7 @@
 
   if (!DartUtils::SetOriginalWorkingDirectory()) {
     OSError err;
-    fprintf(stderr, "Error determining current directory: %s\n", err.message());
-    fflush(stderr);
+    Log::PrintErr("Error determining current directory: %s\n", err.message());
     Platform::Exit(kErrorExitCode);
   }
 
@@ -1901,8 +1897,7 @@
   char* error = Dart_Initialize(&init_params);
   if (error != NULL) {
     EventHandler::Stop();
-    fprintf(stderr, "VM initialization failed: %s\n", error);
-    fflush(stderr);
+    Log::PrintErr("VM initialization failed: %s\n", error);
     free(error);
     Platform::Exit(kErrorExitCode);
   }
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 9c12c19..0d3338c 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -22,6 +22,12 @@
 int Platform::script_index_ = 1;
 char** Platform::argv_ = NULL;
 
+static void segv_handler(int signal, siginfo_t* siginfo, void* context) {
+  Dart_DumpNativeStackTrace(context);
+  abort();
+}
+
+
 bool Platform::Initialize() {
   // Turn off the signal handler for SIGPIPE as it causes the process
   // to terminate on writing to a closed pipe. Without the signal
@@ -33,6 +39,21 @@
     perror("Setting signal handler failed");
     return false;
   }
+
+  act.sa_flags = SA_SIGINFO;
+  act.sa_sigaction = &segv_handler;
+  if (sigemptyset(&act.sa_mask) != 0) {
+    perror("sigemptyset() failed.");
+    return false;
+  }
+  if (sigaddset(&act.sa_mask, SIGPROF) != 0) {
+    perror("sigaddset() failed");
+    return false;
+  }
+  if (sigaction(SIGSEGV, &act, NULL) != 0) {
+    perror("sigaction() failed.");
+    return false;
+  }
   return true;
 }
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 35e9107..0c6de4d 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -28,6 +28,12 @@
 int Platform::script_index_ = 1;
 char** Platform::argv_ = NULL;
 
+static void segv_handler(int signal, siginfo_t* siginfo, void* context) {
+  Dart_DumpNativeStackTrace(context);
+  abort();
+}
+
+
 bool Platform::Initialize() {
   // Turn off the signal handler for SIGPIPE as it causes the process
   // to terminate on writing to a closed pipe. Without the signal
@@ -39,6 +45,20 @@
     perror("Setting signal handler failed");
     return false;
   }
+  act.sa_flags = SA_SIGINFO;
+  act.sa_sigaction = &segv_handler;
+  if (sigemptyset(&act.sa_mask) != 0) {
+    perror("sigemptyset() failed.");
+    return false;
+  }
+  if (sigaddset(&act.sa_mask, SIGPROF) != 0) {
+    perror("sigaddset() failed");
+    return false;
+  }
+  if (sigaction(SIGSEGV, &act, NULL) != 0) {
+    perror("sigaction() failed.");
+    return false;
+  }
   return true;
 }
 
diff --git a/runtime/bin/secure_socket.h b/runtime/bin/secure_socket.h
index 1af6197..543820b 100644
--- a/runtime/bin/secure_socket.h
+++ b/runtime/bin/secure_socket.h
@@ -11,7 +11,7 @@
 
 #include "platform/globals.h"
 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) ||                  \
-    defined(TARGET_OS_WINDOWS)
+    defined(TARGET_OS_WINDOWS) || defined(TARGET_OS_FUCHSIA)
 #include "bin/secure_socket_boringssl.h"
 #elif defined(TARGET_OS_MACOS)
 #if TARGET_OS_IOS
diff --git a/runtime/bin/secure_socket_boringssl.cc b/runtime/bin/secure_socket_boringssl.cc
index 68d68ee..6e3b7fc 100644
--- a/runtime/bin/secure_socket_boringssl.cc
+++ b/runtime/bin/secure_socket_boringssl.cc
@@ -6,7 +6,7 @@
 
 #include "platform/globals.h"
 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) ||                  \
-    defined(TARGET_OS_WINDOWS)
+    defined(TARGET_OS_WINDOWS) || defined(TARGET_OS_FUCHSIA)
 
 #include "bin/secure_socket.h"
 #include "bin/secure_socket_boringssl.h"
@@ -766,6 +766,9 @@
 
 static void AddCompiledInCerts(SSLContext* context) {
   if (root_certificates_pem == NULL) {
+    if (SSL_LOG_STATUS) {
+      Log::Print("Missing compiled-in roots\n");
+    }
     return;
   }
   X509_STORE* store = SSL_CTX_get_cert_store(context->context());
@@ -800,7 +803,7 @@
     ThrowIOException(-1, "TlsException", "Failed to find root cert file");
   }
   int status = SSL_CTX_load_verify_locations(context->context(), file, NULL);
-  CheckStatus(status, "TlsException", "Failure trusting builtint roots");
+  CheckStatus(status, "TlsException", "Failure trusting builtin roots");
   if (SSL_LOG_STATUS) {
     Log::Print("Trusting roots from: %s\n", file);
   }
@@ -815,7 +818,7 @@
     ThrowIOException(-1, "TlsException", "Failed to find root cert cache");
   }
   int status = SSL_CTX_load_verify_locations(context->context(), NULL, cache);
-  CheckStatus(status, "TlsException", "Failure trusting builtint roots");
+  CheckStatus(status, "TlsException", "Failure trusting builtin roots");
   if (SSL_LOG_STATUS) {
     Log::Print("Trusting roots from: %s\n", cache);
   }
@@ -869,10 +872,10 @@
 
   // Fall back on the compiled-in certs if the standard locations don't exist,
   // or we aren't on Linux.
-  AddCompiledInCerts(context);
   if (SSL_LOG_STATUS) {
     Log::Print("Trusting compiled-in roots\n");
   }
+  AddCompiledInCerts(context);
 }
 
 
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 17f5641..b0e384c 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -551,7 +551,7 @@
     Dart_ListSetAt(entry, 1, Dart_NewStringFromCString(addr->as_string()));
 
     RawAddr raw = addr->addr();
-    intptr_t data_length = SocketAddress::GetAddrLength(raw);
+    intptr_t data_length = SocketAddress::GetInAddrLength(raw);
     Dart_Handle data = Dart_NewTypedData(Dart_TypedData_kUint8, data_length);
     Dart_ListSetAsBytes(data, 0, reinterpret_cast<uint8_t*>(&raw), data_length);
     Dart_ListSetAt(entry, 2, data);
diff --git a/runtime/bin/socket_fuchsia.cc b/runtime/bin/socket_fuchsia.cc
index a6498ce..2443ee3 100644
--- a/runtime/bin/socket_fuchsia.cc
+++ b/runtime/bin/socket_fuchsia.cc
@@ -95,39 +95,11 @@
 }
 
 
-static intptr_t CheckConnect(intptr_t fd) {
-  int val;
-  socklen_t vallen = sizeof(val);
-  LOG_INFO("CheckConnect: calling getsockopt(%ld)\n", fd);
-  intptr_t result = getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &vallen);
-  if (result != 0) {
-    FATAL1("CheckConnect: getsockopt(%ld) failed\n", fd);
-  } else if (vallen != sizeof(val)) {
-    FATAL1("CheckConnect: getsockopt(%ld) vallen != sizeof(val)!?!?\n", fd);
-  } else if (val != 0) {
-    LOG_ERR("CheckConnect: getsockopt(%ld) val = %d\n", fd, val);
-    return val;
-  }
-  LOG_INFO("CheckConnect: getsockopt(%ld) connected\n", fd);
-  return 0;
-}
-
-
 static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
   LOG_INFO("Connect: calling connect(%ld)\n", fd);
   intptr_t result = NO_RETRY_EXPECTED(
       connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr)));
   if ((result == 0) || (errno == EINPROGRESS)) {
-    LOG_INFO("Connect: connect(%ld) succeeded\n", fd);
-    intptr_t error = 0;
-    // TODO(US-87): When the issue is resolved this check is no longer needed.
-    while ((error = CheckConnect(fd)) != 0) {
-      if (error != EINPROGRESS) {
-        errno = error;
-        FDUtils::SaveErrorAndClose(fd);
-        return -1;
-      }
-    }
     return fd;
   }
   LOG_ERR("Connect: connect(%ld) failed\n", fd);
@@ -242,9 +214,14 @@
 
 
 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) {
-  LOG_ERR("Socket::GetRemotePeer is unimplemented\n");
-  UNIMPLEMENTED();
-  return NULL;
+  ASSERT(fd >= 0);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
+  if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
+    return NULL;
+  }
+  *port = SocketAddress::GetAddrPort(raw);
+  return new SocketAddress(&raw.addr);
 }
 
 
@@ -324,9 +301,15 @@
 
 
 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) {
-  LOG_ERR("Socket::ParseAddress is unimplemented\n");
-  UNIMPLEMENTED();
-  return false;
+  int result;
+  if (type == SocketAddress::TYPE_IPV4) {
+    result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr));
+  } else {
+    ASSERT(type == SocketAddress::TYPE_IPV6);
+    result =
+        NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr));
+  }
+  return (result == 1);
 }
 
 
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 8262053..9a48adf 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -134,11 +134,8 @@
     }
     var ip = _server.address.address;
     var port = _server.port;
-    if (useAuthToken) {
-      return Uri.parse('http://$ip:$port/$serviceAuthToken/');
-    } else {
-      return Uri.parse('http://$ip:$port/');
-    }
+    var path = useAuthToken ? "$serviceAuthToken/" : "/";
+    return new Uri(scheme: 'http', host: ip, port: port, path: path);
   }
 
   Server(this._service, this._ip, this._port, this._originCheckDisabled);
@@ -154,6 +151,7 @@
     // Explicitly add localhost and 127.0.0.1 on any port (necessary for
     // adb port forwarding).
     if ((uri.host == 'localhost') ||
+        (uri.host == '::1') ||
         (uri.host == '127.0.0.1')) {
       return true;
     }
@@ -300,28 +298,34 @@
     }
   }
 
-  Future startup() {
+  Future startup() async {
     if (_server != null) {
       // Already running.
-      return new Future.value(this);
+      return this;
     }
 
-    var address = new InternetAddress(_ip);
     // Startup HTTP server.
-    return HttpServer.bind(address, _port).then((s) {
-      _server = s;
+    try {
+      var addresses = await InternetAddress.lookup(_ip);
+      var address;
+      // Prefer IPv4 addresses.
+      for (var i = 0; i < addresses.length; i++) {
+        address = addresses[i];
+        if (address.type == InternetAddressType.IP_V4) break;
+      }
+      _server = await HttpServer.bind(address, _port);
       _server.listen(_requestHandler, cancelOnError: true);
       print('Observatory listening on $serverAddress');
       // Server is up and running.
       _notifyServerState(serverAddress.toString());
       onServerAddressChange('$serverAddress');
       return this;
-    }).catchError((e, st) {
+    } catch (e, st) {
       print('Could not start Observatory HTTP server:\n$e\n$st\n');
       _notifyServerState("");
       onServerAddressChange(null);
       return this;
-    });
+    }
   }
 
   Future cleanup(bool force) {
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index a085a72..93d6da5 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -890,12 +890,14 @@
  *
  * Requires there to be no current isolate.
  *
+ * After this call, the `kernel_program` needs to be supplied to a call to
+ * `Dart_LoadKernel()` which will then take ownership of the memory.
+ *
  * \param script_uri The name of the script this isolate will load.
  *   Provided only for advisory purposes to improve debugging messages.
  * \param main The name of the main entry point this isolate will run.
  *   Provided only for advisory purposes to improve debugging messages.
- * \param kernel A buffer containing the Dart Kernel binary.
- * \param kernel_length The length of the Kernel buffer.
+ * \param kernel_program The `dart::kernel::Program` object.
  * \param flags Pointer to VM specific flags or NULL for default flags.
  * \param callback_data Embedder data.  This data will be passed to
  *   the Dart_IsolateCreateCallback when new isolates are spawned from
@@ -907,8 +909,7 @@
  */
 DART_EXPORT Dart_Isolate Dart_CreateIsolateFromKernel(const char* script_uri,
                                                       const char* main,
-                                                      const uint8_t* kernel,
-                                                      intptr_t kernel_length,
+                                                      void* kernel_program,
                                                       Dart_IsolateFlags* flags,
                                                       void* callback_data,
                                                       char** error);
@@ -2703,6 +2704,30 @@
 /* TODO(turnidge): Rename to Dart_LibrarySetNativeResolver? */
 
 
+/**
+ * Returns the callback used to resolve native functions for a library.
+ *
+ * \param library A library.
+ * \param resolver a pointer to a Dart_NativeEntryResolver
+ *
+ * \return A valid handle if the library was found.
+ */
+DART_EXPORT Dart_Handle
+Dart_GetNativeResolver(Dart_Handle library, Dart_NativeEntryResolver* resolver);
+
+
+/**
+ * Returns the callback used to resolve native function symbols for a library.
+ *
+ * \param library A library.
+ * \param resolver a pointer to a Dart_NativeEntrySymbol.
+ *
+ * \return A valid handle if the library was found.
+ */
+DART_EXPORT Dart_Handle Dart_GetNativeSymbol(Dart_Handle library,
+                                             Dart_NativeEntrySymbol* resolver);
+
+
 /*
  * =====================
  * Scripts and Libraries
@@ -2839,15 +2864,28 @@
                                                     intptr_t buffer_len);
 
 /**
- * Loads a dart application which was compiled to a Kernel binary.
+ * Loads a dart application via an in-memory kernel program.
  *
- * \param buffer A buffer which contains a Kernel binary.
- * \param buffer_len Length of the passed in buffer.
+ * \param kernel_program The kernel program obtained via
+ *        `Dart_ReadKernelBinary`.
+ *
+ * The VM will take ownership of the `kernel_program` object.
  *
  * \return If no error occurs, the Library object corresponding to the root
  *   script is returned. Otherwise an error handle is returned.
  */
-DART_EXPORT Dart_Handle Dart_LoadKernel(const uint8_t* buffer,
+DART_EXPORT Dart_Handle Dart_LoadKernel(void* kernel_program);
+
+
+/**
+ * Constructs an in-memory kernel program form a binary.
+ *
+ * \param buffer The start of a memory buffer containing the binary format.
+ * \param buffer_len The length of the memory buffer.
+ *
+ * \return kernel_program The `dart::kernel::Program` object.
+ */
+DART_EXPORT void* Dart_ReadKernelBinary(const uint8_t* buffer,
                                         intptr_t buffer_len);
 
 /**
@@ -2907,6 +2945,13 @@
  */
 DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library);
 
+
+/**
+ * \return An array of libraries.
+ */
+DART_EXPORT Dart_Handle Dart_GetLoadedLibraries();
+
+
 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url);
 /* TODO(turnidge): Consider returning Dart_Null() when the library is
  * not found to distinguish that from a true error case. */
@@ -3236,4 +3281,10 @@
  */
 DART_EXPORT bool Dart_IsPrecompiledRuntime();
 
+
+/**
+ *  Print a native stack trace. Used for crash handling.
+ */
+DART_EXPORT void Dart_DumpNativeStackTrace(void* context);
+
 #endif /* INCLUDE_DART_API_H_ */ /* NOLINT */
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index e62524b..f834394 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -33,7 +33,7 @@
   }
 
   @patch factory List.from(Iterable elements, { bool growable: true }) {
-    if (elements is EfficientLength) {
+    if (elements is EfficientLengthIterable) {
       int length = elements.length;
       var list = growable ? new _GrowableList<E>(length) : new _List<E>(length);
       if (length > 0) {  // Avoid creating iterator unless necessary.
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index 0dea145..f7cd33d 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -435,8 +435,7 @@
   _HashMapEntry(this.key, this.value, this.hashCode, this.next);
 }
 
-abstract class _HashMapIterable<E> extends IterableBase<E>
-                                   implements EfficientLength {
+abstract class _HashMapIterable<E> extends EfficientLengthIterable<E> {
   final HashMap _map;
   _HashMapIterable(this._map);
   int get length => _map.length;
@@ -838,8 +837,7 @@
   }
 }
 
-class _LinkedHashMapKeyIterable<K> extends IterableBase<K>
-                                   implements EfficientLength {
+class _LinkedHashMapKeyIterable<K> extends EfficientLengthIterable<K> {
   LinkedHashMap<K, dynamic> _map;
   _LinkedHashMapKeyIterable(this._map);
   Iterator<K> get iterator => new _LinkedHashMapKeyIterator<K>(_map);
@@ -850,8 +848,7 @@
   Set<K> toSet() => _map._newKeySet()..addAll(this);
 }
 
-class _LinkedHashMapValueIterable<V> extends IterableBase<V>
-                                     implements EfficientLength {
+class _LinkedHashMapValueIterable<V> extends EfficientLengthIterable<V> {
   LinkedHashMap<dynamic, V> _map;
   _LinkedHashMapValueIterable(this._map);
   Iterator<V> get iterator => new _LinkedHashMapValueIterator<V>(_map);
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 9e942e4..d35c1c4 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -174,7 +174,7 @@
         (cid == ClassID.cidArray) ||
         (cid == ClassID.cidGrowableObjectArray) ||
         (cid == ClassID.cidImmutableArray);
-    if (isVMList || (iterable is EfficientLength)) {
+    if (isVMList || (iterable is EfficientLengthIterable)) {
       var cap = _capacity;
       // Pregrow if we know iterable.length.
       var iterLen = iterable.length;
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index b8d0d3c..ba866e3 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -85,8 +85,7 @@
   }
 }
 
-class _ImmutableMapKeyIterable<E> extends IterableBase<E>
-                                  implements EfficientLength {
+class _ImmutableMapKeyIterable<E> extends EfficientLengthIterable<E> {
   final ImmutableMap _map;
   _ImmutableMapKeyIterable(this._map);
 
@@ -97,8 +96,7 @@
   int get length => _map.length;
 }
 
-class _ImmutableMapValueIterable<E> extends IterableBase<E>
-                                    implements EfficientLength {
+class _ImmutableMapValueIterable<E> extends EfficientLengthIterable<E> {
   final ImmutableMap _map;
   _ImmutableMapValueIterable(this._map);
 
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 5abad66..f046d8f 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -155,7 +155,7 @@
   static String _createStringFromIterable(Iterable<int> charCodes,
                                           int start, int end) {
     // Treat charCodes as Iterable.
-    if (charCodes is EfficientLength) {
+    if (charCodes is EfficientLengthIterable) {
       int length = charCodes.length;
       end = RangeError.checkValidRange(start, end, length);
       List charCodeList = new List.from(charCodes.take(end).skip(start),
diff --git a/runtime/observatory/tests/service/auth_token1_test.dart b/runtime/observatory/tests/service/auth_token1_test.dart
index 5afb263..134047a 100644
--- a/runtime/observatory/tests/service/auth_token1_test.dart
+++ b/runtime/observatory/tests/service/auth_token1_test.dart
@@ -21,7 +21,7 @@
 
   // Try connecting to the server without the auth token, it should succeed.
   var port = info.serverUri.port;
-  var url = Uri.parse('http://127.0.0.1:$port');
+  var url = Uri.parse('http://localhost:$port');
   var httpClient = new io.HttpClient();
   try {
     var request = await httpClient.getUrl(url);
diff --git a/runtime/observatory/tests/service/auth_token_test.dart b/runtime/observatory/tests/service/auth_token_test.dart
index 6d38fca..69c162b 100644
--- a/runtime/observatory/tests/service/auth_token_test.dart
+++ b/runtime/observatory/tests/service/auth_token_test.dart
@@ -24,7 +24,7 @@
   // Try connecting to the server without the auth token, it should throw
   // an exception.
   var port = info.serverUri.port;
-  var url = Uri.parse('http://127.0.0.1:$port');
+  var url = Uri.parse('http://localhost:$port');
   var httpClient = new io.HttpClient();
   try {
     var request = await httpClient.getUrl(url);
diff --git a/runtime/observatory/tests/service/get_allocation_samples_test.dart b/runtime/observatory/tests/service/get_allocation_samples_test.dart
index d26c75f..bf4e199 100644
--- a/runtime/observatory/tests/service/get_allocation_samples_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_samples_test.dart
@@ -67,8 +67,8 @@
     cpuProfile.buildFunctionCallerAndCallees();
     var tree = cpuProfile.loadCodeTree(M.ProfileTreeDirection.exclusive);
     var node = tree.root;
-    var expected =
-        ['Root', 'DRT_AllocateObject', 'test', 'test', '_Closure.call'];
+    var expected = ['Root', 'DRT_AllocateObject', '[Stub] Allocate Foo',
+                    'test', 'test', '_Closure.call'];
     for (var i = 0; i < expected.length; i++) {
       expect(node.profileCode.code.name, equals(expected[i]));
       // Depth first traversal.
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index bb0c433..ccbcbcc 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -7,6 +7,7 @@
 gc_test: Pass, RuntimeError # Issue 26490
 pause_on_start_and_exit_test: Pass, RuntimeError # Issue 26470
 pause_on_start_then_step_test: Pass, RuntimeError # Issue 26470
+get_allocation_samples_test: Pass, RuntimeError # Inconsistent stack trace
 # Reload is slow on the bots
 reload_sources_test: Pass, Slow
 
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 9e8caa8..a722876 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -281,7 +281,7 @@
 
 void setupAddresses(Uri serverAddress) {
   serviceWebsocketAddress =
-          'ws://${serverAddress.authority}${serverAddress.path}ws';
+      'ws://${serverAddress.authority}${serverAddress.path}ws';
   serviceHttpAddress =
       'http://${serverAddress.authority}${serverAddress.path}';
 }
diff --git a/runtime/platform/assert.cc b/runtime/platform/assert.cc
index 49c6bec..7929b27 100644
--- a/runtime/platform/assert.cc
+++ b/runtime/platform/assert.cc
@@ -38,7 +38,7 @@
   // until the program is exiting before producing a non-zero exit
   // code through abort.
   if (kind_ == ASSERT) {
-    NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /* native_stack_trace */));
+    NOT_IN_PRODUCT(Profiler::DumpStackTrace());
     OS::Abort();
   }
   failed_ = true;
diff --git a/runtime/tests/vm/dart/hello_fuchsia_test.dart b/runtime/tests/vm/dart/hello_fuchsia_test.dart
index 9ed439b..e2ac092 100644
--- a/runtime/tests/vm/dart/hello_fuchsia_test.dart
+++ b/runtime/tests/vm/dart/hello_fuchsia_test.dart
@@ -5,6 +5,20 @@
 import "dart:async";
 import "dart:io";
 
+testAddressParse() async {
+  print(new InternetAddress("1.0.2.3").rawAddress);
+  print(new InternetAddress("1.0.2.3").type);
+
+  print(new InternetAddress("::1").rawAddress);
+  print(new InternetAddress("::1").type);
+
+  try {
+    print(new InternetAddress("localhost"));
+  } catch (e) {
+    print(e);
+  }
+}
+
 testSimpleBind() async {
   var s = await RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
   print("port = ${s.port}");
@@ -20,11 +34,156 @@
   });
   var socket = await RawSocket.connect("127.0.0.1", server.port);
   print("socket port = ${socket.port}");
+  if (socket.remoteAddress.address != "127.0.0.1" ||
+      socket.remoteAddress.type != InternetAddressType.IP_V4) {
+    throw "Bad remote address ${socket.remoteAddress}";
+  }
+  if (socket.remotePort is! int) {
+    throw "Bad remote port ${socket.remotePort}";
+  }
   await server.close();
   await socket.close();
 }
 
-testSimpleReadWrite({bool dropReads}) async {
+testSimpleReadWriteClose() async {
+  // This test creates a server and a client connects. The client then
+  // writes and the server echos. When the client finishes fully reading the
+  // echo, it closes the socket. When the server receives the close event, it
+  // closes its end of the socket too.
+
+  const messageSize = 1000;
+  int serverReadCount = 0;
+  int clientReadCount = 0;
+
+  List<int> createTestData() {
+    return new List<int>.generate(messageSize, (index) => index & 0xff);
+  }
+
+  void verifyTestData(List<int> data) {
+    assert(messageSize == data.length);
+    List<int> expected = createTestData();
+    for (int i = 0; i < messageSize; i++) {
+      assert(expected[i] == data[i]);
+    }
+  }
+
+  var server = await RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
+  server.listen((client) {
+    int bytesRead = 0;
+    int bytesWritten = 0;
+    bool closedEventReceived = false;
+    List<int> data = new List<int>(messageSize);
+    bool doneReading = false;
+
+    client.writeEventsEnabled = false;
+    client.listen((event) {
+      switch (event) {
+        case RawSocketEvent.READ:
+          if (doneReading) {
+            break;
+          }
+          print("client READ event bytesRead = $bytesRead");
+          assert(bytesWritten == 0);
+          assert(client.available() > 0);
+          var buffer = client.read(200);
+          print("client READ event: read ${buffer.length} more bytes");
+          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
+          bytesRead += buffer.length;
+          if (bytesRead == data.length) {
+            verifyTestData(data);
+            print("client READ event. Done reading, enabling writes");
+            client.writeEventsEnabled = true;
+            doneReading = true;
+          }
+          break;
+        case RawSocketEvent.WRITE:
+          assert(!client.writeEventsEnabled);
+          bytesWritten += client.write(
+              data, bytesWritten, data.length - bytesWritten);
+          print("client WRITE event: $bytesWritten written");
+          if (bytesWritten < data.length) {
+            client.writeEventsEnabled = true;
+          }
+          if (bytesWritten == data.length) {
+            print("client WRITE event: done writing.");
+          }
+          break;
+        case RawSocketEvent.READ_CLOSED:
+          print("client READ_CLOSED event");
+          client.close();
+          server.close();
+          break;
+        case RawSocketEvent.CLOSED:
+          assert(!closedEventReceived);
+          print("client CLOSED event");
+          closedEventReceived = true;
+          break;
+        default: throw "Unexpected event $event";
+      }
+    },
+    onError: (e) { print("client ERROR $e"); },
+    onDone: () {assert(closedEventReceived);});
+  });
+
+  {
+    var completer = new Completer();
+    var socket = await RawSocket.connect("127.0.0.1", server.port);
+    int bytesRead = 0;
+    int bytesWritten = 0;
+    bool closedEventReceived = false;
+    List<int> data = createTestData();
+
+    socket.listen((event) {
+      switch (event) {
+        case RawSocketEvent.READ:
+          assert(socket.available() > 0);
+          print("server READ event: ${bytesRead} read");
+          var buffer = socket.read();
+          print("server READ event: read ${buffer.length} more bytes");
+          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
+          bytesRead += buffer.length;
+          if (bytesRead == messageSize) {
+            print("server READ event: done reading");
+            socket.close();
+          }
+          break;
+        case RawSocketEvent.WRITE:
+          assert(bytesRead == 0);
+          assert(!socket.writeEventsEnabled);
+          bytesWritten += socket.write(
+              data, bytesWritten, data.length - bytesWritten);
+          print("server WRITE event: ${bytesWritten} written");
+          if (bytesWritten < data.length) {
+            socket.writeEventsEnabled = true;
+          } else {
+            print("server WRITE event: done writing");
+            data = new List<int>(messageSize);
+          }
+          break;
+        case RawSocketEvent.READ_CLOSED:
+          print("server READ_CLOSED event");
+          verifyTestData(data);
+          socket.close();
+          break;
+        case RawSocketEvent.CLOSED:
+          assert(!closedEventReceived);
+          print("server CLOSED event");
+          closedEventReceived = true;
+          break;
+        default: throw "Unexpected event $event";
+      }
+    },
+    onError: (e) { print("server ERROR $e"); },
+    onDone: () {
+      assert(closedEventReceived);
+      completer.complete(null);
+    });
+
+    return completer.future;
+  }
+}
+
+testSimpleReadWriteShutdown({bool dropReads}) async {
   // This test creates a server and a client connects. The client then
   // writes and the server echos. When the server has finished its
   // echo it half-closes. When the client gets the close event is
@@ -172,14 +331,39 @@
   }
 }
 
-Future testGoogleUrl(SecurityContext context, String outcome) async {
+Future testGoogleHttp(SecurityContext context, String outcome) async {
+  var client = new HttpClient(context: context);
+  try {
+    // First, check if the lookup works.
+    var address = await InternetAddress.lookup('www.google.com');
+    print(address);
+    var request = await client.getUrl(Uri.parse('http://www.google.com/'));
+    request.followRedirects = false;
+    var response = await request.close();
+    assert('pass' == outcome);
+    try { await response.drain(); } catch (e) {
+      print('drain failed: $e');
+    }
+  } catch (e) {
+    // Lookup failed or connection failed.  Don't report a failure.
+    print("SocketException: $e");
+  } finally {
+    client.close();
+  }
+}
+
+Future testGoogleHttps(SecurityContext context, String outcome) async {
+  // If this isn't reasonable, the certificate will be rejected.
+  print(new DateTime.now());
+
   var client = new HttpClient(context: context);
   // We need to use an external server that is backed by a
   // built-in root certificate authority.
   try {
     // First, check if the lookup works.
-    await InternetAddress.lookup('www.google.com');
-    var request = await client.getUrl(Uri.parse('http://www.google.com'));
+    var address = await InternetAddress.lookup('www.google.com');
+    print(address);
+    var request = await client.getUrl(Uri.parse('https://www.google.com/'));
     request.followRedirects = false;
     var response = await request.close();
     assert('pass' == outcome);
@@ -197,6 +381,10 @@
 main() async {
   print("Hello, Fuchsia!");
 
+  print("testAddressParse");
+  await testAddressParse();
+  print("testAddressParse done");
+
   print("testSimpleBind");
   await testSimpleBind();
   print("testSimpleBind done");
@@ -205,13 +393,23 @@
   await testSimpleConnect();
   print("testSimpleConnect done");
 
-  // print("testSimpleReadWrite");
-  // await testSimpleReadWrite(dropReads: false);
-  // print("testSimpleReadWrite done");
+  print("testSimpleReadWriteClose");
+  await testSimpleReadWriteClose();
+  print("testSimpleReadWriteClose done");
 
-  // print("testGoogleUrl");
-  // await testGoogleUrl(null, 'pass');
-  // print("testGoogleUrl done");
+  // TODO(US-81): Enable.
+  // print("testSimpleReadWriteShutdown");
+  // await testSimpleReadWriteShutdown(dropReads: false);
+  // print("testSimpleReadWriteShutdown done");
+
+  print("testGoogleHttp");
+  await testGoogleHttp(null, 'pass');
+  print("testGoogleHttp done");
+
+  // TODO(US-96)
+  // print("testGoogleHttps");
+  // await testGoogleHttps(null, 'pass');
+  // print("testGoogleHttps done");
 
   print("Goodbyte, Fuchsia!");
 }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 20ba97a..dd5b600 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -22,6 +22,8 @@
 
 cc/SNPrint_BadArgs: Skip
 
+cc/Profiler_InliningIntervalBoundry: Skip # Differences in ia32, debug, release
+
 # Flaky on buildbot. Issue 5133 and 10409.
 cc/Sleep: Pass, Fail
 
@@ -46,8 +48,59 @@
 cc/Dart2JSCompilerStats: Skip
 cc/CorelibCompilerStats: Skip
 
+# Profiler is completely disabled in SIMDBC builds.
+# On the simluator stack traces produced by the Profiler do not match
+# up with the real Dart stack trace and hence we don't get correct
+# symbol names.
 [ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $arch == simmips || $arch == simdbc  || $arch == simdbc64 ]
 cc/Service_Profile: Skip
+cc/Profiler_AllocationSampleTest: Skip
+cc/Profiler_ArrayAllocation: Skip
+cc/Profiler_BasicSourcePosition: Skip
+cc/Profiler_BasicSourcePositionOptimized: Skip
+cc/Profiler_BinaryOperatorSourcePosition: Skip
+cc/Profiler_BinaryOperatorSourcePositionOptimized: Skip
+cc/Profiler_ChainedSamples: Skip
+cc/Profiler_ClosureAllocation: Skip
+cc/Profiler_CodeTicks: Skip
+cc/Profiler_ContextAllocation: Skip
+cc/Profiler_FunctionInline: Skip
+cc/Profiler_FunctionTicks: Skip
+cc/Profiler_InliningIntervalBoundry: Skip
+cc/Profiler_IntrinsicAllocation: Skip
+cc/Profiler_SampleBufferIterateTest: Skip
+cc/Profiler_SampleBufferWrapTest: Skip
+cc/Profiler_SourcePosition: Skip
+cc/Profiler_SourcePositionOptimized: Skip
+cc/Profiler_StringAllocation: Skip
+cc/Profiler_StringInterpolation: Skip
+cc/Profiler_ToggleRecordAllocation: Skip
+cc/Profiler_TrivialRecordAllocation: Skip
+cc/Profiler_TypedArrayAllocation: Skip
+cc/Profiler_GetSourceReport: Skip
+
+# Following tests are failing in a weird way on macos/ia32/debug builds
+# need to investigate.
+[ $runtime == vm && $mode == debug && $arch == ia32 && $system == macos ]
+cc/Profiler_TrivialRecordAllocation: Skip
+cc/Profiler_ToggleRecordAllocation: Skip
+cc/Profiler_FunctionTicks: Skip
+cc/Profiler_CodeTicks: Skip
+cc/Profiler_IntrinsicAllocation: Skip
+cc/Profiler_ArrayAllocation: Skip
+cc/Profiler_ContextAllocation: Skip
+cc/Profiler_ClosureAllocation: Skip
+cc/Profiler_TypedArrayAllocation: Skip
+cc/Profiler_StringAllocation: Skip
+cc/Profiler_StringInterpolation: Skip
+cc/Profiler_BasicSourcePosition: Skip
+cc/Profiler_BasicSourcePositionOptimized: Skip
+cc/Profiler_ChainedSamples: Skip
+cc/Profiler_FunctionInline: Skip
+cc/Profiler_SourcePosition: Skip
+cc/Profiler_SourcePositionOptimized: Skip
+cc/Profiler_BinaryOperatorSourcePosition: Skip
+cc/Profiler_BinaryOperatorSourcePositionOptimized: Skip
 
 [ $compiler == dart2js ]
 dart/redirection_type_shuffling_test: Skip # Depends on lazy enforcement of type bounds
@@ -84,6 +137,7 @@
 dart/snapshot_version_test: SkipByDesign  # Spawns processes
 dart/spawn_infinite_loop_test: Skip  # VM shutdown test
 dart/spawn_shutdown_test: Skip  # VM Shutdown test
+dart/hello_fuchsia_test: SkipByDesign # This is a test for fuchsia OS
 
 [ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
 cc/Dart2JSCompileAll: SkipSlow  # Timeout.
@@ -115,33 +169,7 @@
 cc/String_ScrubName: Fail,OK  # Expects exact type name.
 cc/GetFunctionNames: Fail,OK  # Expects exact type name.
 
-[ $arch == simdbc || $arch == simdbc64 ]
-# TODO(vegorov) Profiler is completely disabled in SIMDBC builds.
-cc/Profiler_AllocationSampleTest: Skip
-cc/Profiler_ArrayAllocation: Skip
-cc/Profiler_BasicSourcePosition: Skip
-cc/Profiler_BasicSourcePositionOptimized: Skip
-cc/Profiler_BinaryOperatorSourcePosition: Skip
-cc/Profiler_BinaryOperatorSourcePositionOptimized: Skip
-cc/Profiler_ChainedSamples: Skip
-cc/Profiler_ClosureAllocation: Skip
-cc/Profiler_CodeTicks: Skip
-cc/Profiler_ContextAllocation: Skip
-cc/Profiler_FunctionInline: Skip
-cc/Profiler_FunctionTicks: Skip
-cc/Profiler_InliningIntervalBoundry: Skip
-cc/Profiler_IntrinsicAllocation: Skip
-cc/Profiler_SampleBufferIterateTest: Skip
-cc/Profiler_SampleBufferWrapTest: Skip
-cc/Profiler_SourcePosition: Skip
-cc/Profiler_SourcePositionOptimized: Skip
-cc/Profiler_StringAllocation: Skip
-cc/Profiler_StringInterpolation: Skip
-cc/Profiler_ToggleRecordAllocation: Skip
-cc/Profiler_TrivialRecordAllocation: Skip
-cc/Profiler_TypedArrayAllocation: Skip
-cc/Profiler_GetSourceReport: Skip
-
+[ $arch == simdbc  || $arch == simdbc64 ]
 # TODO(vegorov) These tests don't seem to work if FLAG_interpret_irregexp
 # is switched on by default because they attempt to call regexp functions
 # directly instead of going through JSSyntaxRegExp_ExecuteMatch.
@@ -163,6 +191,3 @@
 [ $hot_reload || $hot_reload_rollback ]
 dart/spawn_shutdown_test: Skip # We can shutdown an isolate before it reloads.
 dart/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
-
-[ $runtime == dartium ]
-dart/hello_fuchsia_test: Fail # Issue 27867
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index c731c33..974259e 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -215,9 +215,7 @@
                      new (Z) LiteralNode(token_pos, Object::null_instance())),
       error_ne_null_branch, NULL));
 
-  LocalVariable* result = AddNewTempVarToPreamble(
-      new (Z) LoadLocalNode(token_pos, result_param), ST(node->token_pos()));
-  result_ = new (Z) LoadLocalNode(token_pos, result);
+  result_ = MakeName(new (Z) LoadLocalNode(token_pos, result_param));
 }
 
 
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 84b528d..0dc6e7c 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -20,6 +20,11 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool,
+            use_corelib_source_files,
+            kDefaultCorelibSourceFlag,
+            "Attempt to use source files directly when loading in the core "
+            "libraries during the bootstrap process");
 
 struct BootstrapLibProps {
   ObjectStore::BootstrapLibraryId index;
@@ -82,15 +87,20 @@
   const uint8_t* utf8_array = NULL;
   intptr_t file_length = -1;
 
-  Dart_FileOpenCallback file_open = Dart::file_open_callback();
-  Dart_FileReadCallback file_read = Dart::file_read_callback();
-  Dart_FileCloseCallback file_close = Dart::file_close_callback();
-  if ((file_open != NULL) && (file_read != NULL) && (file_close != NULL)) {
-    // Try to open and read the file.
-    void* stream = (*file_open)(source_path, false);
-    if (stream != NULL) {
-      (*file_read)(&utf8_array, &file_length, stream);
-      (*file_close)(stream);
+  // If flag to use the core library files directly is specified then try
+  // to read the file and extract it's contents otherwise just use the
+  // source data that has been backed into the binary.
+  if (FLAG_use_corelib_source_files) {
+    Dart_FileOpenCallback file_open = Dart::file_open_callback();
+    Dart_FileReadCallback file_read = Dart::file_read_callback();
+    Dart_FileCloseCallback file_close = Dart::file_close_callback();
+    if ((file_open != NULL) && (file_read != NULL) && (file_close != NULL)) {
+      // Try to open and read the file.
+      void* stream = (*file_open)(source_path, false);
+      if (stream != NULL) {
+        (*file_read)(&utf8_array, &file_length, stream);
+        (*file_close)(stream);
+      }
     }
   }
   if (file_length == -1) {
@@ -317,17 +327,9 @@
 
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-static RawError* BootstrapFromKernel(Thread* thread,
-                                     const uint8_t* buffer,
-                                     intptr_t buffer_size) {
+static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
   Zone* zone = thread->zone();
-  kernel::KernelReader reader(buffer, buffer_size);
-  kernel::Program* program = reader.ReadPrecompiledProgram();
-  if (program == NULL) {
-    const String& message =
-        String::Handle(zone, String::New("Failed to read Kernel file"));
-    return ApiError::New(message);
-  }
+  kernel::KernelReader reader(program);
 
   Isolate* isolate = thread->isolate();
   // Mark the already-pending classes.  This mark bit will be used to avoid
@@ -363,17 +365,14 @@
   return Error::null();
 }
 #else
-static RawError* BootstrapFromKernel(Thread* thread,
-                                     const uint8_t* buffer,
-                                     intptr_t buffer_size) {
+static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
   UNREACHABLE();
   return Error::null();
 }
 #endif
 
 
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_length) {
+RawError* Bootstrap::DoBootstrapping(kernel::Program* kernel_program) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -396,9 +395,8 @@
     }
   }
 
-  return (kernel_buffer == NULL)
-             ? BootstrapFromSource(thread)
-             : BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_length);
+  return (kernel_program == NULL) ? BootstrapFromSource(thread)
+                                  : BootstrapFromKernel(thread, kernel_program);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 77fb556..15f454b 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -12,17 +12,19 @@
 
 // Forward declarations.
 class RawError;
+namespace kernel {
+class Program;
+}
 
 class Bootstrap : public AllStatic {
  public:
-  // Compile the bootstrap libraries, either from sources or a Kernel binary.
-  // If kernel_buffer is NULL, compile from sources or source paths linked into
-  // the VM.  If it is non-NULL it represents a buffer holding a Kernel binary.
+  // Compile the bootstrap libraries, either from sources or a Kernel program.
+  // If program is NULL, compile from sources or source paths linked into
+  // the VM.  If it is non-NULL it represents the Kernel program to use for
+  // bootstrapping.
   // The caller of this function is responsible for managing the kernel
-  // buffer's memory, and is welcome to deallocate it after this function
-  // returns.
-  static RawError* DoBootstrapping(const uint8_t* kernel_buffer,
-                                   intptr_t kernel_buffer_length);
+  // program's memory.
+  static RawError* DoBootstrapping(kernel::Program* program);
 
   static void SetupNativeResolver();
   static bool IsBootstapResolver(Dart_NativeEntryResolver resolver);
diff --git a/runtime/vm/bootstrap_nocore.cc b/runtime/vm/bootstrap_nocore.cc
index cd49589..74367a1 100644
--- a/runtime/vm/bootstrap_nocore.cc
+++ b/runtime/vm/bootstrap_nocore.cc
@@ -55,18 +55,9 @@
 }
 
 
-RawError* BootstrapFromKernel(Thread* thread,
-                              const uint8_t* buffer,
-                              intptr_t buffer_length) {
+RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
   Zone* zone = thread->zone();
-  kernel::KernelReader reader(buffer, buffer_length);
-  kernel::Program* program = reader.ReadPrecompiledProgram();
-  if (program == NULL) {
-    const String& message =
-        String::Handle(zone, String::New("Failed to read Kernel file"));
-    return ApiError::New(message);
-  }
-
+  kernel::KernelReader reader(program);
   Isolate* isolate = thread->isolate();
   // Mark the already-pending classes.  This mark bit will be used to avoid
   // adding classes to the list more than once.
@@ -102,8 +93,7 @@
 }
 
 
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_length) {
+RawError* Bootstrap::DoBootstrapping(kernel::Program* program) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -126,12 +116,10 @@
     }
   }
 
-  ASSERT(kernel_buffer != NULL);
-  return BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_length);
+  return BootstrapFromKernel(thread, program);
 }
 #else
-RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
-                                     intptr_t kernel_buffer_length) {
+RawError* Bootstrap::DoBootstrapping(kernel::Program* program) {
   UNREACHABLE();
   return Error::null();
 }
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index d8ae134..e561a54 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -563,7 +563,7 @@
       s->Write<uint32_t>(func->ptr()->kind_tag_);
       if (kind == Snapshot::kAppNoJIT) {
         // Omit fields used to support de/reoptimization.
-      } else {
+      } else if (!Snapshot::IncludesCode(kind)) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
         bool is_optimized = Code::IsOptimized(func->ptr()->code_);
         if (is_optimized) {
@@ -571,9 +571,6 @@
         } else {
           s->Write<int32_t>(0);
         }
-        s->Write<int8_t>(func->ptr()->deoptimization_counter_);
-        s->Write<uint16_t>(func->ptr()->optimized_instruction_count_);
-        s->Write<uint16_t>(func->ptr()->optimized_call_site_count_);
 #endif
       }
     }
@@ -643,10 +640,14 @@
         // Omit fields used to support de/reoptimization.
       } else {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-        func->ptr()->usage_counter_ = d->Read<int32_t>();
-        func->ptr()->deoptimization_counter_ = d->Read<int8_t>();
-        func->ptr()->optimized_instruction_count_ = d->Read<uint16_t>();
-        func->ptr()->optimized_call_site_count_ = d->Read<uint16_t>();
+        if (Snapshot::IncludesCode(kind)) {
+          func->ptr()->usage_counter_ = 0;
+        } else {
+          func->ptr()->usage_counter_ = d->Read<int32_t>();
+        }
+        func->ptr()->deoptimization_counter_ = 0;
+        func->ptr()->optimized_instruction_count_ = 0;
+        func->ptr()->optimized_call_site_count_ = 0;
 #endif
       }
     }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index a3d3da6..07547de 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -493,7 +493,7 @@
 
 RawError* Dart::InitializeIsolate(const uint8_t* snapshot_buffer,
                                   intptr_t snapshot_length,
-                                  bool from_kernel,
+                                  kernel::Program* kernel_program,
                                   void* data) {
   // Initialize the new isolate.
   Thread* T = Thread::Current();
@@ -512,17 +512,11 @@
   }
 
   Error& error = Error::Handle(T->zone());
-  if (from_kernel) {
-    ASSERT(snapshot_buffer != NULL);
-    ASSERT(snapshot_length > 0);
-    error = Object::Init(I, snapshot_buffer, snapshot_length);
-  } else {
-    error = Object::Init(I, NULL, -1);
-  }
+  error = Object::Init(I, kernel_program);
   if (!error.IsNull()) {
     return error.raw();
   }
-  if ((snapshot_buffer != NULL) && !from_kernel) {
+  if ((snapshot_buffer != NULL) && kernel_program == NULL) {
     // Read the snapshot and setup the initial state.
     NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
                                              "IsolateSnapshotReader"));
@@ -563,7 +557,7 @@
       MegamorphicCacheTable::PrintSizes(I);
     }
   } else {
-    if ((snapshot_kind_ != Snapshot::kNone) && !from_kernel) {
+    if ((snapshot_kind_ != Snapshot::kNone) && kernel_program == NULL) {
       const String& message =
           String::Handle(String::New("Missing isolate snapshot"));
       return ApiError::New(message);
@@ -591,7 +585,7 @@
       Code::Handle(I->object_store()->megamorphic_miss_code());
   I->set_ic_miss_code(miss_code);
 
-  if ((snapshot_buffer == NULL) || from_kernel) {
+  if ((snapshot_buffer == NULL) || (kernel_program != NULL)) {
     const Error& error = Error::Handle(I->object_store()->PreallocateObjects());
     if (!error.IsNull()) {
       return error.raw();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 3480fad..9af4ed9 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -18,6 +18,9 @@
 class RawError;
 class ReadOnlyHandles;
 class ThreadPool;
+namespace kernel {
+class Program;
+}
 
 class Dart : public AllStatic {
  public:
@@ -44,7 +47,7 @@
   // from_kernel.  Otherwise, initialize from sources.
   static RawError* InitializeIsolate(const uint8_t* snapshot_buffer,
                                      intptr_t snapshot_length,
-                                     bool from_kernel,
+                                     kernel::Program* kernel_program,
                                      void* data);
   static void RunShutdownCallback();
   static void ShutdownIsolate(Isolate* isolate);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index e58810d..2e739e1 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1240,11 +1240,10 @@
                                   const char* main,
                                   const uint8_t* snapshot_buffer,
                                   intptr_t snapshot_length,
-                                  bool from_kernel,
+                                  kernel::Program* kernel_program,
                                   Dart_IsolateFlags* flags,
                                   void* callback_data,
                                   char** error) {
-  ASSERT(!from_kernel || (snapshot_buffer != NULL));
   CHECK_NO_ISOLATE(Isolate::Current());
   char* isolate_name = BuildIsolateName(script_uri, main);
 
@@ -1270,10 +1269,10 @@
     Dart_EnterScope();
     const Error& error_obj = Error::Handle(
         Z, Dart::InitializeIsolate(snapshot_buffer, snapshot_length,
-                                   from_kernel, callback_data));
+                                   kernel_program, callback_data));
     if (error_obj.IsNull()) {
 #if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT)
-      if (FLAG_check_function_fingerprints && !from_kernel) {
+      if (FLAG_check_function_fingerprints && kernel_program == NULL) {
         Library::CheckFunctionFingerprints();
       }
 #endif  // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT).
@@ -1302,20 +1301,19 @@
                                             Dart_IsolateFlags* flags,
                                             void* callback_data,
                                             char** error) {
-  return CreateIsolate(script_uri, main, snapshot_buffer, -1, false, flags,
+  return CreateIsolate(script_uri, main, snapshot_buffer, -1, NULL, flags,
                        callback_data, error);
 }
 
 
-DART_EXPORT Dart_Isolate
-Dart_CreateIsolateFromKernel(const char* script_uri,
-                             const char* main,
-                             const uint8_t* kernel_file,
-                             intptr_t kernel_length,
-                             Dart_IsolateFlags* flags,
-                             void* callback_data,
-                             char** error) {
-  return CreateIsolate(script_uri, main, kernel_file, kernel_length, true,
+DART_EXPORT Dart_Isolate Dart_CreateIsolateFromKernel(const char* script_uri,
+                                                      const char* main,
+                                                      void* kernel_program,
+                                                      Dart_IsolateFlags* flags,
+                                                      void* callback_data,
+                                                      char** error) {
+  return CreateIsolate(script_uri, main, NULL, -1,
+                       reinterpret_cast<kernel::Program*>(kernel_program),
                        flags, callback_data, error);
 }
 
@@ -5350,9 +5348,23 @@
 }
 
 
-DART_EXPORT Dart_Handle Dart_LoadKernel(const uint8_t* buffer,
+DART_EXPORT void* Dart_ReadKernelBinary(const uint8_t* buffer,
                                         intptr_t buffer_len) {
   API_TIMELINE_DURATION;
+
+#if defined(DART_PRECOMPILED_RUNTIME)
+  UNREACHABLE();
+  return NULL;
+#else
+  kernel::Program* program =
+      ReadPrecompiledKernelFromBuffer(buffer, buffer_len);
+  return program;
+#endif
+}
+
+
+DART_EXPORT Dart_Handle Dart_LoadKernel(void* kernel_program) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   StackZone zone(T);
 
@@ -5371,9 +5383,12 @@
   CHECK_CALLBACK_STATE(T);
   CHECK_COMPILATION_ALLOWED(I);
 
-  // TODO(27588): Memory leak!
-  kernel::KernelReader* reader = new kernel::KernelReader(buffer, buffer_len);
-  const Object& tmp = reader->ReadProgram();
+  // NOTE: Now the VM owns the [kernel_program] memory!  Currently we do not
+  // free it because (similar to the token stream) it will be used to repeatedly
+  // run the `kernel::FlowGraphBuilder()`.
+  kernel::KernelReader reader(
+      reinterpret_cast<kernel::Program*>(kernel_program));
+  const Object& tmp = reader.ReadProgram();
   if (tmp.IsError()) {
     return Api::NewHandle(T, tmp.raw());
   }
@@ -5514,6 +5529,26 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_GetLoadedLibraries() {
+  DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
+
+  const GrowableObjectArray& libs =
+      GrowableObjectArray::Handle(Z, I->object_store()->libraries());
+  int num_libs = libs.Length();
+
+  // Create new list and populate with the loaded libraries.
+  Library& lib = Library::Handle();
+  const Array& library_list = Array::Handle(Z, Array::New(num_libs));
+  for (int i = 0; i < num_libs; i++) {
+    lib ^= libs.At(i);
+    ASSERT(!lib.IsNull());
+    library_list.SetAt(i, lib);
+  }
+  return Api::NewHandle(T, library_list.raw());
+}
+
+
 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) {
   DARTSCOPE(Thread::Current());
   const String& url_str = Api::UnwrapStringHandle(Z, url);
@@ -5865,6 +5900,38 @@
 }
 
 
+DART_EXPORT Dart_Handle
+Dart_GetNativeResolver(Dart_Handle library,
+                       Dart_NativeEntryResolver* resolver) {
+  if (resolver == NULL) {
+    RETURN_NULL_ERROR(resolver);
+  }
+  *resolver = NULL;
+  DARTSCOPE(Thread::Current());
+  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
+  if (lib.IsNull()) {
+    RETURN_TYPE_ERROR(Z, library, Library);
+  }
+  *resolver = lib.native_entry_resolver();
+  return Api::Success();
+}
+
+
+DART_EXPORT Dart_Handle Dart_GetNativeSymbol(Dart_Handle library,
+                                             Dart_NativeEntrySymbol* resolver) {
+  if (resolver == NULL) {
+    RETURN_NULL_ERROR(resolver);
+  }
+  *resolver = NULL;
+  DARTSCOPE(Thread::Current());
+  const Library& lib = Api::UnwrapLibraryHandle(Z, library);
+  if (lib.IsNull()) {
+    RETURN_TYPE_ERROR(Z, library, Library);
+  }
+  *resolver = lib.native_entry_symbol_resolver();
+  return Api::Success();
+}
+
 // --- Peer support ---
 
 DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) {
@@ -6604,4 +6671,11 @@
 #endif
 }
 
+
+DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
+#ifndef PRODUCT
+  Profiler::DumpStackTrace(context);
+#endif
+}
+
 }  // namespace dart
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 0e7a1d7..e48ab54 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -2230,9 +2230,10 @@
   {
     Dart_Handle set_type = Dart_GetType(core_lib, set_name, 0, NULL);
     Dart_Handle super_type = Dart_GetSupertype(set_type);
+    Dart_Handle super2_type = Dart_GetSupertype(super_type);
     Dart_Handle iterable_type = Dart_GetType(core_lib, iterable_name, 0, NULL);
     const Type& expected_type = Api::UnwrapTypeHandle(zone, iterable_type);
-    const Type& actual_type = Api::UnwrapTypeHandle(zone, super_type);
+    const Type& actual_type = Api::UnwrapTypeHandle(zone, super2_type);
     EXPECT(expected_type.raw() == actual_type.raw());
   }
   {
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 7c1a288..c59746e 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -122,8 +122,7 @@
     "Polymorphic calls with deoptimization / megamorphic call")                \
   P(precompiled_mode, bool, false, "Precompilation compiler mode")             \
   C(precompiled_runtime, true, false, bool, false, "Precompiled runtime mode") \
-  R(print_snapshot_sizes, false, bool, false,                                  \
-    "Print sizes of generated snapshots.")                                     \
+  P(print_snapshot_sizes, bool, false, "Print sizes of generated snapshots.")  \
   R(print_ssa_liveranges, false, bool, false,                                  \
     "Print live ranges after allocation.")                                     \
   C(print_stop_message, false, false, bool, false, "Print stop message.")      \
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index fdf1d2e..4eb78fa 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -1154,8 +1154,9 @@
           }
           ASSERT((drop->value() != NULL) || !drop->HasTemp());
         } else {
-          ASSERT(definition->HasTemp());
-          result = GetConstant(constant->value());
+          if (definition->HasTemp()) {
+            result = GetConstant(constant->value());
+          }
         }
         // Update expression stack or remove from graph.
         if (definition->HasTemp()) {
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index e3045ed..39743c5 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -107,7 +107,9 @@
   ;  // NOLINT
 // clang-format on
 #elif defined(HOST_ARCH_X64)
-#define COPY_FP_REGISTER(fp) UNIMPLEMENTED();
+// We don't have the asm equivalent to get at the frame pointer on
+// windows x64, return the stack pointer instead.
+#define COPY_FP_REGISTER(fp) fp = Thread::GetCurrentStackPointer();
 #else
 #error Unknown host architecture.
 #endif
@@ -136,6 +138,13 @@
 
 #endif  // !defined(TARGET_OS_WINDOWS))
 
+// Default value for flag --use-corelib-source-files.
+#if defined(TARGET_OS_WINDOWS)
+static const bool kDefaultCorelibSourceFlag = true;
+#else
+static const bool kDefaultCorelibSourceFlag = false;
+#endif  // defined(TARGET_OS_WINDOWS)
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_GLOBALS_H_
diff --git a/runtime/vm/kernel_reader.cc b/runtime/vm/kernel_reader.cc
index 22f5568..e3b633f 100644
--- a/runtime/vm/kernel_reader.cc
+++ b/runtime/vm/kernel_reader.cc
@@ -93,63 +93,54 @@
   return reader_->LookupClass(klass).raw();
 }
 
-Program* KernelReader::ReadPrecompiledProgram() {
-  Program* program = ReadPrecompiledKernelFromBuffer(buffer_, buffer_length_);
-  if (program == NULL) return NULL;
-  intptr_t source_file_count = program->line_starting_table().size();
+KernelReader::KernelReader(Program* program)
+    : program_(program),
+      thread_(dart::Thread::Current()),
+      zone_(thread_->zone()),
+      isolate_(thread_->isolate()),
+      scripts_(Array::ZoneHandle(zone_)),
+      translation_helper_(this, thread_, zone_, isolate_),
+      type_translator_(&translation_helper_,
+                       &active_class_,
+                       /*finalize=*/false) {
+  intptr_t source_file_count = program_->line_starting_table().size();
   scripts_ = Array::New(source_file_count);
-  program_ = program;
-  return program;
 }
 
 Object& KernelReader::ReadProgram() {
-  Program* program = ReadPrecompiledProgram();
-  if (program == NULL) {
-    const dart::String& error = H.DartString("Failed to read .kernell file");
-    return Object::Handle(Z, ApiError::New(error));
-  }
-
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
-    Procedure* main = program->main_method();
+    Procedure* main = program_->main_method();
     Library* kernel_main_library = Library::Cast(main->parent());
 
-    intptr_t length = program->libraries().length();
+    intptr_t length = program_->libraries().length();
     for (intptr_t i = 0; i < length; i++) {
-      Library* kernel_library = program->libraries()[i];
+      Library* kernel_library = program_->libraries()[i];
       ReadLibrary(kernel_library);
     }
 
     for (intptr_t i = 0; i < length; i++) {
-      dart::Library& library = LookupLibrary(program->libraries()[i]);
+      dart::Library& library = LookupLibrary(program_->libraries()[i]);
       if (!library.Loaded()) library.SetLoaded();
     }
 
-    if (!ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) {
-      FATAL("Error in class finalization during bootstrapping.");
+    if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) {
+      dart::Library& library = LookupLibrary(kernel_main_library);
+
+      // Sanity check that we can find the main entrypoint.
+      Object& main_obj = Object::Handle(
+          Z, library.LookupObjectAllowPrivate(H.DartSymbol("main")));
+      ASSERT(!main_obj.IsNull());
+      return library;
     }
-
-    dart::Library& library = LookupLibrary(kernel_main_library);
-
-    // Sanity check that we can find the main entrypoint.
-    Object& main_obj = Object::Handle(
-        Z, library.LookupObjectAllowPrivate(H.DartSymbol("main")));
-    ASSERT(!main_obj.IsNull());
-    return library;
-  } else {
-    // Everything else is a compile-time error. We don't use the [error] since
-    // it sometimes causes the higher-level error handling to try to read the
-    // script and token position (which we don't have) to produce a nice error
-    // message.
-    Error& error = Error::Handle(Z);
-    error = thread_->sticky_error();
-    thread_->clear_sticky_error();
-
-    // Instead we simply make a non-informative error message.
-    const dart::String& error_message =
-        H.DartString("Failed to read .kernell file => CompileTimeError.");
-    return Object::Handle(Z, LanguageError::New(error_message));
   }
+
+  // Either class finalization failed or we caught a compile error.
+  // In both cases sticky error would be set.
+  Error& error = Error::Handle(Z);
+  error = thread_->sticky_error();
+  thread_->clear_sticky_error();
+  return error;
 }
 
 
@@ -499,10 +490,6 @@
           false,  // is_native
           script_class, kernel_field->position()));
   klass.AddFunction(getter);
-  if (klass.IsTopLevel()) {
-    dart::Library& library = dart::Library::Handle(Z, klass.library());
-    library.AddObject(getter, getter_name);
-  }
   getter.set_kernel_function(kernel_field);
   getter.set_result_type(AbstractType::Handle(Z, field.type()));
   getter.set_is_debuggable(false);
@@ -706,7 +693,7 @@
   init_name = Symbols::FromConcat(thread, Symbols::InitPrefix(), init_name);
 
   // Create a static initializer.
-  const dart::Class& owner = dart::Class::Handle(zone, field.Owner());
+  const Object& owner = Object::Handle(field.RawOwner());
   const Function& initializer_fun = Function::ZoneHandle(
       zone,
       dart::Function::New(init_name, RawFunction::kImplicitStaticFinalGetter,
diff --git a/runtime/vm/kernel_reader.h b/runtime/vm/kernel_reader.h
index 60c8de9..f6b4ffd 100644
--- a/runtime/vm/kernel_reader.h
+++ b/runtime/vm/kernel_reader.h
@@ -54,21 +54,7 @@
 
 class KernelReader {
  public:
-  KernelReader(const uint8_t* buffer, intptr_t len)
-      : thread_(dart::Thread::Current()),
-        zone_(thread_->zone()),
-        isolate_(thread_->isolate()),
-        scripts_(Array::ZoneHandle(zone_)),
-        program_(NULL),
-        translation_helper_(this, thread_, zone_, isolate_),
-        type_translator_(&translation_helper_,
-                         &active_class_,
-                         /*finalize=*/false),
-        buffer_(buffer),
-        buffer_length_(len) {}
-
-  // Returns either pointer to a program or null.
-  Program* ReadPrecompiledProgram();
+  explicit KernelReader(Program* program);
 
   // Returns either a library or a failure object.
   dart::Object& ReadProgram();
@@ -112,18 +98,16 @@
 
   dart::RawFunction::Kind GetFunctionType(Procedure* kernel_procedure);
 
+  Program* program_;
+
   dart::Thread* thread_;
   dart::Zone* zone_;
   dart::Isolate* isolate_;
   Array& scripts_;
-  Program* program_;
   ActiveClass active_class_;
   BuildingTranslationHelper translation_helper_;
   DartTypeTranslator type_translator_;
 
-  const uint8_t* buffer_;
-  intptr_t buffer_length_;
-
   Mapping<Library, dart::Library> libraries_;
   Mapping<Class, dart::Class> classes_;
 };
diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc
index ff7c1cd..f741ce5 100644
--- a/runtime/vm/kernel_to_il.cc
+++ b/runtime/vm/kernel_to_il.cc
@@ -4916,7 +4916,8 @@
 
   instructions += EnterScope(node);
   List<Statement>& statements = node->statements();
-  for (intptr_t i = 0; i < statements.length(); ++i) {
+  for (intptr_t i = 0; (i < statements.length()) && instructions.is_open();
+       ++i) {
     instructions += TranslateStatement(statements[i]);
   }
   instructions += ExitScope(node);
@@ -4931,17 +4932,21 @@
   Fragment instructions = node->expression() == NULL
                               ? NullConstant()
                               : TranslateExpression(node->expression());
-  if (inside_try_finally) {
-    ASSERT(scopes_->finally_return_variable != NULL);
-    instructions += StoreLocal(scopes_->finally_return_variable);
-    instructions += Drop();
-    instructions += TranslateFinallyFinalizers(NULL, -1);
-    if (instructions.is_open()) {
-      instructions += LoadLocal(scopes_->finally_return_variable);
+  if (instructions.is_open()) {
+    if (inside_try_finally) {
+      ASSERT(scopes_->finally_return_variable != NULL);
+      instructions += StoreLocal(scopes_->finally_return_variable);
+      instructions += Drop();
+      instructions += TranslateFinallyFinalizers(NULL, -1);
+      if (instructions.is_open()) {
+        instructions += LoadLocal(scopes_->finally_return_variable);
+        instructions += Return();
+      }
+    } else {
       instructions += Return();
     }
   } else {
-    instructions += Return();
+    Pop();
   }
   fragment_ = instructions;
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 920b9bd..428dfa3 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1136,14 +1136,12 @@
 // A non-NULL kernel argument indicates (1).  A NULL kernel indicates (2) or
 // (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or
 // not.
-RawError* Object::Init(Isolate* isolate,
-                       const uint8_t* kernel_buffer,
-                       intptr_t kernel_buffer_length) {
+RawError* Object::Init(Isolate* isolate, kernel::Program* kernel_program) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(isolate == thread->isolate());
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  const bool is_kernel = (kernel_buffer != NULL);
+  const bool is_kernel = (kernel_program != NULL);
 #endif
   NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
                                            "Object::Init");)
@@ -1619,8 +1617,8 @@
 
     // Finish the initialization by compiling the bootstrap scripts containing
     // the base interfaces and the implementation of the internal classes.
-    const Error& error = Error::Handle(
-        zone, Bootstrap::DoBootstrapping(kernel_buffer, kernel_buffer_length));
+    const Error& error =
+        Error::Handle(zone, Bootstrap::DoBootstrapping(kernel_program));
     if (!error.IsNull()) {
       return error.raw();
     }
@@ -7353,7 +7351,7 @@
 
 
 RawObject* Field::RawOwner() const {
-  if (Original()) {
+  if (IsOriginal()) {
     return raw_ptr()->owner_;
   } else {
     const Field& field = Field::Handle(Original());
@@ -14305,9 +14303,7 @@
     Zone* zone = thread->zone();
     const char* name = StubCode::NameOfStub(UncheckedEntryPoint());
     ASSERT(name != NULL);
-    char* stub_name =
-        OS::SCreate(zone, "%s%s", Symbols::StubPrefix().ToCString(), name);
-    return stub_name;
+    return OS::SCreate(zone, "[Stub] %s", name);
   } else if (obj.IsClass()) {
     // Allocation stub.
     Thread* thread = Thread::Current();
@@ -14315,10 +14311,7 @@
     const Class& cls = Class::Cast(obj);
     String& cls_name = String::Handle(zone, cls.ScrubbedName());
     ASSERT(!cls_name.IsNull());
-    char* stub_name =
-        OS::SCreate(zone, "%s%s", Symbols::AllocationStubFor().ToCString(),
-                    cls_name.ToCString());
-    return stub_name;
+    return OS::SCreate(zone, "[Stub] Allocate %s", cls_name.ToCString());
   } else {
     ASSERT(obj.IsFunction());
     // Dart function.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index bf2b009..61a2866 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -29,6 +29,10 @@
 namespace dart {
 
 // Forward declarations.
+namespace kernel {
+class Program;
+}
+
 #define DEFINE_FORWARD_DECLARATION(clazz) class clazz;
 CLASS_LIST(DEFINE_FORWARD_DECLARATION)
 #undef DEFINE_FORWARD_DECLARATION
@@ -527,9 +531,7 @@
 
   // Initialize a new isolate either from a Kernel IR, from source, or from a
   // snapshot.
-  static RawError* Init(Isolate* isolate,
-                        const uint8_t* kernel,
-                        intptr_t kernel_length);
+  static RawError* Init(Isolate* isolate, kernel::Program* program);
 
   static void MakeUnusedSpaceTraversable(const Object& obj,
                                          intptr_t original_size,
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 65e743c..6c13dde 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <magenta/syscalls.h>
 #include <magenta/types.h>
+#include <sys/time.h>
 
 #include "platform/assert.h"
 #include "vm/zone.h"
@@ -77,7 +78,12 @@
 
 
 int64_t OS::GetCurrentTimeMicros() {
-  return mx_time_get(MX_CLOCK_MONOTONIC) / 1000;
+  struct timeval tv;
+  if (gettimeofday(&tv, NULL) < 0) {
+    UNREACHABLE();
+    return 0;
+  }
+  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
 }
 
 
@@ -157,7 +163,7 @@
 
 
 uintptr_t OS::MaxRSS() {
-  UNIMPLEMENTED();
+  // TODO(US-95): Implement.
   return 0;
 }
 
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index c1a9303..29823b8 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -24,7 +24,7 @@
   if (result != 0) {                                                           \
     const int kBufferSize = 1024;                                              \
     char error_message[kBufferSize];                                           \
-    NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /* native_stack_trace */));   \
+    NOT_IN_PRODUCT(Profiler::DumpStackTrace());                                \
     Utils::StrError(result, error_message, kBufferSize);                       \
     FATAL2("pthread error: %d (%s)", result, error_message);                   \
   }
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index 8190521..438fb17 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -25,7 +25,7 @@
   if (result != 0) {                                                           \
     const int kBufferSize = 1024;                                              \
     char error_buf[kBufferSize];                                               \
-    NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /* native_stack_trace */));   \
+    NOT_IN_PRODUCT(Profiler::DumpStackTrace());                                \
     FATAL2("pthread error: %d (%s)", result,                                   \
            Utils::StrError(result, error_buf, kBufferSize));                   \
   }
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index ec0959b..23fe4d7 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -29,7 +29,7 @@
   if (result != 0) {                                                           \
     const int kBufferSize = 1024;                                              \
     char error_message[kBufferSize];                                           \
-    NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /* native_stack_trace */));   \
+    NOT_IN_PRODUCT(Profiler::DumpStackTrace());                                \
     Utils::StrError(result, error_message, kBufferSize);                       \
     FATAL2("pthread error: %d (%s)", result, error_message);                   \
   }
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 7829fd6..f9fd601 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -55,7 +55,7 @@
 DEFINE_FLAG(bool, generic_method_syntax, true, "Enable generic functions.");
 DEFINE_FLAG(bool,
             initializing_formal_access,
-            false,
+            true,
             "Make initializing formal parameters visible in initializer list.");
 DEFINE_FLAG(bool,
             warn_super,
@@ -7594,7 +7594,6 @@
 AstNode* Parser::ParseFunctionStatement(bool is_literal) {
   TRACE_PARSER("ParseFunctionStatement");
   AbstractType& result_type = AbstractType::Handle(Z);
-  const String* variable_name = NULL;
   const String* function_name = NULL;
 
   result_type = Type::DynamicType();
@@ -7616,8 +7615,7 @@
       result_type = ParseType(ClassFinalizer::kDoNotResolve);
     }
     function_name_pos = TokenPos();
-    variable_name = ExpectIdentifier("function name expected");
-    function_name = variable_name;
+    function_name = ExpectIdentifier("function name expected");
 
     // Check that the function name has not been referenced
     // before this declaration.
@@ -7689,7 +7687,7 @@
 
   LocalVariable* function_variable = NULL;
   Type& function_type = Type::ZoneHandle(Z);
-  if (variable_name != NULL) {
+  if (!is_literal) {
     // Since the function type depends on the signature of the closure function,
     // it cannot be determined before the formal parameter list of the closure
     // function is parsed. Therefore, we set the function type to a new
@@ -7705,7 +7703,7 @@
     // Add the function variable to the scope before parsing the function in
     // order to allow self reference from inside the function.
     function_variable = new (Z) LocalVariable(function_name_pos, function_pos,
-                                              *variable_name, function_type);
+                                              *function_name, function_type);
     function_variable->set_is_final();
     ASSERT(current_block_ != NULL);
     ASSERT(current_block_->scope != NULL);
@@ -7773,7 +7771,7 @@
   ASSERT(!signature_type.IsMalformed());
   ASSERT(!signature_type.IsMalbounded());
 
-  if (variable_name != NULL) {
+  if (!is_literal) {
     // Patch the function type of the variable now that the signature is known.
     function_type.set_type_class(Class::Handle(Z, signature_type.type_class()));
     function_type.set_arguments(
@@ -7785,8 +7783,7 @@
     function_type.ResetIsFinalized();
 
     // The function variable type should have been patched above.
-    ASSERT((function_variable == NULL) ||
-           (function_variable->type().raw() == function_type.raw()));
+    ASSERT(function_variable->type().raw() == function_type.raw());
   }
 
   // The code generator does not compile the closure function when visiting
@@ -7815,14 +7812,8 @@
   ASSERT(innermost_function_.raw() == function.raw());
   innermost_function_ = function.parent_function();
 
-  if (function_variable == NULL) {
-    ASSERT(is_literal);
-    return closure;
-  } else {
-    AstNode* initialization =
-        new (Z) StoreLocalNode(function_pos, function_variable, closure);
-    return initialization;
-  }
+  return is_literal ? closure : new (Z) StoreLocalNode(
+                                    function_pos, function_variable, closure);
 }
 
 
@@ -13807,11 +13798,7 @@
   AstNode* primary = NULL;
   const Token::Kind token = CurrentToken();
   if (IsFunctionLiteral()) {
-    // The name of a literal function is visible from inside the function, but
-    // must not collide with names in the scope declaring the literal.
-    OpenBlock();
     primary = ParseFunctionStatement(true);
-    CloseBlock();
   } else if (IsIdentifier()) {
     TokenPosition qual_ident_pos = TokenPos();
     const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix());
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 22febb0..9db93ae 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -418,67 +418,54 @@
 };
 
 
-// Given an exit frame, walk the Dart stack.
-class ProfilerDartExitStackWalker : public ProfilerStackWalker {
- public:
-  ProfilerDartExitStackWalker(Thread* thread,
-                              Isolate* isolate,
-                              Sample* sample,
-                              SampleBuffer* sample_buffer)
-      : ProfilerStackWalker(isolate, sample, sample_buffer),
-        frame_iterator_(thread) {}
-
-  void walk() {
-    // Mark that this sample was collected from an exit frame.
-    sample_->set_exit_frame_sample(true);
-
-    StackFrame* frame = frame_iterator_.NextFrame();
-    if (sample_ == NULL) {
-      // Only when we are dumping the stack trace for debug purposes.
-      Code& code = Code::Handle();
-      while (frame != NULL) {
-        code ^= frame->LookupDartCode();
-        if (!Append(frame->pc(), code)) {
-          return;
-        }
-        frame = frame_iterator_.NextFrame();
-      }
-    } else {
-      while (frame != NULL) {
-        if (!Append(frame->pc())) {
-          return;
-        }
-        frame = frame_iterator_.NextFrame();
-      }
-    }
-  }
-
- private:
-  DartFrameIterator frame_iterator_;
-};
-
-
 // Executing Dart code, walk the stack.
 class ProfilerDartStackWalker : public ProfilerStackWalker {
  public:
-  ProfilerDartStackWalker(Isolate* isolate,
+  ProfilerDartStackWalker(Thread* thread,
                           Sample* sample,
                           SampleBuffer* sample_buffer,
                           uword stack_lower,
                           uword stack_upper,
                           uword pc,
                           uword fp,
-                          uword sp)
-      : ProfilerStackWalker(isolate, sample, sample_buffer),
+                          uword sp,
+                          bool exited_dart_code,
+                          bool allocation_sample)
+      : ProfilerStackWalker(thread->isolate(), sample, sample_buffer),
+        pc_(reinterpret_cast<uword*>(pc)),
+        fp_(reinterpret_cast<uword*>(fp)),
+        sp_(reinterpret_cast<uword*>(sp)),
         stack_upper_(stack_upper),
-        stack_lower_(stack_lower) {
-    pc_ = reinterpret_cast<uword*>(pc);
-    fp_ = reinterpret_cast<uword*>(fp);
-    sp_ = reinterpret_cast<uword*>(sp);
+        stack_lower_(stack_lower),
+        has_exit_frame_(exited_dart_code) {
+    if (exited_dart_code) {
+      StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
+                                  thread);
+      pc_ = NULL;
+      fp_ = NULL;
+      sp_ = NULL;
+      if (!iterator.HasNextFrame()) {
+        return;
+      }
+      // Ensure we are able to get to the exit frame.
+      StackFrame* frame = iterator.NextFrame();
+      if (!frame->IsExitFrame()) {
+        return;
+      }
+      // Skip the exit frame.
+      if (!iterator.HasNextFrame()) {
+        return;
+      }
+      frame = iterator.NextFrame();
+      // Record frame details of the first frame from which we start walking.
+      pc_ = reinterpret_cast<uword*>(frame->pc());
+      fp_ = reinterpret_cast<uword*>(frame->fp());
+      sp_ = reinterpret_cast<uword*>(frame->sp());
+    }
   }
 
   void walk() {
-    sample_->set_exit_frame_sample(false);
+    sample_->set_exit_frame_sample(has_exit_frame_);
     if (!ValidFramePointer()) {
       sample_->set_ignore_sample(true);
       return;
@@ -605,7 +592,8 @@
   uword* fp_;
   uword* sp_;
   const uword stack_upper_;
-  uword stack_lower_;
+  const uword stack_lower_;
+  bool has_exit_frame_;
 };
 
 
@@ -758,7 +746,6 @@
                           bool in_dart_code,
                           Sample* sample,
                           ProfilerNativeStackWalker* native_stack_walker,
-                          ProfilerDartExitStackWalker* dart_exit_stack_walker,
                           ProfilerDartStackWalker* dart_stack_walker,
                           uword pc,
                           uword fp,
@@ -783,7 +770,7 @@
     } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
       AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1);
       // We have a valid exit frame info, use the Dart stack walker.
-      dart_exit_stack_walker->walk();
+      dart_stack_walker->walk();
     } else if (StubCode::HasBeenInitialized() && in_dart_code) {
       AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1);
       // We are executing Dart code. We have frame pointers.
@@ -944,7 +931,33 @@
 #endif
 
 
-void Profiler::DumpStackTrace(bool native_stack_trace) {
+void Profiler::DumpStackTrace(void* context) {
+#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS)
+  ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
+  mcontext_t mcontext = ucontext->uc_mcontext;
+  uword pc = SignalHandler::GetProgramCounter(mcontext);
+  uword fp = SignalHandler::GetFramePointer(mcontext);
+  uword sp = SignalHandler::GetCStackPointer(mcontext);
+  DumpStackTrace(sp, fp, pc);
+#else
+// TODO(fschneider): Add support for more platforms.
+// Do nothing on unsupported platforms.
+#endif
+}
+
+
+void Profiler::DumpStackTrace() {
+  uintptr_t sp = Thread::GetCurrentStackPointer();
+  uintptr_t fp = 0;
+  uintptr_t pc = GetProgramCounter();
+
+  COPY_FP_REGISTER(fp);
+
+  DumpStackTrace(sp, fp, pc);
+}
+
+
+void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) {
   // Allow only one stack trace to prevent recursively printing stack traces if
   // we hit an assert while printing the stack.
   static uintptr_t started_dump = 0;
@@ -964,18 +977,9 @@
     return;
   }
 
-  const bool exited_dart_code = thread->HasExitedDartCode();
-
-  OS::PrintErr("Dumping %s stack trace for thread %" Px "\n",
-               native_stack_trace ? "native" : "dart-only",
+  OS::PrintErr("Dumping native stack trace for thread %" Px "\n",
                OSThread::ThreadIdToIntPtr(os_thread->trace_id()));
 
-  uintptr_t sp = Thread::GetCurrentStackPointer();
-  uintptr_t fp = 0;
-  uintptr_t pc = GetProgramCounter();
-
-  COPY_FP_REGISTER(fp);
-
   uword stack_lower = 0;
   uword stack_upper = 0;
 
@@ -991,18 +995,9 @@
     return;
   }
 
-  if (native_stack_trace) {
-    ProfilerNativeStackWalker native_stack_walker(
-        isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp);
-    native_stack_walker.walk();
-  } else if (exited_dart_code) {
-    ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, NULL,
-                                                       NULL);
-    dart_exit_stack_walker.walk();
-  } else {
-    ProfilerDartStackWalker dart_stack_walker(isolate, NULL, NULL, stack_lower,
-                                              stack_upper, pc, fp, sp);
-  }
+  ProfilerNativeStackWalker native_stack_walker(
+      isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp);
+  native_stack_walker.walk();
   OS::PrintErr("-- End of DumpStackTrace\n");
 }
 
@@ -1024,36 +1019,36 @@
     return;
   }
 
+  uintptr_t sp = Thread::GetCurrentStackPointer();
+  uintptr_t fp = 0;
+  uintptr_t pc = GetProgramCounter();
+
+  COPY_FP_REGISTER(fp);
+
+  uword stack_lower = 0;
+  uword stack_upper = 0;
+
+  if (!InitialRegisterCheck(pc, fp, sp)) {
+    return;
+  }
+
+  if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower,
+                                        &stack_upper)) {
+    // Could not get stack boundary.
+    return;
+  }
+
+  Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
+  sample->SetAllocationCid(cid);
+
   if (FLAG_profile_vm) {
-    uintptr_t sp = Thread::GetCurrentStackPointer();
-    uintptr_t fp = 0;
-    uintptr_t pc = GetProgramCounter();
-
-    COPY_FP_REGISTER(fp);
-
-    uword stack_lower = 0;
-    uword stack_upper = 0;
-
-    if (!InitialRegisterCheck(pc, fp, sp)) {
-      return;
-    }
-
-    if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower,
-                                          &stack_upper)) {
-      // Could not get stack boundary.
-      return;
-    }
-
-    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
-    sample->SetAllocationCid(cid);
     ProfilerNativeStackWalker native_stack_walker(
         isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
     native_stack_walker.walk();
   } else if (exited_dart_code) {
-    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
-    sample->SetAllocationCid(cid);
-    ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample,
-                                                       sample_buffer);
+    ProfilerDartStackWalker dart_exit_stack_walker(
+        thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp,
+        exited_dart_code, true);
     dart_exit_stack_walker.walk();
   } else {
     // Fall back.
@@ -1191,19 +1186,15 @@
 
   ProfilerNativeStackWalker native_stack_walker(
       isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
-
-  ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample,
-                                                     sample_buffer);
-
-  ProfilerDartStackWalker dart_stack_walker(
-      isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
-
   const bool exited_dart_code = thread->HasExitedDartCode();
+  ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer,
+                                            stack_lower, stack_upper, pc, fp,
+                                            sp, exited_dart_code, false);
 
   // All memory access is done inside CollectSample.
   CollectSample(isolate, exited_dart_code, in_dart_code, sample,
-                &native_stack_walker, &dart_exit_stack_walker,
-                &dart_stack_walker, pc, fp, sp, &counters_);
+                &native_stack_walker, &dart_stack_walker, pc, fp, sp,
+                &counters_);
 }
 
 
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 1ea5f2d..ee87a31 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -54,7 +54,8 @@
 
   static SampleBuffer* sample_buffer() { return sample_buffer_; }
 
-  static void DumpStackTrace(bool native_stack_trace = true);
+  static void DumpStackTrace(void* context);
+  static void DumpStackTrace();
 
   static void SampleAllocation(Thread* thread, intptr_t cid);
 
@@ -74,6 +75,8 @@
   }
 
  private:
+  static void DumpStackTrace(uword sp, uword fp, uword pc);
+
   // Does not walk the thread's stack.
   static void SampleThreadSingleFrame(Thread* thread, uintptr_t pc);
   static bool initialized_;
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index f1c0b92..a150c30 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -252,6 +252,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -265,6 +267,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
 
@@ -274,6 +278,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -287,6 +293,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -372,6 +380,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -385,6 +395,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
 
@@ -394,6 +406,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -407,6 +421,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -499,10 +515,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
     EXPECT_EQ(3, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
@@ -522,6 +540,8 @@
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
     EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
@@ -598,10 +618,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
     EXPECT_EQ(3, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
@@ -621,6 +643,8 @@
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
     EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
@@ -747,6 +771,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("_List._List", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("List.List", walker.CurrentName());
@@ -797,6 +823,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("_List._List", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("_GrowableList._GrowableList", walker.CurrentName());
@@ -857,6 +885,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateContext", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("foo", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -923,6 +953,8 @@
     EXPECT(walker.Down());
     EXPECT_SUBSTRING("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_SUBSTRING("foo", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -1080,8 +1112,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("String_concat", walker.CurrentName());
     EXPECT(walker.Down());
+#if 1
     EXPECT_STREQ("_StringBase.+", walker.CurrentName());
     EXPECT(walker.Down());
+#endif
     EXPECT_STREQ("foo", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -1286,11 +1320,13 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.SiblingCount());
     EXPECT_EQ(50000, walker.CurrentNodeTickCount());
     EXPECT_EQ(50000, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("mainA", walker.CurrentName());
     EXPECT_EQ(1, walker.SiblingCount());
@@ -1311,6 +1347,8 @@
     EXPECT_EQ(1, walker.SiblingCount());
     EXPECT_EQ(50000, walker.CurrentNodeTickCount());
     EXPECT_EQ(50000, walker.CurrentInclusiveTicks());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
     EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
@@ -1322,11 +1360,13 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.choo", walker.CurrentName());
     EXPECT_EQ(1, walker.SiblingCount());
     EXPECT_EQ(50000, walker.CurrentNodeTickCount());
     EXPECT_EQ(50000, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.foo", walker.CurrentName());
     EXPECT_EQ(1, walker.SiblingCount());
@@ -1373,6 +1413,8 @@
     EXPECT_EQ(1, walker.SiblingCount());
     EXPECT_EQ(50000, walker.CurrentNodeTickCount());
     EXPECT_EQ(50000, walker.CurrentInclusiveTicks());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
     EXPECT_EQ(50000, walker.CurrentExclusiveTicks());
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
@@ -1397,6 +1439,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Unoptimized Code]", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("[Optimized Code]", walker.CurrentName());
@@ -1416,6 +1462,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Unoptimized Code]", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
 
@@ -1425,6 +1475,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Unoptimized Code]", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("[Inline End]", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.choo", walker.CurrentName());
@@ -1446,8 +1500,6 @@
     // mainA -> B.boo -> B.foo -> B.choo.
     walker.Reset(Profile::kInclusiveFunction);
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized Code]", walker.CurrentName());
-    EXPECT(walker.Down());
     EXPECT_STREQ("mainA", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("[Optimized Code]", walker.CurrentName());
@@ -1462,6 +1514,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("[Inline End]", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Unoptimized Code]", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -1573,6 +1629,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("maybeAlloc", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("right", walker.CurrentName());
@@ -1580,10 +1638,12 @@
     EXPECT_STREQ("a", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("mainAlloc", walker.CurrentName());
+    EXPECT(walker.Down());  // Account for "[Native] [xxxxxxx, xxxxxxx)"
     EXPECT(!walker.Down());
 
     // Inline expansion should show us the complete call chain:
     walker.Reset(Profile::kInclusiveFunction);
+    EXPECT(walker.Down());  // Account for "[Native] [xxxxxxx, xxxxxxx)"
     EXPECT(walker.Down());
     EXPECT_STREQ("mainAlloc", walker.CurrentName());
     EXPECT(walker.Down());
@@ -1593,6 +1653,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("maybeAlloc", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -1667,6 +1729,8 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("orange", walker.CurrentName());
@@ -1768,10 +1832,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT_STREQ("A", walker.CurrentToken());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -1860,10 +1926,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT_STREQ("A", walker.CurrentToken());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -1945,10 +2013,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT_STREQ("A", walker.CurrentToken());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.oats", walker.CurrentName());
@@ -2068,10 +2138,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT_STREQ("A", walker.CurrentToken());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.oats", walker.CurrentName());
@@ -2174,10 +2246,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT_STREQ("A", walker.CurrentToken());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.oats", walker.CurrentName());
@@ -2306,10 +2380,12 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
+    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+    EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
     EXPECT_STREQ("A", walker.CurrentToken());
     EXPECT(walker.Down());
     EXPECT_STREQ("B.oats", walker.CurrentName());
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 427a196..b7a1b83 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -268,7 +268,7 @@
     SetReadException("Invalid object found in message.");
   }
   str_ ^= ReadObjectImpl(kAsInlinedObject);
-  cls = library_.LookupClass(str_);
+  cls = library_.LookupClassAllowPrivate(str_);
   if (cls.IsNull()) {
     SetReadException("Invalid object found in message.");
   }
@@ -299,7 +299,7 @@
     str_ ^= ReadObjectImpl(kAsInlinedObject);
     func ^= library_.LookupLocalFunction(str_);
   } else {
-    cls_ = library_.LookupClass(str_);
+    cls_ = library_.LookupClassAllowPrivate(str_);
     if (cls_.IsNull()) {
       SetReadException("Expected a class name, but found an invalid name.");
     }
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index dcc6cee..dfadde2 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -147,6 +147,7 @@
   // fields fp_ and sp_ when they return the respective frame objects.
   friend class FrameSetIterator;
   friend class StackFrameIterator;
+  friend class ProfilerDartStackWalker;
   DISALLOW_COPY_AND_ASSIGN(StackFrame);
 };
 
@@ -286,6 +287,7 @@
   StackFrame* current_frame_;  // Points to the current frame in the iterator.
   Thread* thread_;
 
+  friend class ProfilerDartStackWalker;
   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
 };
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index f15485b..f8a7996 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -367,11 +367,9 @@
   V(hashCode, "get:hashCode")                                                  \
   V(OptimizedOut, "<optimized out>")                                           \
   V(NotInitialized, "<not initialized>")                                       \
-  V(AllocationStubFor, "[Stub] Allocate ")                                     \
   V(TempParam, ":temp_param")                                                  \
   V(_UserTag, "_UserTag")                                                      \
   V(Default, "Default")                                                        \
-  V(StubPrefix, "[Stub] ")                                                     \
   V(ClassID, "ClassID")                                                        \
   V(DartIsVM, "dart.isVM")                                                     \
   V(stack, ":stack")                                                           \
diff --git a/samples/samples.status b/samples/samples.status
index fd8f581..2b249fd 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -17,9 +17,6 @@
 [ $compiler == dart2analyzer ]
 build_dart: Skip
 
-[ $arch == ia32 && $system == windows ]
-sample_extension/test/sample_extension_app_snapshot_test: RuntimeError # Issue 27786
-
 [ $arch == arm ]
 sample_extension/test/*: Skip # Issue 14705
 
diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
index beb67f2..0d61257 100644
--- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -431,8 +431,7 @@
   String toString() => Maps.mapToString(this);
 }
 
-class _HashMapKeyIterable<E> extends Iterable<E>
-                             implements EfficientLength {
+class _HashMapKeyIterable<E> extends EfficientLengthIterable<E> {
   final _map;
   _HashMapKeyIterable(this._map);
 
@@ -664,8 +663,7 @@
   String toString() => Maps.mapToString(this);
 }
 
-class _Es6MapIterable<E> extends Iterable<E>
-                         implements EfficientLength {
+class _Es6MapIterable<E> extends EfficientLengthIterable<E> {
   final _map;
   final bool _isKeys;
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart
index 004127b..447c74928 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_array.dart
@@ -146,7 +146,7 @@
   void insertAll(int index, Iterable<E> iterable) {
     checkGrowable('insertAll');
     RangeError.checkValueInInterval(index, 0, this.length, "index");
-    if (iterable is! EfficientLength) {
+    if (iterable is! EfficientLengthIterable) {
       iterable = iterable.toList();
     }
     int insertionLength = iterable.length;
@@ -463,7 +463,7 @@
   void replaceRange(int start, int end, Iterable<E> replacement) {
     checkGrowable('replace range');
     RangeError.checkValidRange(start, end, this.length);
-    if (replacement is! EfficientLength) {
+    if (replacement is! EfficientLengthIterable) {
       replacement = replacement.toList();
     }
     int removeLength = end - start;
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 4b21b3d..9368930 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -56,7 +56,7 @@
 import 'dart:_interceptors';
 import 'dart:_internal' as _symbol_dev;
 import 'dart:_internal' show
-    EfficientLength,
+    EfficientLengthIterable,
     MappedIterable,
     IterableElementError;
 
diff --git a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
index ada768f..98fad05 100644
--- a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -380,8 +380,7 @@
   LinkedHashMapCell(this.hashMapCellKey, this.hashMapCellValue);
 }
 
-class LinkedHashMapKeyIterable<E> extends Iterable<E>
-    implements EfficientLength {
+class LinkedHashMapKeyIterable<E> extends EfficientLengthIterable<E> {
   final dynamic/*=JsLinkedHashMap<E, dynamic>*/ _map;
   LinkedHashMapKeyIterable(this._map);
 
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
index 26ccb5c..edfce85 100644
--- a/sdk/lib/collection/iterable.dart
+++ b/sdk/lib/collection/iterable.dart
@@ -91,7 +91,7 @@
   Set<E> toSet() => new Set<E>.from(this);
 
   int get length {
-    assert(this is! EfficientLength);
+    assert(this is! EfficientLengthIterable);
     int count = 0;
     Iterator it = iterator;
     while (it.moveNext()) {
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 7e6dbd3a..8b6713a 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -395,7 +395,7 @@
 
   void replaceRange(int start, int end, Iterable<E> newContents) {
     RangeError.checkValidRange(start, end, this.length);
-    if (newContents is! EfficientLength) {
+    if (newContents is! EfficientLengthIterable) {
       newContents = newContents.toList();
     }
     int removeLength = end - start;
@@ -482,7 +482,7 @@
 
   void insertAll(int index, Iterable<E> iterable) {
     RangeError.checkValueInInterval(index, 0, length, "index");
-    if (iterable is! EfficientLength || identical(iterable, this)) {
+    if (iterable is! EfficientLengthIterable || identical(iterable, this)) {
       iterable = iterable.toList();
     }
     int insertionLength = iterable.length;
diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart
index 7871b87..d5b8621 100644
--- a/sdk/lib/collection/maps.dart
+++ b/sdk/lib/collection/maps.dart
@@ -111,8 +111,7 @@
  * It accesses the values by iterating over the keys of the map, and using the
  * map's `operator[]` to lookup the keys.
  */
-class _MapBaseValueIterable<K, V> extends Iterable<V>
-                                  implements EfficientLength {
+class _MapBaseValueIterable<K, V> extends EfficientLengthIterable<V> {
   final Map<K, V> _map;
   _MapBaseValueIterable(this._map);
 
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 386cf50..2e6a24a 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -17,7 +17,7 @@
  * This goes both for using the [iterator] directly, or for iterating an
  * `Iterable` returned by a method like [map] or [where].
  */
-abstract class Queue<E> implements Iterable<E>, EfficientLength {
+abstract class Queue<E> implements EfficientLengthIterable<E> {
 
   /**
    * Creates a queue.
@@ -487,7 +487,7 @@
       return queue;
     } else {
       int capacity = _INITIAL_CAPACITY;
-      if (elements is EfficientLength) {
+      if (elements is EfficientLengthIterable) {
         capacity = elements.length;
       }
       ListQueue<E> result = new ListQueue<E>(capacity);
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 72a2f52..9a41ef3 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -607,8 +607,7 @@
   T _getValue(_SplayTreeNode<K> node);
 }
 
-class _SplayTreeKeyIterable<K> extends Iterable<K>
-                               implements EfficientLength {
+class _SplayTreeKeyIterable<K> extends EfficientLengthIterable<K> {
   _SplayTree<K, _SplayTreeNode<K>> _tree;
   _SplayTreeKeyIterable(this._tree);
   int get length => _tree._count;
@@ -624,8 +623,7 @@
   }
 }
 
-class _SplayTreeValueIterable<K, V> extends Iterable<V>
-                                    implements EfficientLength {
+class _SplayTreeValueIterable<K, V> extends EfficientLengthIterable<V> {
   SplayTreeMap<K, V> _map;
   _SplayTreeValueIterable(this._map);
   int get length => _map._count;
diff --git a/sdk/lib/convert/codec.dart b/sdk/lib/convert/codec.dart
index 7f42c86..f4ff700 100644
--- a/sdk/lib/convert/codec.dart
+++ b/sdk/lib/convert/codec.dart
@@ -13,8 +13,6 @@
  *
  * Fused codecs generally attempt to optimize the operations and can be faster
  * than executing each step of an encoding separately.
- *
- * *Codecs are still experimental and are subject to change without notice.*
  */
 abstract class Codec<S, T> {
   const Codec();
@@ -99,4 +97,4 @@
   Converter<S, T> get decoder => _codec.encoder;
 
   Codec<S, T> get inverted => _codec;
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index aa9292e..9ea0c02 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -368,7 +368,7 @@
    * Some iterables have a more efficient way to find the number of elements.
    */
   int get length {
-    assert(this is! EfficientLength);
+    assert(this is! EfficientLengthIterable);
     int count = 0;
     Iterator it = iterator;
     while (it.moveNext()) {
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index d887e67..33e011c 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -51,7 +51,7 @@
  * directly or through iterating an [Iterable] that is backed by the list, will
  * break the iteration.
  */
-abstract class List<E> implements Iterable<E>, EfficientLength {
+abstract class List<E> implements EfficientLengthIterable<E> {
   /**
    * Creates a list of the given length.
    *
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index a4d7ed7..d2e9d8d 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -31,7 +31,7 @@
  * 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 Iterable<E> implements EfficientLength {
+abstract class Set<E> extends EfficientLengthIterable<E> {
   /**
    * Creates an empty [Set].
    *
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 0e7b171..73b3669 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -8,7 +8,8 @@
  * Marker interface for [Iterable] subclasses that have an efficient
  * [length] implementation.
  */
-abstract class EfficientLength {
+abstract class EfficientLengthIterable<T> extends Iterable<T> {
+  const EfficientLengthIterable();
   /**
    * Returns the number of elements in the iterable.
    *
@@ -24,8 +25,7 @@
  * All other methods are implemented in terms of [length] and [elementAt],
  * including [iterator].
  */
-abstract class ListIterable<E> extends Iterable<E>
-                               implements EfficientLength {
+abstract class ListIterable<E> extends EfficientLengthIterable<E> {
   int get length;
   E elementAt(int i);
 
@@ -354,7 +354,7 @@
   final _Transformation<S, T> _f;
 
   factory MappedIterable(Iterable<S> iterable, T function(S value)) {
-    if (iterable is EfficientLength) {
+    if (iterable is EfficientLengthIterable) {
       return new EfficientLengthMappedIterable<S, T>(iterable, function);
     }
     return new MappedIterable<S, T>._(iterable, function);
@@ -376,7 +376,7 @@
 }
 
 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T>
-                                          implements EfficientLength {
+    implements EfficientLengthIterable<T> {
   EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value))
       : super._(iterable, function);
 }
@@ -406,7 +406,7 @@
  * Expects efficient `length` and `elementAt` on the source iterable.
  */
 class MappedListIterable<S, T> extends ListIterable<T>
-                               implements EfficientLength {
+                               implements EfficientLengthIterable<T> {
   final Iterable<S> _source;
   final _Transformation<S, T> _f;
 
@@ -427,7 +427,7 @@
 
   Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f);
 
-  // Specialization of [Iterable.map] to non-EfficientLength.
+  // Specialization of [Iterable.map] to non-EfficientLengthIterable.
   Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) =>
      new MappedIterable<E, dynamic/*=T*/>._(this, f);
 }
@@ -500,7 +500,7 @@
     if (takeCount is! int || takeCount < 0) {
       throw new ArgumentError(takeCount);
     }
-    if (iterable is EfficientLength) {
+    if (iterable is EfficientLengthIterable) {
       return new EfficientLengthTakeIterable<E>(iterable, takeCount);
     }
     return new TakeIterable<E>._(iterable, takeCount);
@@ -514,7 +514,7 @@
 }
 
 class EfficientLengthTakeIterable<E> extends TakeIterable<E>
-                                     implements EfficientLength {
+                                     implements EfficientLengthIterable<E> {
   EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount)
       : super._(iterable, takeCount);
 
@@ -587,7 +587,7 @@
   final int _skipCount;
 
   factory SkipIterable(Iterable<E> iterable, int count) {
-    if (iterable is EfficientLength) {
+    if (iterable is EfficientLengthIterable) {
       return new EfficientLengthSkipIterable<E>(iterable, count);
     }
     return new SkipIterable<E>._(iterable, count);
@@ -614,7 +614,7 @@
 }
 
 class EfficientLengthSkipIterable<E> extends SkipIterable<E>
-                                     implements EfficientLength {
+                                     implements EfficientLengthIterable<E> {
   EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount)
       : super._(iterable, skipCount);
 
@@ -676,7 +676,7 @@
 /**
  * The always empty [Iterable].
  */
-class EmptyIterable<E> extends Iterable<E> implements EfficientLength {
+class EmptyIterable<E> extends EfficientLengthIterable<E> {
   const EmptyIterable();
 
   Iterator<E> get iterator => const EmptyIterator();
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 97507e5..990fb9c 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -4,16 +4,7 @@
 
 [ $compiler == dart2analyzer ]
 
-# Trailing commas are now allowed by the language - issue #26644
-Language/Functions/Formal_Parameters/syntax_t12: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t05: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t04: MissingCompileTimeError
-Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: MissingCompileTimeError
-# End issue #26644
-
+Language/Functions/Formal_Parameters/syntax_t05: StaticWarning # Issue 26644
 Language/Classes/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
 Language/Classes/Getters/static_getter_t02: CompileTimeError # Issue 24534
 Language/Classes/Getters/static_t01: StaticWarning # Please triage this failure.
@@ -37,7 +28,6 @@
 Language/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
 Language/Enums/syntax_t08: MissingCompileTimeError # Please triage this failure.
 Language/Enums/syntax_t09: MissingCompileTimeError # Please triage this failure.
-Language/Expressions/Assignable_Expressions/syntax_t08: StaticWarning
 Language/Expressions/Assignment/super_assignment_static_warning_t03: StaticWarning # Issue 15467
 Language/Expressions/Constants/exception_t01: fail, OK # co19 issue #438, Static variables are initialized lazily, need not be constants
 Language/Expressions/Constants/exception_t02: fail, OK # co19 issue #438, Static variables are initialized lazily, need not be constants
@@ -166,7 +156,6 @@
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t03: StaticWarning # Please triage this failure.
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure.
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure.
-Language/Libraries_and_Scripts/Imports/deferred_import_t02: CompileTimeError # co19 issue 60.
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError # Please triage this failure.
 Language/Libraries_and_Scripts/Parts/compilation_t01: Pass, MissingCompileTimeError # Issue 26692
 Language/Libraries_and_Scripts/Parts/compilation_t02: Pass, MissingCompileTimeError # Issue 26692
@@ -264,7 +253,6 @@
 LayoutTests/fast/dom/icon-url-list_t01: StaticWarning # Please triage this failure.
 LayoutTests/fast/dom/implementation-api-args_t01: StaticWarning # Please triage this failure.
 LayoutTests/fast/dom/javascript-backslash_t01: StaticWarning # Please triage this failure.
-LayoutTests/fast/dom/location-missing-arguments_t01: StaticWarning # Please triage this failure.
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # Please triage this failure. isProtocolHandlerRegistered and unregisterProtocolHandler don't exist
 LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning # Please triage this failure.
 LayoutTests/fast/dom/option-properties_t01: StaticWarning # Please triage this failure.
@@ -352,26 +340,6 @@
 LibTest/html/Window/requestFileSystem_A02_t01: StaticWarning # Please triage this failure.
 LibTest/html/Window/resizeBy_A01_t01: StaticWarning # Please triage this failure.
 LibTest/html/Window/resizeTo_A01_t01: StaticWarning # Please triage this failure.
-LibTest/isolate/Isolate/spawnUri_A02_t01: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawnUri_A02_t06: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawnUri_A02_t07: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A02_t04: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A02_t05: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A02_t06: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A02_t07: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A04_t01: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A04_t02: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A04_t03: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A04_t04: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A04_t05: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A05_t03: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t01: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t02: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t03: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t04: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t05: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t06: StaticWarning # co19 issue 74
-LibTest/isolate/Isolate/spawn_A06_t07: StaticWarning # co19 issue 74
 LibTest/isolate/IsolateStream/any_A01_t01: Fail # Please triage this failure.
 LibTest/isolate/IsolateStream/any_A02_t01: Fail # Please triage this failure.
 LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # Please triage this failure.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 1b57b2e..957c549 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -15,22 +15,9 @@
 # Tests that fail everywhere, including the analyzer.
 
 LibTest/typed_data/ByteData/buffer_A01_t01: Fail # co19 r736 bug - sent comment.
-
 LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
 
-Language/Functions/Formal_Parameters/Optional_Formals/syntax_t14: Fail # co19 issue 80
-
-[ $system == linux ]
-LibTest/collection/ListBase/ListBase_class_A01_t01: Fail # co19 issue 72
-LibTest/collection/ListBase/ListBase_class_A01_t02: Fail # co19 issue 72
-LibTest/collection/ListBase/listToString_A01_t01: Fail # co19 issue 72
-LibTest/collection/ListBase/listToString_A02_t01: Fail # co19 issue 72
-LibTest/collection/MapBase/MapBase_class_A01_t01: Fail # co19 issue 72
-LibTest/collection/MapMixin/MapMixin_class_A01_t01: Fail # co19 issue 72
-
 [ $compiler != dart2analyzer ]
-LibTest/isolate/ReceivePort/take_A01_t02: Fail # co19 issue 81
-LibTest/async/Stream/take_A01_t02: Fail # co19 issue 81
 # Tests that fail on every runtime, but not on the analyzer.
 Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # Issue 14513,25525
 Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # Issue 14513,25525
@@ -38,7 +25,6 @@
 Language/Expressions/Instance_Creation/Const/abstract_class_t03: Pass, Fail # co19 issue 66
 LibTest/async/Stream/asBroadcastStream_A02_t01: Fail # co19 issue 687
 LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: RuntimeError # Issue 27183
-LibTest/collection/LinkedListEntry/unlink_A01_t02: Fail # co19 pull request 73
 LibTest/core/Expando/Expando_A03_t01: RuntimeError # Issue 17735
 LibTest/core/Expando/Expando_A03_t03: RuntimeError # Issue 17735
 LibTest/core/Expando/Expando_A03_t04: RuntimeError # Issue 17735
@@ -82,13 +68,7 @@
 [ $runtime == dartium || $compiler == dart2js ]
 LibTest/async/Future/Future.delayed_A01_t02: Pass, Fail # Issue 15524
 
-[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == drt || $runtime == dartium || $runtime == dart_precompiled || $runtime == dart_app) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == drt || $runtime == dart_precompiled || $runtime == dart_app) ]
 # Optional trailing commas for argument and parameter lists added to language.
 # https://github.com/dart-lang/co19/issues/68
-Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: Fail, OK
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: Fail, OK
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: Fail, OK
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: Fail, OK
-Language/Functions/Formal_Parameters/syntax_t04: Fail, OK
 Language/Functions/Formal_Parameters/syntax_t05: Fail, OK
-Language/Functions/Formal_Parameters/syntax_t12: Fail, OK
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index a5fdba2..7de6fe8 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,18 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-# Trailing commas are now allowed by the language - issue #26644
-Language/Functions/Formal_Parameters/syntax_t12: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t05: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t04: MissingCompileTimeError
-Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: MissingCompileTimeError
-# End of issue 26644
-Language/Variables/final_t01/01: CompileTimeError # co19 issue 77
-Language/Variables/final_t02/01: CompileTimeError # co19 issue 77
-LibTest/isolate/Isolate/spawn_A03_t01: CompileTimeError # co19 issue 77
+Language/Functions/Formal_Parameters/syntax_t05: RuntimeError # Issue 26644
 
 Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError # compiler cancelled: cannot resolve type T
 Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError, OK # co19 issue 258
@@ -240,11 +229,11 @@
 Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t08: CompileTimeError # Please triage this failure
 Language/Expressions/Property_Extraction/Super_Closurization: CompileTimeError # Issue 26287
 Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: RuntimeError # Please triage this failure
+Language/Expressions/Shift/syntax_t01/14: MissingRuntimeError # Please triage this failure
 Language/Functions/External_Functions/not_connected_to_a_body_t01: CompileTimeError, OK # Issue 5021
 Language/Generics/syntax_t17: fail # Issue 21203
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/Imports/deferred_import_t02: CompileTimeError # co19 issue 60
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01/01: CompileTimeError # Please triage this failure
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError # Please triage this failure
 Language/Libraries_and_Scripts/Scripts/top_level_main_t05: RuntimeError # Please triage this failure
@@ -290,6 +279,8 @@
 Language/Types/Interface_Types/subtype_t27: Skip # Times out or crashes. Issue 21174
 Language/Types/Interface_Types/subtype_t28: Pass, Fail, Crash # Stack overflow. Issue 25282
 Language/Types/Interface_Types/subtype_t30: fail # Issue 14654
+Language/Variables/final_t01/01: CompileTimeError # co19 issue 77
+Language/Variables/final_t02/01: CompileTimeError # co19 issue 77
 Language/Variables/local_variable_t01: MissingCompileTimeError # Issue 21050
 LayoutTests/fast/dom/css-innerHTML_t01: SkipByDesign # Test is incorrect.
 LayoutTests/fast/loader/loadInProgress_t01: Skip # Issue 23466
@@ -495,8 +486,28 @@
 LibTest/core/Map/Map_class_A01_t04: Slow, Pass
 LibTest/core/Uri/Uri_A06_t03: Slow, Pass
 LibTest/math/Point/operator_mult_A02_t01: RuntimeError # Issue 1533
-LibTest/typed_data/Float32x4List/reduce_A01_t01: Fail # co19 issue 78
-LibTest/typed_data/Float32x4List/lastWhere_A02_t01: Fail # co19 issue 78
+
+[ $compiler == dart2js && $checked && $runtime != d8]
+LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/url/trivial_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/url/trivial-segments_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $checked && $runtime != drt && $runtime != d8]
+LayoutTests/fast/forms/change-form-element-document-crash_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/isAttribute_A02_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-002_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime != drt && $runtime != d8 && $runtime != jsshell && $runtime != chrome]
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-001_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $checked && $runtime != ff && $runtime != d8 && $runtime != drt]
+LayoutTests/fast/dom/clone-node-load-event-crash_t01: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $fast_startup ]
 Language/Classes/Instance_Methods/Operators/unary_minus: Fail # mirrors not supported
@@ -582,11 +593,6 @@
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: Fail # please triage
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: Fail # please triage
 
-[ $compiler == dart2js && $runtime == chrome && $fast_startup && $checked ]
-WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/isAttribute_A02_t01: RuntimeError # Please triage this failure
-
 [ $compiler == dart2js && $fast_startup && $browser && $runtime != chrome && $runtime != drt]
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005_t01: Fail # please triage
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-001_t01: Fail # please triage
@@ -664,6 +670,9 @@
 Language/Expressions/Property_Extraction/General_Super_Property_Extraction/getter_lookup_t02: Timeout, Skip # Please triage this failure
 Language/Expressions/Property_Extraction/Super_Closurization/setter_closurization_t09: CompileTimeError # Please triage this failure
 
+[ $compiler == dart2js && $checked != true && $runtime != d8 && $runtime != jsshell]
+LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # Please triage this failure
+
 [ $compiler == dart2js && $minified ]
 LibTest/typed_data/Float32List/runtimeType_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32x4List/runtimeType_A01_t01: fail # co19-roll r559: Please triage this failure
@@ -741,7 +750,7 @@
 LibTest/core/Stopwatch/start_A01_t03: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Uri/Uri_A06_t03: Pass, Slow
-LibTest/isolate/Isolate/spawn_A03_t01: Pass # co19 issue 77
+LibTest/isolate/Isolate/spawn_A03_t01: RuntimeError # Please triage this failure
 LibTest/isolate/Isolate/spawn_A03_t03: RuntimeError # Please triage this failure
 LibTest/isolate/Isolate/spawn_A03_t04: RuntimeError # Please triage this failure
 LibTest/isolate/Isolate/spawn_A04_t02: RuntimeError # Please triage this failure
@@ -810,8 +819,6 @@
 LibTest/async/DeferredLibrary/*: Skip # Issue 17458
 
 [ $compiler == dart2js && $browser ]
-Language/Classes/deсlarations_t01: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
 LayoutTests/fast/mediastream/getusermedia_t01: Pass, RuntimeError, Timeout # Please triage this failure.
 LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
@@ -995,6 +1002,7 @@
 LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, Timeout # Please triage this failure
+LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
@@ -1065,7 +1073,6 @@
 LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content/content-quotes-05_t01: RuntimeError # Issue https://github.com/dart-lang/co19/issues/46
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
@@ -1431,8 +1438,10 @@
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: RuntimeError # Please triage this failure
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
 LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/speechsynthesis/speech-synthesis-cancel_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/speechsynthesis/speech-synthesis-pause-resume_t01: Skip # Times out. Please triage this failure
@@ -1475,6 +1484,7 @@
 LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # Please triage this failure
@@ -1482,6 +1492,7 @@
 LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/url/file-http-base_t01: RuntimeError # Please triage this failure
@@ -1519,7 +1530,6 @@
 LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/position_t01: RuntimeError # Please triage this failure
@@ -1790,7 +1800,9 @@
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
 
-[ $compiler == dart2js && $runtime == chrome && $checked ]
+[ $compiler == dart2js && $runtime == chrome && $checked]
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: RuntimeError # Please triage this failure
@@ -1830,13 +1842,13 @@
 LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/css-table-width-with-border-padding_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/css-table-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/fixed-table-layout-width-change_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/html-table-width-max-width-constrained_t01: RuntimeError # Please triage this failure
@@ -1847,13 +1859,11 @@
 LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/table-width-exceeding-max-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-bad-mimetype_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # Please triage this failure
-LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # Issue 18251
 LibTest/html/Element/Element.tag_A01_t01: RuntimeError # Please triage this failure
+LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # Issue 18251
 WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # Please triage this failure
@@ -1883,6 +1893,10 @@
 LibTest/isolate/Isolate/spawn_A01_t05: Skip # Times out. Please triage this failure
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Skip # Times out. Please triage this failure
 
+[ $compiler == dart2js && $runtime == chrome && $system == windows ]
+Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t04: Pass, Slow # Issue 25940
+Language/Expressions/Bitwise_Expressions/method_invocation_super_t01: Pass, Slow # Issue 25940
+
 [ $compiler == dart2js && $runtime == chrome && $system != macos ]
 LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Please triage this failure
@@ -1937,7 +1951,6 @@
 LayoutTests/fast/canvas/webgl/null-uniform-location_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/program-test_t01: RuntimeError # Please triage this failure
@@ -1977,24 +1990,18 @@
 LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-exceptions_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-unprefixed-context-id_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime == chrome && $system == linux]
 LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
+LayoutTests/fast/text/international/combining-marks-position_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/regional-indicator-symobls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
-
-[ $compiler == dart2js && $runtime == chrome && $system == windows ]
-Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t04: Pass, Slow # Issue 25940
-Language/Expressions/Bitwise_Expressions/method_invocation_super_t01: Pass, Slow # Issue 25940
-LibTest/isolate/Isolate/spawn_A04_t04: Skip # Times out. Please triage this failure
-
-[ $compiler == dart2js && $runtime == chrome && $system == linux]
-LayoutTests/fast/text/international/combining-marks-position_t01: RuntimeError # Please triage this failure
 LibTest/math/log_A01_t01: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $runtime == drt ]
@@ -2674,6 +2681,9 @@
 LayoutTests/fast/dom/HTMLScriptElement/remove-source_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # Please triage this failure
 
+[ $compiler == dart2js && $runtime == drt && ($fast_startup != true || $checked != true) ]
+WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
+
 [ $compiler == dart2js && $runtime == drt && $fast_startup && $checked ]
 LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: RuntimeError # Please triage this failure
@@ -2725,7 +2735,6 @@
 LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/html/article-element_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/html/aside-element_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
@@ -2733,7 +2742,6 @@
 LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # Please triage this failure
@@ -2748,17 +2756,12 @@
 LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/url/trivial-segments_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/url/trivial_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # Please triage this failure
 LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # Please triage this failure
 WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # Please triage this failure
@@ -2795,7 +2798,6 @@
 LayoutTests/fast/canvas/alpha_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-blend-solid_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-composite-canvas_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-composite-image_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # Please triage this failure
@@ -2806,7 +2808,6 @@
 LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-fill-zeroSizeGradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-fillRect-zeroSizeGradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-fillText-invalid-maxWidth_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-fillText-zeroSizeGradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-font-ex-units-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-frameless-document-text_t01: RuntimeError # Please triage this failure
@@ -2830,7 +2831,6 @@
 LayoutTests/fast/canvas/canvas-strokeRect-alpha-shadow_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-strokeRect-gradient-shadow_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-strokeRect-zeroSizeGradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-strokeText-invalid-maxWidth_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-strokeText-zeroSizeGradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-toDataURL-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
@@ -2838,10 +2838,13 @@
 LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/rgba-parsing_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Issue 27872
 LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 26898
 LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, RuntimeError # Issue 26898
 LayoutTests/fast/canvas/webgl/context-lost_t01: Pass, RuntimeError # Issue 26898
+LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: RuntimeError # Issue 27872
+LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: Skip # Times out.
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
@@ -2849,7 +2852,6 @@
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
@@ -3219,7 +3221,6 @@
 LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/window-screen-properties_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # Issue 22564
-LayoutTests/fast/dom/XMLSerializer-attribute-entities_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/anchor-origin_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # Please triage this failure
@@ -3230,6 +3231,7 @@
 LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/containerNode_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/createElementNS-namespace-errors_t01: RuntimeError # Issue 27873
 LayoutTests/fast/dom/css-delete-doc_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/css-rule-functions_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # Please triage this failure
@@ -3428,7 +3430,6 @@
 LayoutTests/fast/filesystem/filesystem-reference_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/filesystem-unserializable_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/filesystem-uri-origin_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/filesystem/input-access-entries_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/op-copy_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/op-get-entry_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/op-get-metadata_t01: RuntimeError # Please triage this failure
@@ -3777,7 +3778,6 @@
 LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/position_t01: RuntimeError # Please triage this failure
@@ -3971,7 +3971,7 @@
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # Please triage this failure
@@ -4015,7 +4015,6 @@
 WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: Pass, RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/tabular-data/the-caption-element/caption_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/tabular-data/the-table-element/caption-methods_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/tabular-data/the-table-element/table-insertRow_t01: RuntimeError # Please triage this failure
@@ -4133,19 +4132,63 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure. Note that Chrome also requires the Slow flag. (Could just be a slow test).
 WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
+[ $compiler == dart2js && $runtime == ff && $checked == false]
+LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime == ff && $system == macos]
+LayoutTests/fast/canvas/canvas-modify-emptyPath_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/innerHTML/005_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/html/draggable_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/ruby/modify-positioned-ruby-text-crash_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t03: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime == ff && $checked]
+LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-imageSmoothingEnabled-zero-size_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/css-table-width_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # Please triage this failure
+LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # Please triage this failure
+WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # Please triage this failure
+WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # Please triage this failure
+
 [ $compiler == dart2js && $runtime == ff && $system == windows ]
-LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # Issue 22564
 Language/Classes/Getters/type_object_t02: RuntimeError, Slow # Issue 25940
 Language/Classes/Abstract_Instance_Members/override_no_named_parameters_t06: Pass, Slow # Issue 25940
 Language/Classes/Constructors/Factories/return_type_t03: Pass, Slow # Issue 25940
 Language/Classes/Constructors/Factories/return_wrong_type_t02: Pass, Slow # Issue 25940
 Language/Classes/Constructors/Factories/return_type_t05: Pass, Slow # Issue 25940
+LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # Issue 22564
 
 [ $compiler == dart2js && $runtime == ff && $system != windows ]
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
@@ -4155,6 +4198,10 @@
 LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Skip # Times out always
 LayoutTests/fast/canvas/webgl/texture-complete_t01: Skip # Times out sometimes
 LayoutTests/fast/canvas/webgl/texture-npot_t01: Skip # Times out sometimes
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime == ff && $system != linux]
+LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $runtime == safari ]
 Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
@@ -6635,6 +6682,7 @@
 
 [ $compiler == dart2js && $runtime == ie10 ]
 Language/Expressions/Top_level_Getter_Invocation/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
+Language/Statements/If/type_t06: Skip # Times out on Windows 8. Please triage this failure
 Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
 Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
@@ -6729,7 +6777,7 @@
 LayoutTests/fast/canvas/canvas-set-properties-with-non-invertible-ctm_t01: Pass, RuntimeError # Issue 22216
 LayoutTests/fast/canvas/canvas-setTransform_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-to-canvas_t01: Pass, RuntimeError # Issue 22216
-LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow_t01: Pass, RuntimeError # Passes on Windows 8. Please triage this failure
 LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/drawImage-with-bad-canvas_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/canvas/drawImage-with-negative-source-destination_t01: Pass, RuntimeError # Issue 22216
@@ -7989,6 +8037,7 @@
 LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-html-no-responsetype_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-document-responsetype_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: RuntimeError # Please triage this failure
@@ -8056,6 +8105,7 @@
 LayoutTests/fast/xsl/xslt-string-parameters_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/xslt-transform-to-fragment-crash_t01: RuntimeError # Please triage this failure
 LibTest/async/Future/doWhile_A05_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
+LibTest/async/Future/forEach_A04_t02: RuntimeError # Please triage this failure
 LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/async/Stream/timeout_A01_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
 LibTest/async/Stream/timeout_A03_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
@@ -8106,9 +8156,9 @@
 LibTest/html/Element/leftView_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/loadEvent_A01_t01: Skip # Times out. Please triage this failure
 LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out, Issue 23437
-LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out, Issue 23437
 LibTest/html/Element/onFocus_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/html/Element/onLoad_A01_t01: Skip # Times out. Please triage this failure
+LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out, Issue 23437
 LibTest/html/Element/ownerDocument_A01_t05: RuntimeError # Please triage this failure
 LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # Please triage this failure
 LibTest/html/Element/replaceWith_A01_t02: RuntimeError # Please triage this failure
@@ -8422,9 +8472,9 @@
 WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-table-insertion-mode/end-tag-table_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/appending-to-a-template/template-child-nodes_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/serializing-html-templates/outerhtml_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/template-element/content-attribute_t01: RuntimeError # Please triage this failure
@@ -8641,15 +8691,15 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $runtime == ie11 ]
-Language/Variables/implicit_setter_void_t07: Skip # Times out. Please triage this failure
-Language/Functions/Formal_Parameters/scope_t01: Skip # Times out. Please triage this failure
 Language/Expressions/Conditional/type_t04: Skip # Times out. Please triage this failure
 Language/Expressions/Identifier_Reference/evaluation_function_t02: Skip # Times out. Please triage this failure
+Language/Functions/Formal_Parameters/scope_t01: Skip # Times out. Please triage this failure
 Language/Statements/Local_Variable_Declaration/syntax_t18: Skip # Times out. Please triage this failure
 Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
 Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
-Language/Types/Interface_Types/subtype_t37: Skip # Times out. Please triage this failure
 Language/Types/Function_Types/subtype_no_args_t03: Skip # Times out. Please triage this failure
+Language/Types/Interface_Types/subtype_t37: Skip # Times out. Please triage this failure
+Language/Variables/implicit_setter_void_t07: Skip # Times out. Please triage this failure
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -8829,9 +8879,9 @@
 LayoutTests/fast/canvas/winding-enumeration_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/block-after_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # Please triage this failure
@@ -9298,7 +9348,6 @@
 LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/XMLSerializer-attribute-entities_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/XMLSerializer-attribute-namespaces_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/XMLSerializer-element-ns-no-reemit_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/allowed-children_t01: RuntimeError # Please triage this failure
@@ -9383,7 +9432,6 @@
 LayoutTests/fast/dom/partial-layout-non-overlay-scrollbars_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/remove-body-during-body-replacement_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/dom/serialize-attribute_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/setAttribute-using-initial-input-value_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/setAttributeNS-namespace-errors_t01: RuntimeError # Please triage this failure
@@ -10058,10 +10106,10 @@
 LibTest/html/Element/loadEvent_A01_t01: Skip # Times out. Please triage this failure
 LibTest/html/Element/marginEdge_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out, Issue 23437
-LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out, Issue 23437
 LibTest/html/Element/onError_A01_t01: Skip # Times out. Please triage this failure
 LibTest/html/Element/onFocus_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/html/Element/onLoad_A01_t01: Skip # Times out. Please triage this failure
+LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out, Issue 23437
 LibTest/html/Element/ownerDocument_A01_t05: RuntimeError # Please triage this failure
 LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # Please triage this failure
@@ -10151,7 +10199,6 @@
 LibTest/html/Window/resizeTo_A01_t01: RuntimeError # Please triage this failure
 LibTest/math/sqrt_A02_t02: Skip # Times out. Please triage this failure
 LibTest/typed_data/ByteData/ByteData.view_A01_t01: Pass, RuntimeError # Please triage this failure
-LibTest/typed_data/ByteData/offsetInBytes_A01_t01: RuntimeError # Please triage this failure
 LibTest/typed_data/Float32List/removeWhere_A01_t01: Skip # Times out. Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: RuntimeError # Please triage this failure
 LibTest/typed_data/Int32List/lastWhere_A01_t01: Skip # Times out. Please triage this failure
@@ -10247,9 +10294,9 @@
 WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-table-insertion-mode/end-tag-table_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/appending-to-a-template/template-child-nodes_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/serializing-html-templates/outerhtml_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html-templates/template-element/content-attribute_t01: RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index f2d3d8a..3f61aa96 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -5,6 +5,1206 @@
 [ $compiler == none && $runtime == drt ]
 *: Skip # running co19 tests on content_shell would make our dartium cycle-times very long
 
+[ $compiler == none && $runtime == dartium ]
+Language/Classes/Constructors/Generative_Constructors/execution_t03: Fail, OK
+Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
+Language/Classes/declarations_t01: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t02: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t03: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t04: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t06: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t08: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t12: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t13: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t14: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t15: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t16: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t17: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t18: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t19: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t20: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t21: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t22: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t23: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t24: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t25: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t26: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t27: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t28: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t29: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t30: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t31: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t32: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t33: Skip # Times out. Please triage this failure.
+Language/Classes/declarations_t34: Skip # Times out. Please triage this failure.
+Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure.
+Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure.
+Language/Expressions/Assignment/super_assignment_failed_t05: RuntimeError # Issue 25671
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out. Issue 25967
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out. Issue 25967
+Language/Expressions/Identifier_Reference/built_in_identifier_t35: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t36: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t37: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t53: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t54: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t55: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t56: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t57: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t58: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t59: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t60: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t61: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t62: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t63: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t64: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t65: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t66: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t67: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t68: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t14: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t19: Fail # Issue 25772
+Language/Expressions/Instance_Creation/New/execution_t04: Fail, OK
+Language/Expressions/Instance_Creation/New/execution_t06: Fail, OK
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: RuntimeError # Issue 24607
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction: RuntimeError # Issue 26287
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+Language/Expressions/Property_Extraction/Super_Closurization: RuntimeError # Issue 26287
+Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError, OK  # Uses Isolate.spawn.
+Language/Functions/Formal_Parameters/syntax_t05: RuntimeError # Issue 26644
+Language/Libraries_and_Scripts/Exports/reexport_t01: fail # Dart issue 12916
+Language/Libraries_and_Scripts/Exports/reexport_t02: fail # Dart issue 12916
+Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
+Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
+Language/Libraries_and_Scripts/Scripts/top_level_main_t03: Pass # Issue 14478: This should break.
+Language/Libraries_and_Scripts/Scripts/top_level_main_t03: RuntimeError # co19-roll r786: Please triage this failure.
+Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
+Language/Mixins/declaring_constructor_t05: Fail # Issue 24767
+Language/Mixins/declaring_constructor_t06: Fail # Issue 24767
+Language/Mixins/Mixin_Application/syntax_t16: RuntimeError # Please triage this failure.
+Language/Mixins/not_object_superclass_t01: Fail # Please triage this failure.
+Language/Mixins/reference_to_super_t01: Fail # Please triage this failure.
+Language/Statements/Assert/execution_t02: skip # co19 issue 734
+Language/Statements/Assert/execution_t03: skip # co19 issue 734
+Language/Statements/Assert/type_t02: skip # co19 issue 734
+Language/Statements/Assert/type_t05: skip # co19 issue 734
+Language/Statements/Continue/async_loops_t10: Timeout, Skip # Issue 25748
+Language/Statements/Labels/syntax_t03: fail # Dart issue 2238
+Language/Statements/Switch/syntax_t02: fail # Dart issue 12908
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05: RuntimeError # Issue 25662,25634
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t02: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Please triage this failure
+LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/borders/border-radius-child_t01: Skip # co19 issue 732.
+LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.veryLarge_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.verySmall_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is behind a flag in Chrome
+LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-large-dimensions_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-large-fills_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-lose-restore-googol-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-lose-restore-max-int-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/drawImage-with-broken-image_t01: Timeout, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Causes following tests to fail. co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure. Issue 22026
+LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/error-reporting_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/get-active-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-get-calls_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-getstring_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/shader-precision-format_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-complete_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-npot_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/viewport-unchanged-upon-resize_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-specific_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
+LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-display_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/justify-self-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Skip # 45 Roll failure.
+LayoutTests/fast/css/aspect-ratio-inheritance_t01: Skip # 45 Roll No longer supported.
+LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: Skip # 45 Roll No longer supported.
+LayoutTests/fast/css/auto-min-size_t01: RuntimeError #  45 Roll co19 test rewrite issue 25807
+LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/fontfaceset-events_t01: Pass, RuntimeError # Issue 23433
+LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-2_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-3_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError #  45 Roll co19 test rewrite issue 25807
+LayoutTests/fast/css/parsing-object-position_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-line_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-underline-position_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/computed-style-set-property_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/computed-style-set-property_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/createDocumentType2_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/createDocumentType2_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/createElementNS_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/createElementNS_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
+LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Bad test can't register HtmlElement.
+LayoutTests/fast/dom/custom/document-register-namespace_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/document-register-namespace_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/custom/document-register-type-extensions_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/document-register-type-extensions_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/element-names_t01: RuntimeError # 45 Roll issue dart-lang/co19/issues/25
+LayoutTests/fast/dom/custom/element-type_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/element-type_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/element-upgrade_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/custom/element-upgrade_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Document/createElement-invalid-names_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Document/createElement-invalid-names_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/DOMException/prototype-object_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/DOMException/prototype-object_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLImageElement/image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLImageElement/parse-src_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
+LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # co19-roll r722: Issue 18127
+LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # co19-roll r722: Issue 18250
+LayoutTests/fast/dom/HTMLTemplateElement/cycles_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLTemplateElement/cycles_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLTemplateElement/cycles-in-shadow_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLTemplateElement/cycles-in-shadow_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # co19-roll r722: Issue 18249
+LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/dom/MutationObserver/observe-childList_t01: RuntimeError # co19-roll r722: Issue 18253
+LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/dom/Node/contains-method_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Node/contains-method_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-hierarchy-exception_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-hierarchy-exception_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-image_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/insertAdjacentElement_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/encoding/css-charset-dom_t01: Skip #  45 Roll No longer supported see issue https://github.com/dart-lang/co19/issues/35
+LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Skip # Timeout. Please triage this failure.
+LayoutTests/fast/events/clipboard-clearData_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/document-elementFromPoint_t01: Skip # co19 issue 732.
+LayoutTests/fast/events/event-creation_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/initkeyboardevent-crash_t01: RuntimeError, Timeout # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/input-focus-no-duplicate-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/invalid-003_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/invalid-004_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/label-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/mutation-during-append-child_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/events/mutation-during-append-child_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/events/mutation-during-insert-before_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/events/mutation-during-insert-before_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/events/mutation-during-replace-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/mutation-during-replace-child-2_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Flaky timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip #  45 Roll No longer supported.
+LayoutTests/fast/events/scoped/editing-commands_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/scroll-event-does-not-bubble_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/exclusions/parsing/parsing-wrap-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/exclusions/parsing/parsing-wrap-through_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-close_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-close-read_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-close-revoke_t01: RuntimeError # Experimental feature not exposed anywhere yet
+LayoutTests/fast/files/xhr-response-blob_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/async-operations_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/filesystem/file-entry-to-uri_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-abort-depth_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-gc-blob_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-write-overlapped_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/read-directory-many_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/filesystem/simple-readonly_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Experimental feature not exposed in Chrome yet
+LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/HTMLOptionElement_selected2_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Experimental feature not exposed in Chrome yet
+LayoutTests/fast/forms/input-value-sanitization_t01: RuntimeError # 45 roll issue
+LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/listbox-select-all_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/menulist-selection-reset_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/menulist-submit-without-selection_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/missing-action_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/multiple-selected-options-innerHTML_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/option-change-single-selected_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/option-strip-unicode-spaces_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/parser-associated-form-removal_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/search-popup-crasher_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-clientheight-large-size_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-ancestor-dir-attribute_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/submit-nil-value-field-assert_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/textarea-paste-newline_t01: Pass, RuntimeError # Issue 23433
+LayoutTests/fast/forms/textarea-scrollbar-height_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError # co19 issue 11.
+LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # co19-roll r722: Please triage this failure.
+LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/boundingBox-with-continuation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/inline-position-top-align_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/loadInProgress_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Skip # Times out. Dartium 45 roll: Please triage this failure.
+LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/media/media-query-list-syntax_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
+LayoutTests/fast/mediastream/getusermedia_t01: Skip # co19 issue 738
+LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
+LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475 # co19 issue 11.
+LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t06: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t07: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t07: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t08: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t08: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t09: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t09: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes. # co19 issue 11.
+LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
+LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari # co19 issue 11.
+LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/overflow/scrollbar-restored_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Skip # Times out: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Skip # Times out: Please triage this failure.
+LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/speechsynthesis/*: Skip # Times out on Dartium. Fails elsewhere. Issue 22017
+LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/inline-block-with-padding_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others # co19 issue 11.
+LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
+LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
+LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 732.
+LayoutTests/fast/table/computeLogicalWidth-table-needsSectionRecalc_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox # co19 issue 11.
+LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip # co19 issue 11.
+LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/min-width-css-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-css-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-html-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/nested-tables-with-div-offset_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
+LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
+LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes. # co19 issue 11.
+LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail. # co19 issue 11.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
+LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail # co19 issue 11.
+LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed. # co19 issue 11.
+LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox. # co19 issue 11.
+LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test. # co19 issue 11.
+LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
+LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
+LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
+LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Please triage this failure.
+LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 22200
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/clone_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/insertAllBefore_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/Document/insertBefore_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/Document/securityPolicy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Document/text_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/Element/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/contentEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/dataset_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
+LibTest/html/Element/getAttributeNS_A01_t02: RuntimeError # Please triage this failure.
+LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
+LibTest/html/Element/insertAllBefore_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/Element/insertBefore_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/Element/replaceWith_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Element/text_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/HttpRequest/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/responseType_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
+LibTest/html/IFrameElement/appendHtml_A01_t02: RuntimeError # Issue 23462
+LibTest/html/IFrameElement/attributeChanged_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/attributes_setter_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/IFrameElement/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/contentWindow_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createFragment_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/createShadowRoot_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/enteredView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/IFrameElement.created_A01_t01: RuntimeError # Issue 24568
+LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/insertAllBefore_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/IFrameElement/insertBefore_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/leftView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
+LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Issue 16574
+LibTest/html/IFrameElement/querySelector_A01_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/IFrameElement/setInnerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Node/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/append_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/nodes_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Window/document_A01_t01: Skip # accesses window.document from a cross-frame window
+LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/moveBy_A01_t01: RuntimeError # Please triage this failure.
+LibTest/html/Window/moveTo_A01_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/postMessage_A01_t02: RuntimeError # Please triage this failure.
+LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
+LibTest/html/Window/requestFileSystem_A02_t01: Skip # Issue 24585.
+LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t06: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A03_t01: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A03_t02: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A03_t03: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A03_t04: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A04_t01: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A04_t02: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A04_t03: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A04_t04: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A04_t05: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A05_t01: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A05_t02: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A05_t03: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t01: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t02: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t03: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t04: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t05: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t06: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawn_A06_t07: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawnUri_A01_t01: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t03: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t04: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A01_t06: RuntimeError # Issue 27219
+LibTest/isolate/Isolate/spawnUri_A01_t07: RuntimeError # Issue 27219
+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/RawReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/RawReceivePort/handler_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/RawReceivePort/sendPort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/close_A02_t01: Skip # Times out
+LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/drain_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/every_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/expand_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/first_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/first_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/first_A02_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/firstWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/firstWhere_A03_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/fold_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/fold_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/forEach_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/isEmpty_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/join_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/join_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/last_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/last_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/lastWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/lastWhere_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/length_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/listen_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/map_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/pipe_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/reduce_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/reduce_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/reduce_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
+LibTest/isolate/ReceivePort/single_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/single_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/singleWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/skip_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/skipWhile_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/take_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/take_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/take_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/takeWhile_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/toList_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/toSet_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
+LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
+WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/events/event_constants/constants_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/event_constructors/Event_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/event_constructors/Event_A02_t01: Skip # co19-roll r706.  Please triage this failure.
+WebPlatformTest/dom/events/type_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/Node-replaceChild_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttribute_A01_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttribute_A01_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttribute_A03_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A06_t03: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t03: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/attributes/setAttributeNS_A08_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-adoptNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElement_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-createElementNS_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Document-getElementsByTagName_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Element-childElementCount_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-appendChild_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/Node-appendChild_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/Node-appendChild_t02: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-insertBefore_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-isEqualNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/dom/nodes/Node-nodeName_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/dom/nodes/Node-replaceChild_t01: RuntimeError # co19-roll r722: Please triage this failure
+WebPlatformTest/dom/nodes/Node-textContent_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/EventObject.multiple.dispatchEvent_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. co19-roll r738: Please triage this failure.
+WebPlatformTest/html-imports/link-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-imports/link-import_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-imports/link-import-null_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html-imports/loading-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html-templates/innerhtml-on-templates/innerhtml_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Skip # accesses window.document from a cross-frame window
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-namespace_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-newelements_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-param_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t05: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t02: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t03: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t05: RuntimeError # co19 issue 11.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/disabled-elements/disabledElement_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Dartium 45 roll
+WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
+WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-autocomplete_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-elements-matches_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-elements-nameditem_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-form-element/form-nameditem_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/forms/the-input-element/date_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/datetime-local_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/email_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/email_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/input-textselection_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/month_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/pattern_attribute_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/forms/the-input-element/range_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-option-element/option-text-recurse_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: Skip # co19 issue 11.
+WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: Skip # co19 issue 11.
+WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/checked_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/default_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/dir_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: Pass, RuntimeError # Spurious pass # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/semantics/text-level-semantics/the-a-element/a.text-getter_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
+WebPlatformTest/html/syntax/parsing/math-parse_t01: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # co19 issue 11.
+WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Tests APIs that aren't yet visible. Tests should be deleted.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/33
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-005_t01: RuntimeError #  45 Roll co19 test rewrite issue 25807
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Not clear that any of this works. Also suppressed in dart2js
+WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Pass, RuntimeError # Flaky with Dartium JsInterop. Seems like timing issues in the test.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, Fail # https://github.com/dart-lang/co19/issues/12
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-001_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
+WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
+
+# Must fix failures below after JsInterop checkin.
+LayoutTests/fast/events/clipboard-dataTransferItemList-remove_t01: Skip # Issue 26134, timesout
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: Skip # Issue 26134, timeout
+html/cross_domain_iframe_test: RuntimeError # Issue 26134
+
 [ $compiler == none && $runtime == dartium && $system == macos ]
 LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Skip # Depends on animation timing, commented as known to be flaky in test.  Will not fix.
 LayoutTests/fast/forms/input-value-sanitization_t01: RuntimeError # 45 roll
@@ -53,7 +1253,6 @@
 LayoutTests/fast/canvas/webgl/webgl-exceptions_t01: RuntimeError # 45 rollwebgl doesn't run on on windows/linux bots.
 LayoutTests/fast/canvas/webgl/webgl-unprefixed-context-id_t01: RuntimeError # 45 rollwebgl doesn't run on on windows/linux bots.
 
-
 [ $compiler == none && $runtime == dartium && $mode == debug ]
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: Skip # Issue 19495.
 WebPlatformTest/html/semantics/forms/the-datalist-element/datalistoptions_t01: Skip # Issue 20540.
@@ -146,1188 +1345,3 @@
 WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-
-[ $compiler == none && $runtime == dartium ]
-Language/Classes/Constructors/Generative_Constructors/execution_t03: Fail, OK
-Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
-Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
-Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
-Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure.
-Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure.
-Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure.
-Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure.
-Language/Classes/deсlarations_t01: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t02: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t03: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t04: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t06: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t08: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t12: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t13: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t14: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t15: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t16: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t17: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t18: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t19: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t20: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t21: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t22: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t23: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t24: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t25: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t26: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t27: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t28: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t29: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t30: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t31: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t32: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t33: Skip # Times out. Please triage this failure.
-Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
-Language/Expressions/Assignment/super_assignment_failed_t05: RuntimeError # Issue 25671
-Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out. Issue 25967
-Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out. Issue 25967
-Language/Expressions/Identifier_Reference/built_in_identifier_t35: Fail # Issue 25732
-Language/Expressions/Identifier_Reference/built_in_identifier_t36: Fail # Issue 25732
-Language/Expressions/Identifier_Reference/built_in_identifier_t37: Fail # Issue 25732
-Language/Expressions/Identifier_Reference/built_in_identifier_t53: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t54: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t55: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t56: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t57: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t58: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t59: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t60: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t61: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t62: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t63: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t64: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t65: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t66: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t67: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_identifier_t68: Fail # Issue 25733
-Language/Expressions/Identifier_Reference/built_in_not_dynamic_t14: Fail # Issue 25732
-Language/Expressions/Identifier_Reference/built_in_not_dynamic_t19: Fail # Issue 25772
-Language/Expressions/Instance_Creation/New/execution_t04: Fail, OK
-Language/Expressions/Instance_Creation/New/execution_t06: Fail, OK
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: Pass
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: RuntimeError # Issue 24607
-Language/Expressions/Property_Extraction/General_Super_Property_Extraction: RuntimeError # Issue 26287
-Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
-Language/Expressions/Property_Extraction/Super_Closurization: RuntimeError # Issue 26287
-Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError, OK  # Uses Isolate.spawn.
-Language/Functions/Formal_Parameters/syntax_t05: Pass
-Language/Libraries_and_Scripts/Exports/reexport_t01: fail # Dart issue 12916
-Language/Libraries_and_Scripts/Exports/reexport_t02: fail # Dart issue 12916
-Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
-Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
-Language/Libraries_and_Scripts/Scripts/top_level_main_t03: Pass # Issue 14478: This should break.
-Language/Libraries_and_Scripts/Scripts/top_level_main_t03: RuntimeError # co19-roll r786: Please triage this failure.
-Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
-Language/Mixins/Mixin_Application/syntax_t16: RuntimeError # Please triage this failure.
-Language/Mixins/declaring_constructor_t05: Fail # Issue 24767
-Language/Mixins/declaring_constructor_t06: Fail # Issue 24767
-Language/Mixins/not_object_superclass_t01: Fail # Please triage this failure.
-Language/Mixins/reference_to_super_t01: Fail # Please triage this failure.
-Language/Statements/Assert/execution_t02: skip # co19 issue 734
-Language/Statements/Assert/execution_t03: skip # co19 issue 734
-Language/Statements/Assert/type_t02: skip # co19 issue 734
-Language/Statements/Assert/type_t05: skip # co19 issue 734
-Language/Statements/Continue/async_loops_t10: Timeout, Skip # Issue 25748
-Language/Statements/Labels/syntax_t03: fail # Dart issue 2238
-Language/Statements/Switch/syntax_t02: fail # Dart issue 12908
-Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Please triage this failure
-Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t02: RuntimeError # Please triage this failure
-Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Please triage this failure
-Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08: RuntimeError # Issue 25748
-Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError # Issue 25748
-Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10: RuntimeError # Issue 25748
-Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05: RuntimeError # Issue 25662,25634
-LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/borders/border-radius-child_t01: Skip # co19 issue 732.
-LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.veryLarge_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.verySmall_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is behind a flag in Chrome
-LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-large-dimensions_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-large-fills_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-lose-restore-googol-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-lose-restore-max-int-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/drawImage-with-broken-image_t01: Timeout, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Causes following tests to fail. co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/error-reporting_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/get-active-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-get-calls_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-getstring_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/shader-precision-format_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Issue 20540
-LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-complete_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-npot_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # 45 rollwebgl doesn't run on on windows/linux but failed on mac bots.
-LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/viewport-unchanged-upon-resize_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-specific_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
-LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-display_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/justify-self-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Skip # 45 Roll failure.
-LayoutTests/fast/css/aspect-ratio-inheritance_t01: Skip # 45 Roll No longer supported.
-LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: Skip # 45 Roll No longer supported.
-LayoutTests/fast/css/auto-min-size_t01: RuntimeError #  45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
-LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
-LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fontfaceset-events_t01: Pass, RuntimeError # Issue 23433
-LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-2_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-3_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError #  45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/parsing-object-position_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-line_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-underline-position_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hash_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-hostname_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-pathname_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-port_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLImageElement/image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLImageElement/parse-src_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
-LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # co19-roll r722: Issue 18127
-LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # co19-roll r722: Issue 18250
-LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # co19-roll r722: Issue 18249
-LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/observe-childList_t01: RuntimeError # co19-roll r722: Issue 18253
-LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
-LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Bad test can't register HtmlElement.
-LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/custom/element-names_t01: RuntimeError # 45 Roll issue dart-lang/co19/issues/25
-LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-image_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/insertAdjacentElement_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/encoding/css-charset-dom_t01: Skip #  45 Roll No longer supported see issue https://github.com/dart-lang/co19/issues/35
-LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Skip # Timeout. Please triage this failure.
-LayoutTests/fast/events/clipboard-clearData_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/document-elementFromPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/events/event-creation_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/initkeyboardevent-crash_t01: RuntimeError, Timeout # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/input-focus-no-duplicate-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/invalid-003_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/invalid-004_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/label-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/mutation-during-replace-child-2_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/mutation-during-replace-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Flaky timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip #  45 Roll No longer supported.
-LayoutTests/fast/events/scoped/editing-commands_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/scroll-event-does-not-bubble_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/exclusions/parsing/parsing-wrap-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/exclusions/parsing/parsing-wrap-through_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/files/blob-close-read_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/files/blob-close-revoke_t01: RuntimeError # Experimental feature not exposed anywhere yet
-LayoutTests/fast/files/blob-close_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/files/xhr-response-blob_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/async-operations_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/filesystem/file-entry-to-uri_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-abort-depth_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-gc-blob_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-write-overlapped_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/read-directory-many_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/filesystem/simple-readonly_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/HTMLOptionElement_selected2_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Experimental feature not exposed in Chrome yet
-LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Experimental feature not exposed in Chrome yet
-LayoutTests/fast/forms/input-value-sanitization_t01: RuntimeError # 45 roll issue
-LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/listbox-select-all_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/menulist-selection-reset_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/menulist-submit-without-selection_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/missing-action_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/multiple-selected-options-innerHTML_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/option-change-single-selected_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/option-strip-unicode-spaces_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/parser-associated-form-removal_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/search-popup-crasher_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-clientheight-large-size_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-ancestor-dir-attribute_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-nonhtml-ancestor_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/submit-nil-value-field-assert_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/textarea-paste-newline_t01: Pass, RuntimeError # Issue 23433
-LayoutTests/fast/forms/textarea-scrollbar-height_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError # co19 issue 11.
-LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/boundingBox-with-continuation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/inline-position-top-align_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/loadInProgress_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Skip # Times out. Dartium 45 roll: Please triage this failure.
-LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out. co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/media-query-list-syntax_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475 # co19 issue 11.
-LayoutTests/fast/mediastream/getusermedia_t01: Skip # co19 issue 738
-LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t06: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t07: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t07: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t08: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t08: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t09: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t09: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes. # co19 issue 11.
-LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
-LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari # co19 issue 11.
-LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/scrollbar-restored_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass # co19 issue 11.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
-LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Skip # Times out: Please triage this failure.
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Skip # Times out: Please triage this failure.
-LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/speechsynthesis/*: Skip # Times out on Dartium. Fails elsewhere. Issue 22017
-LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/inline-block-with-padding_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others # co19 issue 11.
-LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
-LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip # co19 issue 11.
-LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 11.
-LayoutTests/fast/table/col-width-span-expand_t01: Skip # co19 issue 732.
-LayoutTests/fast/table/computeLogicalWidth-table-needsSectionRecalc_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-max-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox # co19 issue 11.
-LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip # co19 issue 11.
-LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/table/min-width-css-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-css-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-html-block-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/nested-tables-with-div-offset_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-colgroup-present-after-table-row_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
-LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
-LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes. # co19 issue 11.
-LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail. # co19 issue 11.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail # co19 issue 11.
-LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-rtl_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed. # co19 issue 11.
-LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox. # co19 issue 11.
-LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test. # co19 issue 11.
-LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
-LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
-LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 22200
-LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
-LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
-LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Please triage this failure.
-LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/clone_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Document/securityPolicy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/contentEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/dataset_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
-LibTest/html/Element/getAttributeNS_A01_t02: RuntimeError # Please triage this failure.
-LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Issue 16395
-LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Element/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/Element/replaceWith_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseText_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/IFrameElement.created_A01_t01: RuntimeError # Issue 24568
-LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
-LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
-LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
-LibTest/html/IFrameElement/appendHtml_A01_t02: RuntimeError # Issue 23462
-LibTest/html/IFrameElement/attributeChanged_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/attributes_setter_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/blur_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/borderEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/IFrameElement/clone_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/contentWindow_A01_t01: RuntimeError # Also fails in dart2js as this test should not pass given current Dart semantics for cross frame windows.
-LibTest/html/IFrameElement/createFragment_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t02: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createFragment_A01_t03: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/createShadowRoot_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/enteredView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/focus_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/leftView_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # co19-roll r706.  Issue 16574
-LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Issue 16574
-LibTest/html/IFrameElement/querySelector_A01_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/IFrameElement/setInnerHtml_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Node/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/append_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LibTest/html/Window/document_A01_t01: Skip # accesses window.document from a cross-frame window
-LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/moveBy_A01_t01: RuntimeError # Also fails in dart2js as this test should not pass given current Dart semantics for cross frame windows.
-LibTest/html/Window/moveTo_A01_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/postMessage_A01_t02: RuntimeError # Also fails in dart2js.
-LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A02_t01: Skip # Issue 24585.
-LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LibTest/isolate/Isolate/spawnUri_A01_t01: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t03: Skip # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t04: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
-LibTest/isolate/Isolate/spawnUri_A01_t06: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawnUri_A01_t07: RuntimeError # Issue 27219
-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_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/Isolate/spawn_A01_t06: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A03_t01: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A03_t02: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A03_t03: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A03_t04: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A04_t01: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A04_t02: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A04_t03: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A04_t04: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A04_t05: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A05_t01: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A05_t02: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A05_t03: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t01: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t02: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t03: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t04: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t05: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t06: RuntimeError # Issue 27219
-LibTest/isolate/Isolate/spawn_A06_t07: RuntimeError # Issue 27219
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/RawReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/RawReceivePort/handler_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/RawReceivePort/sendPort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/close_A02_t01: Skip # Times out
-LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/drain_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/every_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/expand_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/firstWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/firstWhere_A03_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/first_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/first_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/first_A02_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/fold_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/fold_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/forEach_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/isEmpty_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/join_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/join_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/lastWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/lastWhere_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/last_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/last_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/length_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/listen_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/map_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/pipe_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/reduce_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/reduce_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/reduce_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/singleWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/single_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/single_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/skipWhile_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/skip_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/takeWhile_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/take_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/take_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/take_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/toList_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/toSet_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/SendPort/send_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/SendPort/send_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/SendPort/send_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/SendPort/send_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/SendPort/send_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
-WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/EventObject.multiple.dispatchEvent_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/Node-replaceChild_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/dom/events/event_constants/constants_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constructors/Event_A01_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/event_constructors/Event_A02_t01: Skip # co19-roll r706.  Please triage this failure.
-WebPlatformTest/dom/events/type_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-adoptNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElementNS_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-getElementsByTagName_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-appendChild_t02: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-insertBefore_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-nodeName_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/dom/nodes/Node-replaceChild_t01: RuntimeError # co19-roll r722: Please triage this failure
-WebPlatformTest/dom/nodes/Node-textContent_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A06_t03: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A07_t03: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttributeNS_A08_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/attributes/setAttribute_A03_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-imports/link-import-null_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html-imports/link-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/link-import_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-imports/loading-import_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html-templates/innerhtml-on-templates/innerhtml_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/additions-to-the-in-head-insertion-mode/generating-of-implied-end-tags_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Skip # accesses window.document from a cross-frame window
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-namespace_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-newelements_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-param_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t05: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t02: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t03: RuntimeError # co19 issue 11.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/nameditem_t05: RuntimeError # co19 issue 11.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/disabled-elements/disabledElement_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out and fails. # co19-roll r738: Please triage this failure.LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Dartium 45 roll
-WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
-WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-autocomplete_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-elements-matches_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-elements-nameditem_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-form-element/form-nameditem_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/forms/the-input-element/date_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime-local_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/datetime_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/input-textselection_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/month_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/pattern_attribute_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/forms/the-input-element/range_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-option-element/option-text-recurse_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: Skip # co19 issue 11.
-WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: Skip # co19 issue 11.
-WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/checked_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/default_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/dir_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: Pass, RuntimeError # Spurious pass # co19 issue 11.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/disabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/text-level-semantics/the-a-element/a.text-getter_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
-WebPlatformTest/html/syntax/parsing/math-parse_t01: RuntimeError # co19 issue 11.
-WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # co19 issue 11.
-WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Tests APIs that aren't yet visible. Tests should be deleted.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/33
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-005_t01: RuntimeError #  45 Roll co19 test rewrite issue 25807
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Not clear that any of this works. Also suppressed in dart2js
-WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Pass, RuntimeError # Flaky with Dartium JsInterop. Seems like timing issues in the test.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Skip # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, Fail # https://github.com/dart-lang/co19/issues/12
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-001_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
-WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: RuntimeError # Please triage this failure.
-# Must fix failures below after JsInterop checkin.
-WebPlatformTest/dom/nodes/Node-appendChild_t01: RuntimeError # Issue 26134
-WebPlatformTest/dom/nodes/attributes/setAttribute_A01_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/Document/createElement-invalid-names_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/createDocumentType2_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/createElementNS_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/HTMLTemplateElement/cycles-in-shadow_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/HTMLTemplateElement/cycles_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/computed-style-set-property_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/custom/document-register-type-extensions_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/custom/document-register-namespace_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/custom/element-type_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/custom/element-upgrade_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/DOMException/prototype-object_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/shadow/shadow-hierarchy-exception_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/Node/contains-method_t01: RuntimeError # Issue 26134
-LayoutTests/fast/events/mutation-during-append-child_t01: RuntimeError # Issue 26134
-LayoutTests/fast/events/mutation-during-insert-before_t01: RuntimeError # Issue 26134
-LayoutTests/fast/events/clipboard-dataTransferItemList-remove_t01: Skip # Issue 26134, timesout
-LibTest/html/Document/text_A01_t01: RuntimeError # Issue 26134
-LibTest/html/Document/insertBefore_A01_t01: RuntimeError # Issue 26134
-LibTest/html/Document/insertAllBefore_A01_t01: RuntimeError # Issue 26134
-LibTest/html/IFrameElement/insertBefore_A01_t01: RuntimeError # Issue 26134
-LibTest/html/IFrameElement/insertAllBefore_A01_t01: RuntimeError # Issue 26134
-LibTest/html/Element/text_A01_t01: RuntimeError # Issue 26134
-LibTest/html/Element/insertBefore_A01_t01: RuntimeError # Issue 26134
-LibTest/html/Element/insertAllBefore_A01_t01: RuntimeError # Issue 26134
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: Skip # Issue 26134, timeout
-html/cross_domain_iframe_test: RuntimeError # Issue 26134
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 722e628..b7d42e2 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -4,6 +4,7 @@
 
 # Disable tests globally for kernel.
 [ $compiler == rasta || $compiler == rastap || $compiler == dartk || $compiler == dartkp ]
+Language/Libraries_and_Scripts/Imports/static_type_t01: Skip # No support for deferred libraries.
 Language/Metadata/*: Skip # No support for metadata ATM.
 LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Skip # No support for deferred libraries.
 LibTest/isolate/*: Skip # No support for isolates ATM.
@@ -33,14 +34,13 @@
 Language/Classes/Setters/name_t13: CompileTimeError
 Language/Classes/Setters/name_t14: CompileTimeError
 Language/Classes/Setters/name_t15: CompileTimeError
-Language/Classes/definition_t23: Crash
+Language/Classes/definition_t23: CompileTimeError
 Language/Enums/declaration_equivalent_t01: RuntimeError
 Language/Enums/syntax_t08: MissingCompileTimeError
 Language/Enums/syntax_t09: MissingCompileTimeError
 Language/Expressions/Constants/exception_t01: MissingCompileTimeError
 Language/Expressions/Constants/exception_t02: MissingCompileTimeError
 Language/Expressions/Constants/string_length_t01: Crash
-Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: MissingCompileTimeError
 Language/Expressions/Function_Invocation/Function_Expression_Invocation/not_a_function_expression_t01: RuntimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t03: RuntimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t04: RuntimeError
@@ -81,9 +81,6 @@
 Language/Expressions/Method_Invocation/Ordinary_Invocation/accessible_instance_member_t05: RuntimeError
 Language/Expressions/Method_Invocation/Ordinary_Invocation/evaluation_t07: RuntimeError
 Language/Expressions/Method_Invocation/Ordinary_Invocation/method_lookup_failed_t18: RuntimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: MissingCompileTimeError
 Language/Expressions/Object_Identity/string_t01: RuntimeError
 Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: CompileTimeError
 Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: CompileTimeError
@@ -222,9 +219,7 @@
 Language/Expressions/Strings/adjacent_strings_t02: RuntimeError
 Language/Expressions/Type_Test/evaluation_t10: RuntimeError
 Language/Functions/External_Functions/not_connected_to_a_body_t01: RuntimeError
-Language/Functions/Formal_Parameters/syntax_t04: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t05: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t12: MissingCompileTimeError
+Language/Functions/Formal_Parameters/syntax_t05: RuntimeError
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError
 Language/Libraries_and_Scripts/Exports/invalid_uri_t02: Pass
@@ -233,11 +228,12 @@
 Language/Libraries_and_Scripts/Exports/syntax_t05: MissingCompileTimeError
 Language/Libraries_and_Scripts/Exports/syntax_t06: MissingCompileTimeError
 Language/Libraries_and_Scripts/Imports/deferred_import_t01: RuntimeError
-Language/Libraries_and_Scripts/Imports/deferred_import_t02: CompileTimeError
+Language/Libraries_and_Scripts/Imports/deferred_import_t02: RuntimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01/01: MissingRuntimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_t02: Pass
 Language/Libraries_and_Scripts/Imports/static_type_t01: RuntimeError
+Language/Libraries_and_Scripts/Parts/compilation_t02: Pass Crash
 Language/Libraries_and_Scripts/Parts/syntax_t06: Pass
 Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
 Language/Libraries_and_Scripts/Scripts/top_level_main_t02: Crash
@@ -321,19 +317,6 @@
 Language/Libraries_and_Scripts/Imports/static_type_t01/03: Pass
 Language/Libraries_and_Scripts/Imports/static_type_t01/07: Pass
 Language/Libraries_and_Scripts/Imports/static_type_t01/02: Pass
-LibTest/core/Match/operator_subscript_A01_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Assertion_A01_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Assertion_A02_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Assertion_A03_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A06_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClass_A02_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Disjunction_A01_t01: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t02: RuntimeError
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Quantifier_A03_t01: RuntimeError
-LibTest/core/RegExp/firstMatch_A02_t01: RuntimeError
-LibTest/core/RegExp/hasMatch_A01_t02: RuntimeError
-LibTest/core/RegExp/stringMatch_A01_t01: RuntimeError
 
 # dartk: JIT failures (debug)
 [ $compiler == dartk && $runtime == vm && $mode == debug ]
@@ -367,23 +350,20 @@
 Language/Enums/declaration_equivalent_t01: RuntimeError
 Language/Enums/syntax_t08: MissingCompileTimeError
 Language/Enums/syntax_t09: MissingCompileTimeError
-Language/Expressions/Assignment/indexed_expression_super_t01: RuntimeError
-Language/Expressions/Assignment/indexed_expression_super_t02: RuntimeError
-Language/Expressions/Assignment/indexed_expression_super_t04: RuntimeError
-Language/Expressions/Assignment/super_assignment_failed_t01: RuntimeError
-Language/Expressions/Assignment/super_assignment_failed_t02: RuntimeError
-Language/Expressions/Assignment/super_assignment_t06: RuntimeError
-Language/Expressions/Assignment/super_assignment_value_t02: RuntimeError
 Language/Expressions/Constants/exception_t01: Crash
 Language/Expressions/Constants/exception_t02: Crash
 Language/Expressions/Constants/string_length_t01: Crash
-Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Function_Invocation/Function_Expression_Invocation/not_a_function_expression_t01: Crash
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/not_a_function_expression_t01: RuntimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t03: RuntimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t04: RuntimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t03: MissingCompileTimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t04: MissingCompileTimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/static_method_invocation_t02: RuntimeError
+Language/Expressions/Function_Invocation/async_cleanup_t07: RuntimeError
+Language/Expressions/Function_Invocation/async_cleanup_t08: RuntimeError
+Language/Expressions/Function_Invocation/async_generator_invokation_t05: RuntimeError
+Language/Expressions/Function_Invocation/async_generator_invokation_t06: RuntimeError
+Language/Expressions/Function_Invocation/async_generator_invokation_t09: RuntimeError
 Language/Expressions/Identifier_Reference/built_in_identifier_t35: Pass
 Language/Expressions/Identifier_Reference/built_in_identifier_t36: Pass
 Language/Expressions/Identifier_Reference/built_in_identifier_t37: Pass
@@ -411,15 +391,6 @@
 Language/Expressions/Method_Invocation/Ordinary_Invocation/accessible_instance_member_t05: RuntimeError
 Language/Expressions/Method_Invocation/Ordinary_Invocation/evaluation_t07: RuntimeError
 Language/Expressions/Method_Invocation/Ordinary_Invocation/method_lookup_failed_t18: RuntimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: MissingCompileTimeError
-Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t05: Crash
-Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t01: RuntimeError
-Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t02: RuntimeError
-Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t03: RuntimeError
-Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t04: RuntimeError
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: MissingCompileTimeError
-Language/Expressions/Multiplicative_Expressions/syntax_t01: Crash
 Language/Expressions/Null/instance_of_class_null_t01: Crash
 Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: CompileTimeError
 Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: CompileTimeError
@@ -555,14 +526,9 @@
 Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t06: CompileTimeError
 Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t07: CompileTimeError
 Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t08: CompileTimeError
-Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: RuntimeError
-Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t02: RuntimeError
 Language/Expressions/Type_Test/evaluation_t10: RuntimeError
-Language/Expressions/Unary_Expressions/syntax_t10: Crash
 Language/Functions/External_Functions/not_connected_to_a_body_t01: RuntimeError
-Language/Functions/Formal_Parameters/syntax_t04: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t05: MissingCompileTimeError
-Language/Functions/Formal_Parameters/syntax_t12: MissingCompileTimeError
+Language/Functions/Formal_Parameters/syntax_t05: RuntimeError
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError
 Language/Libraries_and_Scripts/Exports/invalid_uri_t02: Pass
@@ -572,14 +538,12 @@
 Language/Libraries_and_Scripts/Exports/syntax_t06: MissingCompileTimeError
 Language/Libraries_and_Scripts/Imports/deferred_import_t01: RuntimeError
 Language/Libraries_and_Scripts/Imports/deferred_import_t02: RuntimeError
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01/01: MissingRuntimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_t02: Pass
-Language/Libraries_and_Scripts/Imports/static_type_t01: RuntimeError
-Language/Libraries_and_Scripts/Parts/compilation_t02: Crash
 Language/Libraries_and_Scripts/Parts/syntax_t06: Pass
 Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
 Language/Libraries_and_Scripts/Scripts/top_level_main_t02: Crash
-Language/Libraries_and_Scripts/Scripts/top_level_main_t05: Crash
 Language/Libraries_and_Scripts/definition_syntax_t01: MissingCompileTimeError
 Language/Libraries_and_Scripts/definition_syntax_t03: MissingCompileTimeError
 Language/Libraries_and_Scripts/definition_syntax_t04: MissingCompileTimeError
@@ -626,23 +590,20 @@
 Language/Statements/Rethrow/execution_t04: RuntimeError
 Language/Statements/Switch/syntax_t02: Pass
 Language/Statements/Try/catch_scope_t01: RuntimeError
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: Fail
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t05: Fail
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t06: Fail
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t01: RuntimeError
 Language/Types/Interface_Types/subtype_t44: RuntimeError
 Language/Types/Static_Types/deferred_type_t01: RuntimeError
 Language/Variables/final_or_static_initialization_t01: MissingCompileTimeError
 Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError
 Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError
+Language/Variables/final_t01/01: MissingRuntimeError
+Language/Variables/final_t02/01: MissingRuntimeError
 Language/Variables/final_t04: MissingCompileTimeError
 Language/Variables/final_t05: MissingCompileTimeError
 Language/Variables/final_t06: MissingCompileTimeError
 Language/Variables/final_t07: MissingCompileTimeError
-LibTest/core/Invocation/isAccessor_A01_t01: RuntimeError
-LibTest/core/Invocation/isAccessor_A01_t02: Crash
-LibTest/core/Invocation/isGetter_A01_t01: RuntimeError
-LibTest/core/Invocation/isGetter_A01_t02: Crash
-LibTest/core/Invocation/isMethod_A01_t01: Crash
-LibTest/core/Invocation/isMethod_A01_t02: RuntimeError
-LibTest/core/Invocation/isSetter_A01_t01: RuntimeError
-LibTest/core/Invocation/isSetter_A01_t02: Crash
-LibTest/core/Invocation/memberName_A01_t01: RuntimeError
-LibTest/core/Invocation/namedArguments_A01_t01: Crash
-LibTest/core/Invocation/positionalArguments_A01_t01: Crash
\ No newline at end of file
+LibTest/core/StringBuffer/StringBuffer_A01_t02: RuntimeError
+LibTest/core/StringBuffer/write_A01_t02: RuntimeError
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index ac487d8a..a0e3bc4 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -48,6 +48,8 @@
 
 [ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $mode == debug ]
 LibTest/core/List/List_class_A01_t02: Pass, Slow
+
+[ ($runtime == dart_precompiled || $runtime == dart_app) && $mode == debug ]
 Language/Libraries_and_Scripts/Imports/deferred_import_t02: Crash # Issue 27201
 
 [ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && ($arch != x64 && $arch != simarm64 && $arch != arm64 && $arch != simdbc64 && $arch != simdbc) ]
@@ -228,4 +230,4 @@
 LibTest/isolate/Isolate/spawn_A01_t04: Pass, Timeout
 LibTest/isolate/Isolate/spawnUri_A01_t06: Pass, Fail # Timing dependent
 LibTest/isolate/Isolate/spawnUri_A01_t07: Pass, Fail # Timing dependent
-LibTest/isolate/ReceivePort/take_A01_t02: Crash, Fail # Issue 27773
+LibTest/isolate/ReceivePort/take_A01_t02: Skip # Issue 27773
diff --git a/tests/compiler/dart2js/kernel/visitor_test.dart b/tests/compiler/dart2js/kernel/visitor_test.dart
index ec8e3ae..d632442 100644
--- a/tests/compiler/dart2js/kernel/visitor_test.dart
+++ b/tests/compiler/dart2js/kernel/visitor_test.dart
@@ -19,7 +19,7 @@
 
 import '../memory_compiler.dart';
 
-const String TESTCASE_DIR = 'third_party/pkg/kernel/testcases/';
+const String TESTCASE_DIR = 'pkg/kernel/testcases/';
 
 const List<String> SKIP_TESTS = const <String>[
   /// The test expects an unpatched api.
diff --git a/tests/compiler/dart2js/options_helper.dart b/tests/compiler/dart2js/options_helper.dart
index 5df9c08..ec63774 100644
--- a/tests/compiler/dart2js/options_helper.dart
+++ b/tests/compiler/dart2js/options_helper.dart
@@ -18,7 +18,3 @@
   bool get hidePackageWarnings => true;
   bool showPackageWarningsFor(Uri uri) => false;
 }
-
-class MockParserOptions implements ParserOptions {
-  bool get enableGenericMethodSyntax => true;
-}
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 4ed194b..36472bb 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -105,7 +105,7 @@
       new ScannerOptions(canUseNative: true),
       reporter,
       library.entryCompilationUnit);
-  Parser parser = new Parser(listener, new MockParserOptions());
+  Parser parser = new Parser(listener);
   Token endToken = parseMethod(parser, tokens);
   assert(endToken.kind == EOF_TOKEN);
   Node node = listener.popNode();
@@ -150,7 +150,7 @@
       reporter,
       unit,
       new IdGenerator());
-  PartialParser parser = new PartialParser(listener, new MockParserOptions());
+  PartialParser parser = new PartialParser(listener);
   reporter.withCurrentElement(unit, () => parser.parseUnit(tokens));
   return unit.localMembers;
 }
diff --git a/tests/compiler/dart2js/partial_parser_test.dart b/tests/compiler/dart2js/partial_parser_test.dart
index b1c4d3b..8cf82ae 100644
--- a/tests/compiler/dart2js/partial_parser_test.dart
+++ b/tests/compiler/dart2js/partial_parser_test.dart
@@ -12,7 +12,7 @@
 
 void testSkipExpression() {
   PartialParser parser =
-      new PartialParser(new Listener(), new MockParserOptions());
+      new PartialParser(new Listener());
   Token token = scan('a < b;');
   token = parser.skipExpression(token);
   Expect.equals(';', token.value);
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 0ac90d1..96dba28 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -2724,7 +2724,7 @@
   Token tokens = scan(text);
   NodeListener listener =
       new NodeListener(const ScannerOptions(), compiler.reporter, null);
-  Parser parser = new Parser(listener, new MockParserOptions());
+  Parser parser = new Parser(listener);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
   Element compilationUnit = new CompilationUnitElementX(
@@ -2768,7 +2768,7 @@
   Token tokens = scan(text);
   NodeListener listener =
       new NodeListener(const ScannerOptions(), compiler.reporter, null);
-  Parser parser = new Parser(listener, new MockParserOptions(),
+  Parser parser = new Parser(listener,
       asyncAwaitKeywordsEnabled: element.asyncMarker != AsyncMarker.SYNC);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
diff --git a/tests/compiler/dart2js/unparser2_test.dart b/tests/compiler/dart2js/unparser2_test.dart
index d63bdb4..820fab7 100644
--- a/tests/compiler/dart2js/unparser2_test.dart
+++ b/tests/compiler/dart2js/unparser2_test.dart
@@ -93,7 +93,7 @@
   Token beginToken = scanner.tokenize();
   NodeListener listener =
       new NodeListener(const ScannerOptions(), diagnosticListener, element);
-  Parser parser = new Parser(listener, new MockParserOptions());
+  Parser parser = new Parser(listener);
   parser.parseUnit(beginToken);
   Node node = listener.popNode();
   Expect.isTrue(listener.nodes.isEmpty);
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 1436f88..4f7663f 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -81,11 +81,11 @@
 [ $runtime == ff ]
 double_round3_test: Pass, Fail, OK # Fails on ff 34, passes on ff 35. Runtime rounds 0.49999999999999994 to 1.
 double_round_to_double2_test: Pass, Fail, OK # Fails on ff 34, passes on ff 35. Runtime rounds 0.49999999999999994 to 1.
+list_test/none: RuntimeError # Issue 27871
+list_test/01: RuntimeError # Issue 27871
 
-[ $runtime == opera ]
-core_runtime_types_test: Fail
-null_nosuchmethod_test: Fail # Issue: 7413
-unicode_test: Fail # Issue 14694
+[ $compiler == dart2js && $runtime == drt && $csp && $minimized ]
+core_runtime_types_test: Pass, Fail # Issue 27913
 
 [ $compiler == dart2js ]
 error_stack_trace1_test: RuntimeError # Issue 12399
diff --git a/tests/corelib/growable_list_test.dart b/tests/corelib/growable_list_test.dart
index 4b125bf..5350919 100644
--- a/tests/corelib/growable_list_test.dart
+++ b/tests/corelib/growable_list_test.dart
@@ -34,7 +34,7 @@
   int get length => throw "SHOULD NOT BE CALLED";
 }
 
-// Implement Set for private EfficientLength interface.
+// Implement Set for private EfficientLengthIterable interface.
 class EfficientTestIterable extends TestIterableBase
                             implements Set<int> {
   EfficientTestIterable(length, count, [callbackIndex = -1, callback])
@@ -104,7 +104,7 @@
 }
 
 void testConcurrentModification() {
-  // Without EfficientLength interface
+  // Without EfficientLengthIterable interface
   {
     // Change length of list after 200 additions.
     var l = [];
@@ -127,7 +127,7 @@
     }, (e) => e is ConcurrentModificationError, "cm2");
   }
 
-  // With EfficientLength interface (uses length).
+  // With EfficientLengthIterable interface (uses length).
   {
     // Change length of list after 20 additions.
     var l = [];
diff --git a/tests/isolate/compile_time_error_test.dart b/tests/isolate/compile_time_error_test.dart
index 4bb70c7..8450630 100644
--- a/tests/isolate/compile_time_error_test.dart
+++ b/tests/isolate/compile_time_error_test.dart
@@ -14,7 +14,7 @@
   TestClass.named(num this.fld1)
     // Should cause a compilation error (for the spawned isolate). It is a
     // runtime error for the test.
-    : fld2 = fld1  /// 01: compile-time error
+    : fld2 = this.fld1  /// 01: compile-time error
   ;
   num fld1;
   num fld2;
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 1c39f36..8274317 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -89,6 +89,7 @@
 
 [ $csp ]
 deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode
+browser/package_resolve_browser_hook_test: RuntimeError # CSP violation. Issue 27914
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 isolate_stress_test: Pass, Slow # TODO(kasperl): Please triage.
@@ -105,13 +106,14 @@
 spawn_uri_multi_test/none: RuntimeError # Issue 13544
 
 [ ($compiler == none) && $runtime == dartium && $arch == x64 ]
-isolate/spawn_uri_multi_test/01: Skip # Times out. Issue 24795
+spawn_uri_multi_test/01: Skip # Times out. Issue 24795
 
 [ ($compiler == none) && ( $runtime == dartium || $runtime == drt) ]
 spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out. Issue 14463
 typed_message_test: Skip # Issue 13921, 14400
 isolate_stress_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
 object_leak_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
+send_private_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
 spawn_uri_missing_from_isolate_test: Skip # Issue 17649
 spawn_uri_missing_test: SkipSlow # Times out.
 kill3_test: Fail, OK  # 13921 Dom isolates don't support spawnFunction
@@ -228,9 +230,6 @@
 [ $mode == product ]
 issue_24243_parent_isolate_test: Skip # Requires checked mode
 
-[ $compiler == dart2js && $cps_ir && $checked ]
-*: Skip # `assert` not implemented
-
 [ $hot_reload || $hot_reload_rollback ]
 function_send_test: Pass, Fail # Closure identity
 message3_test/fun: Pass, Fail # Closure identity
diff --git a/tests/isolate/send_private_test.dart b/tests/isolate/send_private_test.dart
new file mode 100644
index 0000000..57df312
--- /dev/null
+++ b/tests/isolate/send_private_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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:isolate";
+import "package:expect/expect.dart";
+
+class _Private {
+  String data;
+  _Private(this.data);
+}
+
+void child(message) {
+  print("Got message: $message");
+  SendPort replyPort = message[0];
+  _Private object = message[1];
+  Expect.isTrue(object is _Private);
+  Expect.equals("XYZ", object.data);
+  replyPort.send(object);
+}
+
+void main() {
+  var port;
+  port = new RawReceivePort((message) {
+    print("Got reply: $message");
+    Expect.isTrue(message is _Private);
+    Expect.equals("XYZ", message.data);
+    port.close();
+  });
+
+  Isolate.spawn(child, [port.sendPort, new _Private("XYZ")]);
+}
diff --git a/tests/language/efficient_length_warning_test.dart b/tests/language/efficient_length_warning_test.dart
new file mode 100644
index 0000000..5edfc72
--- /dev/null
+++ b/tests/language/efficient_length_warning_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart test program.
+
+import "dart:math";
+
+main() {
+  // This should no longer cause a warning because the least-upper-bound
+  // of List<int> and Set<int> is Object.
+  // The LUB is now EfficientLengthIterable and it extends Iterable.
+  var x = (new Random().nextBool() // Unpredictable condition.
+      ? <int>[1]
+      : new Set<int>.from([1])).first;
+  if (x != 1) throw "Wat?";
+}
diff --git a/tests/language/initializing_formal_type_test.dart b/tests/language/initializing_formal_type_test.dart
index 7544f9d..af44444 100644
--- a/tests/language/initializing_formal_type_test.dart
+++ b/tests/language/initializing_formal_type_test.dart
@@ -8,9 +8,14 @@
 import "package:expect/expect.dart";
 
 class A {
-  int x;
-  String y;
-  A(this.x) : y = x { y = x; }
+  num x;
+  double y;
+  // Finding the type of an initializing formal: should cause a warning
+  // in the initializer but not the body, because the former has type
+  // `int` and the latter has type `num`.
+  A(int this.x) : y = x {
+    y = x;
+  }
 }
 
 main() {
diff --git a/tests/language/language.status b/tests/language/language.status
index 5a23a4d..68a294c 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -91,7 +91,6 @@
 [ $compiler == none && ($runtime == dartium || $runtime == drt) ]
 issue13474_test: Pass, Fail # Issue 14651.
 config_import_test: Fail # Issue 14651.
-generic_methods_generic_function_parameter_test: RuntimeError # Issue 25869
 vm/optimized_guarded_field_isolates_test: RuntimeError, OK  # Uses Isolate.spawn.
 main_test/01: Fail # Issue 20028
 main_test/02: Fail # Issue 20028
@@ -106,8 +105,9 @@
 initializing_formal_access_test: Skip
 initializing_formal_capture_test: Skip
 initializing_formal_final_test: Skip
-initializing_formal_type_test: Skip
 initializing_formal_promotion_test: Skip
+initializing_formal_type_test: Skip
+parameter_initializer5_test: Skip
 
 # Experimental feature: Syntactic support for generic methods.
 # Skip these in dartium, because the test framework can't pass VM flags to
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index ec05db6..72203db 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -356,7 +356,6 @@
 parameter_initializer2_negative_test: CompileTimeError
 parameter_initializer3_negative_test: CompileTimeError
 parameter_initializer4_negative_test: CompileTimeError
-parameter_initializer5_negative_test: CompileTimeError
 parameter_initializer6_negative_test: CompileTimeError
 parser_quirks_test: StaticWarning
 part2_test: StaticWarning
@@ -498,14 +497,8 @@
 for_in_side_effects_test: StaticWarning, OK # Test uses custom class that does not implement Iterable in for-in.
 
 # Experimental feature: Syntactic support for generic methods.
-generic_functions_test: CompileTimeError # Issue 25868
-generic_local_functions_test: CompileTimeError # Issue 25868
-generic_methods_test: CompileTimeError # Issue 25868
-generic_sends_test: CompileTimeError # Issue 25868
-generic_methods_new_test: CompiletimeError # Issue 25868
-generic_methods_function_type_test: CompiletimeError # Issue 25868
-generic_methods_type_expression_test: CompiletimeError # Issue 25868
-generic_methods_generic_function_parameter_test: CompiletimeError # Issue 25868
+generic_methods_type_expression_test: StaticWarning # Issue 25868
+generic_methods_generic_function_parameter_test: StaticWarning # Issue 25868
 
 # Experimental feature: Use initializing formals in initializers and constructor body.
 initializing_formal_type_test: StaticWarning # Issue 26658
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 7a10bf8..4d5379c 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -80,13 +80,6 @@
 [ $compiler == dart2js && $browser ]
 config_import_test: Fail # Test flag is not passed to the compiler.
 
-# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: CompileTimeError # DartOptions not passed to compiler.
-initializing_formal_capture_test: CompileTimeError # DartOptions not passed to compiler.
-initializing_formal_final_test: CompileTimeError # DartOptions not passed to compiler.
-initializing_formal_promotion_test: CompileTimeError # DartOptions not passed to compiler.
-initializing_formal_type_test: CompileTimeError # DartOptions not passed to compiler.
-
 library_env_test/has_no_io_support: Pass # Issue 27398
 library_env_test/has_io_support: RuntimeError # Issue 27398
 
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index 133e4c0..6262b1b 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -62,12 +62,12 @@
 constructor_duplicate_final_test/03: MissingCompileTimeError
 constructor_named_arguments_test/01: Crash
 custom_await_stack_trace_test: RuntimeError
-cyclic_type2_test: Crash
+cyclic_type2_test: CompileTimeError
 cyclic_type_test/00: RuntimeError
 cyclic_type_test/01: RuntimeError
-cyclic_type_test/02: Crash
+cyclic_type_test/02: CompileTimeError
 cyclic_type_test/03: RuntimeError
-cyclic_type_test/04: Crash
+cyclic_type_test/04: CompileTimeError
 cyclic_type_variable_test/01: Crash
 cyclic_type_variable_test/02: Crash
 cyclic_type_variable_test/03: Crash
@@ -177,15 +177,14 @@
 generic_field_mixin2_test: RuntimeError
 generic_field_mixin4_test: RuntimeError
 generic_field_mixin5_test: RuntimeError
-generic_functions_test: CompileTimeError
+generic_functions_test: Crash
 generic_inheritance_test: RuntimeError
-generic_local_functions_test: CompileTimeError
-generic_methods_function_type_test: CompileTimeError
-generic_methods_generic_function_parameter_test: CompileTimeError
-generic_methods_new_test: CompileTimeError
-generic_methods_test: CompileTimeError
-generic_methods_type_expression_test: CompileTimeError
-generic_sends_test: CompileTimeError
+generic_local_functions_test: Crash
+generic_methods_function_type_test: Crash
+generic_methods_generic_function_parameter_test: Crash
+generic_methods_new_test: Crash
+generic_methods_test: Crash
+generic_methods_type_expression_test: Crash
 generic_test: RuntimeError
 getter_closure_execution_order_test: RuntimeError
 getter_setter_in_lib_test: RuntimeError
@@ -199,19 +198,19 @@
 is_not_class2_test: RuntimeError
 issue13474_test: RuntimeError
 issue_1751477_test: RuntimeError
-least_upper_bound_expansive_test/01: Crash
-least_upper_bound_expansive_test/02: Crash
-least_upper_bound_expansive_test/03: Crash
-least_upper_bound_expansive_test/04: Crash
-least_upper_bound_expansive_test/05: Crash
-least_upper_bound_expansive_test/06: Crash
-least_upper_bound_expansive_test/07: Crash
-least_upper_bound_expansive_test/08: Crash
-least_upper_bound_expansive_test/09: Crash
-least_upper_bound_expansive_test/10: Crash
-least_upper_bound_expansive_test/11: Crash
-least_upper_bound_expansive_test/12: Crash
-least_upper_bound_expansive_test/none: Crash
+least_upper_bound_expansive_test/01: CompileTimeError
+least_upper_bound_expansive_test/02: CompileTimeError
+least_upper_bound_expansive_test/03: CompileTimeError
+least_upper_bound_expansive_test/04: CompileTimeError
+least_upper_bound_expansive_test/05: CompileTimeError
+least_upper_bound_expansive_test/06: CompileTimeError
+least_upper_bound_expansive_test/07: CompileTimeError
+least_upper_bound_expansive_test/08: CompileTimeError
+least_upper_bound_expansive_test/09: CompileTimeError
+least_upper_bound_expansive_test/10: CompileTimeError
+least_upper_bound_expansive_test/11: CompileTimeError
+least_upper_bound_expansive_test/12: CompileTimeError
+least_upper_bound_expansive_test/none: CompileTimeError
 library_env_test/has_html_support: RuntimeError
 library_env_test/has_no_io_support: RuntimeError
 library_env_test/has_no_mirror_support: RuntimeError
@@ -293,6 +292,7 @@
 not_enough_positional_arguments_test/05: MissingRuntimeError
 null_test/none: RuntimeError
 number_identifier_test/05: RuntimeError
+parameter_initializer5_test: CompileTimeError
 positional_parameters_type_test/01: MissingRuntimeError
 positional_parameters_type_test/02: MissingRuntimeError
 prefix10_negative_test: Fail
@@ -343,6 +343,7 @@
 not_enough_positional_arguments_test/02: Crash  # Crash
 not_enough_positional_arguments_test/05: Crash  # Crash
 vm/optimized_guarded_field_isolates_test: Crash  # Class finalization issue
+generic_sends_test: Crash  # Crash
 
 # dartk: precompilation failures
 [ $compiler == dartkp && $runtime == dart_precompiled ]
@@ -353,22 +354,17 @@
 accessor_conflict_import_prefixed_test: RuntimeError
 accessor_conflict_import_test: RuntimeError
 assertion_test: RuntimeError
-async_break_in_finally_test: RuntimeError
-async_control_structures_test: RuntimeError
+async_await_test: RuntimeError
 async_star_cancel_and_throw_in_finally_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError
-async_star_regression_fisk_test: Crash
+async_star_pause_test: RuntimeError
+async_star_regression_fisk_test: Timeout
 async_star_stream_take_test: Timeout
 async_star_take_reyield_test: Timeout
-async_star_test: Crash
-async_throw_in_catch_test/forceAwait: RuntimeError
-async_throw_in_catch_test/none: RuntimeError
+async_star_test: Timeout
 asyncstar_throw_in_catch_test: Timeout
 asyncstar_yield_test: Timeout
 asyncstar_yieldstar_test: Timeout
-await_exceptions_test: RuntimeError
-await_future_test: RuntimeError
-await_regression_test: RuntimeError
 bad_constructor_test/05: CompileTimeError
 bad_raw_string_negative_test: Fail
 cha_deopt1_test: RuntimeError
@@ -382,6 +378,8 @@
 compile_time_constant_k_test/03: RuntimeError
 compile_time_constant_o_test/01: RuntimeError
 compile_time_constant_o_test/02: RuntimeError
+conditional_import_string_test: CompileTimeError
+conditional_import_test: CompileTimeError
 config_import_test: RuntimeError
 conflicting_type_variable_and_setter_test: CompileTimeError
 const_dynamic_type_literal_test/02: RuntimeError
@@ -397,7 +395,7 @@
 constructor_duplicate_final_test/01: MissingRuntimeError
 constructor_duplicate_final_test/02: MissingRuntimeError
 constructor_duplicate_final_test/03: MissingCompileTimeError
-constructor_named_arguments_test/01: Crash
+custom_await_stack_trace_test: RuntimeError
 cyclic_type2_test: CompileTimeError
 cyclic_type_test/00: RuntimeError
 cyclic_type_test/01: RuntimeError
@@ -480,7 +478,6 @@
 f_bounded_equality_test: RuntimeError
 field_initialization_order_test: RuntimeError
 final_field_initialization_order_test: RuntimeError
-final_super_field_set_test/01: RuntimeError
 final_syntax_test/01: MissingCompileTimeError
 final_syntax_test/02: MissingCompileTimeError
 final_syntax_test/03: MissingCompileTimeError
@@ -496,7 +493,6 @@
 fixed_type_variable_test/06: RuntimeError
 for2_test: RuntimeError
 for_variable_capture_test: RuntimeError
-forwarding_factory_constructor_default_values_test: RuntimeError
 full_stacktrace1_test: RuntimeError
 full_stacktrace2_test: RuntimeError
 full_stacktrace3_test: RuntimeError
@@ -517,14 +513,14 @@
 generic_field_mixin2_test: RuntimeError
 generic_field_mixin4_test: RuntimeError
 generic_field_mixin5_test: RuntimeError
-generic_functions_test: CompileTimeError
+generic_functions_test: Crash
 generic_inheritance_test: RuntimeError
-generic_local_functions_test: CompileTimeError
-generic_methods_function_type_test: CompileTimeError
-generic_methods_new_test: CompileTimeError
-generic_methods_test: CompileTimeError
-generic_methods_type_expression_test: CompileTimeError
-generic_sends_test: CompileTimeError
+generic_local_functions_test: Crash
+generic_methods_function_type_test: Crash
+generic_methods_generic_function_parameter_test: Crash
+generic_methods_new_test: Crash
+generic_methods_test: Crash
+generic_methods_type_expression_test: Crash
 generic_test: RuntimeError
 getter_closure_execution_order_test: RuntimeError
 getter_setter_in_lib_test: RuntimeError
@@ -533,14 +529,13 @@
 initializing_formal_access_test: CompileTimeError
 initializing_formal_capture_test: CompileTimeError
 initializing_formal_final_test: CompileTimeError
+initializing_formal_promotion_test: CompileTimeError
 initializing_formal_type_test: CompileTimeError
 instance_creation_in_function_annotation_test: Crash
 invocation_mirror_invoke_on2_test: Crash
-invocation_mirror_test: Crash
 is_not_class2_test: RuntimeError
 issue13474_test: RuntimeError
 issue21079_test: Crash
-issue22800_test: Crash
 issue_1751477_test: RuntimeError
 large_class_declaration_test: Timeout
 least_upper_bound_expansive_test/01: CompileTimeError
@@ -634,25 +629,23 @@
 no_main_test/01: Crash
 not_enough_positional_arguments_test/01: CompileTimeError
 not_enough_positional_arguments_test/02: MissingRuntimeError
-not_enough_positional_arguments_test/05: Crash
+not_enough_positional_arguments_test/05: MissingRuntimeError
 null_test/none: RuntimeError
 number_identifier_test/05: RuntimeError
+parameter_initializer5_test: CompileTimeError
 positional_parameters_type_test/01: MissingRuntimeError
 positional_parameters_type_test/02: MissingRuntimeError
 prefix10_negative_test: Fail
-prefix16_test: RuntimeError
 prefix21_test: RuntimeError
 redirecting_constructor_initializer_test: RuntimeError
-redirecting_factory_default_values_test/none: RuntimeError
 redirecting_factory_reflection_test: Crash
 regress_18535_test: Crash
 regress_18713_test: RuntimeError
 regress_22443_test: RuntimeError
 regress_22700_test: RuntimeError
-regress_22777_test: Crash
 regress_23408_test: RuntimeError
-regress_26175_test: Crash
 regress_27164_test: CompileTimeError
+regress_27617_test/1: MissingCompileTimeError
 regress_r24720_test: RuntimeError
 reify_typevar_test: RuntimeError
 script1_negative_test: Fail
@@ -663,27 +656,15 @@
 stacktrace_rethrow_error_test/withtraceparameter: RuntimeError
 stacktrace_rethrow_nonerror_test: RuntimeError
 static_setter_get_test/01: RuntimeError
+string_interpolation7_test: RuntimeError
 super_call3_test/01: Crash
 super_call4_test: RuntimeError
-super_getter_setter_test: RuntimeError
-super_no_such_method1_test/01: RuntimeError
-super_no_such_method2_test/01: RuntimeError
-super_no_such_method3_test/01: RuntimeError
-super_no_such_method4_test/01: RuntimeError
-super_no_such_method5_test/01: RuntimeError
-super_operator_index3_test: RuntimeError
-super_operator_index4_test: RuntimeError
-super_operator_index5_test: RuntimeError
-super_operator_index6_test: RuntimeError
-super_operator_index7_test: RuntimeError
-super_operator_index8_test: RuntimeError
 super_test: RuntimeError
 switch7_negative_test: Fail
 switch_try_catch_test: RuntimeError
 sync_generator3_test/test2: RuntimeError
 tearoff_basic_test: CompileTimeError
 tearoff_constructor_basic_test: CompileTimeError
-throw8_test: RuntimeError
 try_catch_on_syntax_test/10: MissingRuntimeError
 try_catch_on_syntax_test/11: MissingRuntimeError
 try_finally_regress_25654_test: RuntimeError
@@ -695,4 +676,4 @@
 vm/debug_break_enabled_vm_test/none: CompileTimeError
 vm/reflect_core_vm_test: CompileTimeError
 vm/type_cast_vm_test: RuntimeError
-vm/type_vm_test: RuntimeError
\ No newline at end of file
+vm/type_vm_test: RuntimeError
diff --git a/tests/language/parameter_initializer5_negative_test.dart b/tests/language/parameter_initializer5_test.dart
similarity index 66%
rename from tests/language/parameter_initializer5_negative_test.dart
rename to tests/language/parameter_initializer5_test.dart
index afa5e2a..eb7208d 100644
--- a/tests/language/parameter_initializer5_negative_test.dart
+++ b/tests/language/parameter_initializer5_test.dart
@@ -1,15 +1,17 @@
 // 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.
+//
+// DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
-// Fails because this.x parameter is used in initializer expression.
+// Use the this.x parameter in an initializer expression.
 
 class Foo {
   var x, y;
   Foo(this.x): y = x { }
 }
 
-
 main() {
   new Foo(12);
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index ab4f18c..2a84f7b 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -259,6 +259,7 @@
 async/timer_not_available_test: Fail, OK
 mirrors/native_class_test: Fail, OK # This test is meant to run in a browser.
 mirrors/deferred_type_test: CompileTimeError, OK # Don't have a multitest marker for dynamic compile time errors.
+mirrors/initializing_formals_test/01: Fail # initializing formals are implicitly final as of Dart 1.21
 
 [ $compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit ]
 async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
@@ -268,6 +269,7 @@
 mirrors/mirrors_used*: SkipByDesign # Invalid tests. MirrorsUsed does not have a specification, and dart:mirrors is not required to hide declarations that are not covered by any MirrorsUsed annotation.
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
+mirrors/initializing_formals_test/01: Fail # initializing formals are implicitly final as of Dart 1.21
 async/schedule_microtask6_test: Fail # Issue 10910
 async/timer_test: Fail, Pass # Issue 15487
 async/multiple_timer_test: Fail, Pass # Issue 15487
diff --git a/tests/standalone/io/socket_info_test.dart b/tests/standalone/io/socket_info_ipv4_test.dart
similarity index 81%
rename from tests/standalone/io/socket_info_test.dart
rename to tests/standalone/io/socket_info_ipv4_test.dart
index eb14246..f8d63bd 100644
--- a/tests/standalone/io/socket_info_test.dart
+++ b/tests/standalone/io/socket_info_ipv4_test.dart
@@ -14,7 +14,11 @@
         Expect.equals(clientSocket.port, socket.remotePort);
         Expect.equals(clientSocket.remotePort, socket.port);
         Expect.equals(socket.remoteAddress.address, "127.0.0.1");
+        Expect.equals(socket.remoteAddress.type,
+                      InternetAddressType.IP_V4);
         Expect.equals(clientSocket.remoteAddress.address, "127.0.0.1");
+        Expect.equals(clientSocket.remoteAddress.type,
+                      InternetAddressType.IP_V4);
         socket.destroy();
         clientSocket.destroy();
         server.close();
diff --git a/tests/standalone/io/socket_info_ipv6_test.dart b/tests/standalone/io/socket_info_ipv6_test.dart
new file mode 100644
index 0000000..d6969ab
--- /dev/null
+++ b/tests/standalone/io/socket_info_ipv6_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:io";
+
+void testHostAndPort() {
+  ServerSocket.bind("::1", 0).then((server) {
+
+    Socket.connect("::1", server.port).then((clientSocket) {
+      server.listen((socket) {
+        Expect.equals(socket.port, server.port);
+        Expect.equals(clientSocket.port, socket.remotePort);
+        Expect.equals(clientSocket.remotePort, socket.port);
+        Expect.equals(socket.remoteAddress.address, "::1");
+        Expect.equals(socket.remoteAddress.type,
+                      InternetAddressType.IP_V6);
+        Expect.equals(clientSocket.remoteAddress.address, "::1");
+        Expect.equals(clientSocket.remoteAddress.type,
+                      InternetAddressType.IP_V6);
+        socket.destroy();
+        clientSocket.destroy();
+        server.close();
+      });
+    });
+  });
+}
+
+void main() {
+  testHostAndPort();
+}
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index d4d6076..e9f3276 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -12,7 +12,7 @@
 import "../../../tools/testing/dart/test_options.dart";
 import "process_test_util.dart";
 
-final DEFAULT_TIMEOUT = 10;
+final DEFAULT_TIMEOUT = 20;
 final LONG_TIMEOUT = 30;
 
 List<String> packageOptions() {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index fb7510f..dfc31c0 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -195,6 +195,7 @@
 io/platform_resolved_executable_test/06: RuntimeError  # Issue 23641
 io/process_sync_test: Pass, Timeout # Issue 24596
 io/sleep_test: Pass, Fail # Issue 25757
+io/socket_info_ipv6_test: RuntimeError # Issue 27876
 
 [ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $mode == debug && $builder_tag == asan ]
 io/file_lock_test: Skip  # Timeout.
@@ -352,10 +353,11 @@
 io/skipping_dart2js_compilations_test: Pass, Slow # Slow.
 
 [ $builder_tag == no_ipv6 ]
-io/http_bind_test: Skip
-io/raw_datagram_socket_test: Skip
-io/socket_source_address_test: Skip
-io/socket_bind_test: Skip
-io/http_proxy_advanced_test: Skip
-io/http_ipv6_test: Skip
-io/socket_ipv6_test: Skip
+io/http_bind_test: SkipByDesign
+io/raw_datagram_socket_test: SkipByDesign
+io/socket_source_address_test: SkipByDesign
+io/socket_bind_test: SkipByDesign
+io/http_proxy_advanced_test: SkipByDesign
+io/http_ipv6_test: SkipByDesign
+io/socket_ipv6_test: SkipByDesign
+io/socket_info_ipv6_test: SkipByDesign
diff --git a/third_party/tcmalloc/COPYING b/third_party/tcmalloc/COPYING
new file mode 100644
index 0000000..e4956cf
--- /dev/null
+++ b/third_party/tcmalloc/COPYING
@@ -0,0 +1,28 @@
+Copyright (c) 2005, Google Inc.
+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/third_party/tcmalloc/README.dart b/third_party/tcmalloc/README.dart
index 71dd619..bf326f9 100644
--- a/third_party/tcmalloc/README.dart
+++ b/third_party/tcmalloc/README.dart
@@ -11,6 +11,8 @@
 . From that repo, copy src/config.h and src/gperftools/tcmalloc.h, and any other
   generated header files to the include/ directory in this directory.
 
+. Also copy the COPYING file and any other relevant licensing information.
+
 . Make sure that include/config.h defines HAVE_UCONTEXT_H on Linux,
 
 . Update tcmalloc_sources.gypi, and tcmalloc.gyp if necessary. This may require
diff --git a/tools/VERSION b/tools/VERSION
index 6f94e01..4af9fe7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,5 +28,5 @@
 MAJOR 1
 MINOR 21
 PATCH 0
-PRERELEASE 9
+PRERELEASE 10
 PRERELEASE_PATCH 0
diff --git a/tools/dartk_wrappers/dartk b/tools/dartk_wrappers/dartk
index ca93a28..9d15f6e 100755
--- a/tools/dartk_wrappers/dartk
+++ b/tools/dartk_wrappers/dartk
@@ -7,7 +7,7 @@
 PROG_NAME="$BASH_SOURCE"
 WRAPPERS_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
 DART_ROOT="$(cd "${WRAPPERS_DIR}/../.." ; pwd -P)"
-DARTK="$DART_ROOT/third_party/pkg/kernel/bin/dartk.dart"
+DARTK="$DART_ROOT/pkg/kernel/bin/dartk.dart"
 
 if [[ `uname` == 'Darwin' ]];
 then
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index cafe953..c1a89e7 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -40,7 +40,6 @@
   "http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
   "http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
   "json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
-  "kernel_rev": "@1906e420431656d351a9f4ee9a36b8ca9a4da1db",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "matcher_tag": "@0.12.0",
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
@@ -70,7 +69,7 @@
   "web_components_rev": "@6349e09f9118dce7ae1b309af5763745e25a9d61",
   "WebCore_rev": "@a86fe28efadcfc781f836037a80f27e22a5dad17",
 
-  "co19_rev": "@d4767b4caea3c5828ad8e053cd051d44a59061af",
+  "co19_rev": "@f05d5aee5930bfd487aedf832fbd7b832f502b15",
 })
 
 deps.update({
@@ -111,8 +110,6 @@
       (Var("github_mirror") % "http_parser") + Var("http_parser_rev"),
   "src/dart/third_party/pkg/http_throttle":
       (Var("github_mirror") % "http_throttle") + Var("http_throttle_rev"),
-  "src/dart/third_party/pkg/kernel":
-      (Var("github_mirror") % "kernel") + Var("kernel_rev"),
   "src/dart/third_party/pkg/logging":
       (Var("github_mirror") % "logging") + Var("logging_rev"),
   "src/dart/third_party/pkg/matcher":
diff --git a/tools/gn.py b/tools/gn.py
index 304bdaa..91caa19 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -77,10 +77,6 @@
   # dart_bootstrap if the prebuilt SDK doesn't work.
   gn_args['dart_host_pub_exe'] = ""
 
-  # For Fuchsia support, the default is to not compile in the root
-  # certificates.
-  gn_args['dart_use_fallback_root_certificates'] = True
-
   gn_args['dart_zlib_path'] = "//runtime/bin/zlib"
 
   # Use tcmalloc only when targeting Linux and when not using ASAN.
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 9118fc8..130db11 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -47,7 +47,7 @@
     '--use-sdk',
     '--checked'
   ],
-  const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk', '--checked'],
+  const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk', '--fast-startup'],
   const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk'],
 ];
 
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index f348318..0a15772 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -58,6 +58,7 @@
     bool hotReload = configuration['hot_reload'];
     bool hotReloadRollback = configuration['hot_reload_rollback'];
     bool useFastStartup = configuration['fast_startup'];
+    bool verifyKernel = configuration['verify-ir'];
 
     switch (compiler) {
       case 'dart2analyzer':
@@ -92,14 +93,16 @@
       case 'dartk':
         return ComposedCompilerConfiguration.createDartKConfiguration(
             isHostChecked: isHostChecked,
-            useSdk: useSdk);
+            useSdk: useSdk,
+            verify: verifyKernel);
       case 'dartkp':
         return ComposedCompilerConfiguration.createDartKPConfiguration(
             isHostChecked: isHostChecked,
             arch: configuration['arch'],
             useBlobs: useBlobs,
             isAndroid: configuration['system'] == 'android',
-            useSdk: useSdk);
+            useSdk: useSdk,
+            verify: verifyKernel);
       case 'none':
         return new NoneCompilerConfiguration(
             isDebug: isDebug,
@@ -212,7 +215,9 @@
 
 /// The "dartk" compiler.
 class DartKCompilerConfiguration extends CompilerConfiguration {
-  DartKCompilerConfiguration({bool isHostChecked, bool useSdk})
+  final bool verify;
+
+  DartKCompilerConfiguration({bool isHostChecked, bool useSdk, this.verify})
       : super._subclass(isHostChecked: isHostChecked, useSdk: useSdk);
 
   @override
@@ -226,14 +231,15 @@
       CommandBuilder commandBuilder,
       List arguments,
       Map<String, String> environmentOverrides) {
-    var extraArguments = [
+    Iterable<String> extraArguments = [
       '--sdk',
       '$buildDir/patched_sdk',
       '--link',
       '--target=vm',
+      verify ? '--verify-ir' : null,
       '--out',
       outputFileName
-    ];
+    ].where((x) => x != null);
     return commandBuilder.getKernelCompilationCommand(
         'dartk',
         outputFileName,
@@ -304,8 +310,9 @@
 
 class ComposedCompilerConfiguration extends CompilerConfiguration {
   final List<PipelineCommand> pipelineCommands;
+  final bool isPrecompiler;
 
-  ComposedCompilerConfiguration(this.pipelineCommands)
+  ComposedCompilerConfiguration(this.pipelineCommands, {this.isPrecompiler: false})
       : super._subclass();
 
   CommandArtifact computeCompilationArtifact(
@@ -354,37 +361,38 @@
       List<String> sharedOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    return <String>[artifact.filename];
+    final String suffix = isPrecompiler ? "/out.aotsnapshot" : "";
+    return <String>["${artifact.filename}${suffix}"];
   }
 
   static ComposedCompilerConfiguration createDartKPConfiguration(
       {bool isHostChecked, String arch, bool useBlobs, bool isAndroid,
-       bool useSdk}) {
+       bool useSdk, bool verify}) {
     var nested = [];
 
     // Compile with dartk.
     nested.add(new PipelineCommand.runWithGlobalArguments(
         new DartKCompilerConfiguration(isHostChecked: isHostChecked,
-            useSdk: useSdk)));
+            useSdk: useSdk, verify: verify)));
 
     // Run the normal precompiler.
     nested.add(new PipelineCommand.runWithPreviousKernelOutput(
         new PrecompilerCompilerConfiguration(
           arch: arch, useBlobs: useBlobs, isAndroid: isAndroid)));
 
-    return new ComposedCompilerConfiguration(nested);
+    return new ComposedCompilerConfiguration(nested, isPrecompiler: true);
   }
 
   static ComposedCompilerConfiguration createDartKConfiguration(
-      {bool isHostChecked, bool useSdk}) {
+      {bool isHostChecked, bool useSdk, bool verify}) {
     var nested = [];
 
     // Compile with dartk.
     nested.add(new PipelineCommand.runWithGlobalArguments(
         new DartKCompilerConfiguration(isHostChecked: isHostChecked,
-            useSdk: useSdk)));
+            useSdk: useSdk, verify: verify)));
 
-    return new ComposedCompilerConfiguration(nested);
+    return new ComposedCompilerConfiguration(nested, isPrecompiler: false);
   }
 }
 
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index e9802e9..83856fe 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -287,6 +287,9 @@
           'verbose', 'Verbose output', ['-v', '--verbose'], [], false,
           type: 'bool'),
       new _TestOptionSpecification(
+          'verify-ir', 'Verify kernel IR', ['--verify-ir'], [], false,
+          type: 'bool'),
+      new _TestOptionSpecification(
           'list', 'List tests only, do not run them', ['--list'], [], false,
           type: 'bool'),
       new _TestOptionSpecification(
@@ -605,24 +608,28 @@
   // For printing out reproducing command lines, we don't want to add these
   // options.
   Set<String> _blacklistedOptions = new Set<String>.from([
-    'progress',
-    'failure-summary',
-    'step_name',
-    'report',
-    'tasks',
-    'verbose',
-    'time',
-    'dart',
-    'drt',
-    'dartium',
-    'firefox',
-    'chrome',
-    'safari',
-    'build_directory',
     'append_logs',
+    'build_directory',
+    'chrome',
+    'copy_coredumps',
+    'dart',
+    'dartium',
+    'drt',
+    'exclude_suite',
+    'failure-summary',
+    'firefox',
     'local_ip',
+    'progress',
+    'report',
+    'safari',
     'shard',
     'shards',
+    'step_name',
+    'tasks',
+    'time',
+    'verbose',
+    'write_debug_log',
+    'write_test_outcome_log',
   ]);
 
   List<String> _constructReproducingCommandArguments(Map config) {
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index f9d7b99..1cb1a39 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -1854,6 +1854,7 @@
   int pid;
   OutputLog stdout = new OutputLog();
   OutputLog stderr = new OutputLog();
+  List<String> diagnostics = <String>[];
   bool compilationSkipped = false;
   Completer<CommandOutput> completer;
 
@@ -1917,46 +1918,35 @@
 
           // Close stdin so that tests that try to block on input will fail.
           process.stdin.close();
-          void timeoutHandler() {
+          timeoutHandler() async {
             timedOut = true;
             if (process != null) {
+              var executable, arguments;
               if (io.Platform.isLinux) {
-                // Try to print stack traces of the timed out process.
-                io.Process.run('eu-stack', ['-p ${process.pid}'])
-                .then((result) {
-                  io.stdout.write(result.stdout);
-                  io.stderr.write(result.stderr);
-                })
-                .catchError(
-                    (error) => print("Error when printing stack trace: $error"))
-                .whenComplete(() {
-                  if (!process.kill()) {
-                    DebugLogger.error("Unable to kill ${process.pid}");
-                  }
-                });
+                executable = 'eu-stack';
+                arguments = ['-p ${process.pid}'];
               } else if (io.Platform.isMacOS) {
                 // Try to print stack traces of the timed out process.
                 // `sample` is a sampling profiler but we ask it sample for 1
                 // second with a 4 second delay between samples so that we only
                 // sample the threads once.
-                io.Process.run('/usr/bin/sample',
-                               ['${process.pid}', '1', '4000', '-mayDie'])
-                .then((result) {
-                  io.stdout.write(result.stdout);
-                  io.stderr.write(result.stderr);
-                })
-                .catchError(
-                    (error) => print("Error when printing stack trace: $error"))
-                .whenComplete(() {
-                  if (!process.kill()) {
-                    DebugLogger.error("Unable to kill ${process.pid}");
-                  }
-                });
-              } else {
-                if (!process.kill()) {
-                  DebugLogger.error("Unable to kill ${process.pid}");
+                executable = '/usr/bin/sample';
+                arguments = ['${process.pid}', '1', '4000', '-mayDie'];
+              }
+
+              if (executable != null) {
+                try {
+                  var result = await io.Process.run(executable, arguments);
+                  diagnostics.addAll(result.stdout.split('\n'));
+                  diagnostics.addAll(result.stderr.split('\n'));
+                } catch (error) {
+                  diagnostics.add("Unable to capture stack traces: $error");
                 }
               }
+
+              if (!process.kill()) {
+                diagnostics.add("Unable to kill ${process.pid}");
+              }
             }
           }
 
@@ -2014,6 +2004,7 @@
         new DateTime.now().difference(startTime),
         compilationSkipped,
         pid);
+    commandOutput.diagnostics.addAll(diagnostics);
     return commandOutput;
   }